Import Cobalt 21.master.0.299983

Includes the following patches:
  https://cobalt-review.googlesource.com/c/cobalt/+/6030
    n1214.hwang@samsung.com
diff --git a/cobalt_oss.sublime-workspace b/cobalt_oss.sublime-workspace
deleted file mode 100644
index ad5f187..0000000
--- a/cobalt_oss.sublime-workspace
+++ /dev/null
@@ -1,1794 +0,0 @@
-{
-	"auto_complete":
-	{
-		"selected_items":
-		[
-			[
-				"call_arg",
-				"call_args_list"
-			],
-			[
-				"device_au",
-				"device_authentication_query_string"
-			],
-			[
-				"signature_hash",
-				"signature_hash_size_in_bytes"
-			],
-			[
-				"ComputeSign",
-				"ComputeSignatureWithProvidedSecret"
-			]
-		]
-	},
-	"buffers":
-	[
-		{
-			"file": "src/starboard/shared/starboard/application.cc",
-			"settings":
-			{
-				"buffer_size": 12106,
-				"encoding": "UTF-8",
-				"line_ending": "Unix"
-			}
-		},
-		{
-			"file": "src/starboard/shared/wayland/application_wayland.cc",
-			"settings":
-			{
-				"buffer_size": 8003,
-				"line_ending": "Unix"
-			}
-		},
-		{
-			"file": "src/starboard/shared/x11/application_x11.cc",
-			"settings":
-			{
-				"buffer_size": 41757,
-				"line_ending": "Unix"
-			}
-		}
-	],
-	"build_system": "",
-	"build_system_choices":
-	[
-	],
-	"build_varint": "",
-	"command_palette":
-	{
-		"height": 0.0,
-		"last_filter": "",
-		"selected_items":
-		[
-		],
-		"width": 0.0
-	},
-	"console":
-	{
-		"height": 157.0,
-		"history":
-		[
-		]
-	},
-	"distraction_free":
-	{
-		"menu_visible": true,
-		"show_minimap": false,
-		"show_open_files": false,
-		"show_tabs": false,
-		"side_bar_visible": false,
-		"status_bar_visible": false
-	},
-	"expanded_folders":
-	[
-		"/usr/local/google/home/aabtop/src/cobalt_oss"
-	],
-	"file_history":
-	[
-		"/usr/local/google/home/aabtop/src/cobalt_oss/src/starboard/shared/x11/application_x11.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/configuration.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/shared/posix/socket_internal.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/net/base/net_errors_starboard.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/examples/glclear/main.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/web_platform_tests/html-media-capture/capture_reflect.html",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/build/all.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/linux/x64directfb/sanitizer_options.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/ps4/sanitizer_options.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/llvm-project/compiler-rt/lib/msan/msan.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/media_capture/media_capture_test.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/cssom/cssom.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/base/token.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/debug/debug.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/dom.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/net/dns/host_resolver_impl.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/default_tick_clock.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/default_tick_clock.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/time_starboard.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/time.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/time.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/time/time_now_starboard.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/xhr/xml_http_request.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/base.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/net/url_request/url_fetcher_impl.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/net/url_request/url_fetcher.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/net/url_request/url_fetcher_core.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/buildbot/buildcop.config",
-		"/usr/local/google/home/aabtop/src/cobalt/src/buildbot/slave_scripts/gclient_config.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/tools/buildbot/results/submit_results.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/tools/buildbot/results/results.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/tools/buildbot/results/submit_results_test.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/crypto/bio/connect.c",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/config/android/openssl/opensslconf.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/config/lbshell/openssl/opensslconf.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/boringssl.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/include/openssl/base.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/include/openssl/thread.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/config/starboard/openssl/opensslconf.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/crypto/rsa_extra/rsa_test.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/crypto/internal.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src/include/openssl/is_boringssl.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/player.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/png_utils/png_encode.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/png_utils/png_encode.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/window.idl",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/screenshot_manager.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/mozjs-45/mozjs-45.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/jpeg_utils/jpeg_encode.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/jpeg_utils/jpeg_encode.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/png_utils/png_utils.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/screenshot.idl",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/window.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/browser_module.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/debug/debugger_starboard.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/test/jpeg_utils/jpeg_utils.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/loader.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/image/image_encoder.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/libjpeg/libjpeg.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/screenshot.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/screenshot.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout_tests/testdata/cobalt/screenshot-with-animation.html",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/libjpeg-turbo/libjpeg.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/CHANGELOG.md",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/CHANGELOG.md",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/tools/buildbot/run_black_box_tests.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/black_box_tests/black_box_tests.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout/box.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/application.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/linux/x86x11/compiler_flags.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/linux/shared/compiler_flags.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/sys_info_android.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/android/shared/system_get_property.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/user_agent_string.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/image/webp_image_decoder.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/image/animated_webp_image.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/synchronization/lock.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/web_module.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/base/task_runner.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/raspi/shared/gyp_configuration.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/image/image_decoder_test.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/image/animated_webp_image.h",
-		"/usr/local/google/home/aabtop/src/cobalt_oss/foo.txt",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/cpu_features.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/linux/x64x11/clang/3.6/download_clang.sh",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/shared/linux/cpu_features_get.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/css_parser/grammar.y",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/dom/html_element.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout/layout_unit.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/loader/embedded_resources/cobalt_splash_screen.css",
-		"/usr/local/google/home/aabtop/src/gitscrub.txt",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/rasterizer/rasterizer.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/render_tree/render_tree.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout/layout.gyp",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/webdriver_benchmarks/youtube/youtube_testrunner.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/webdriver_benchmarks/youtube/css_selectors.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/tools/lbshell/memlog_to_chart_data.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/memory_tracker/tool/log_writer_tool.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/v8/gypfiles/toolchain.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/icu/source/common/unicode/uvernum.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/tools/command_line.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/tools/example/app_launcher_client.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/nxswitch/launcher.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/nxswitch/tools/build_deploy_run.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/mutex.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/blitter.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/window.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/tools/lbshell/oss_re.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/icu/README.cobalt",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/libvpx_ps4/libvpx_ps4.gyp",
-		"/usr/local/google/home/aabtop/src/scrub.txt",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/libvpx_ps4/vp9-dec-core/vp9/decoder/kernels/intra_fillborder_c.pssl",
-		"/usr/local/google/home/aabtop/src/cobalt/src/buildbot/steel/cobalt_build_configs.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/android/shared/gyp_configuration.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/ps4/cobalt/configuration.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/build/cobalt_configuration.gypi",
-		"/usr/local/google/home/aabtop/src/cobalt/src/third_party/icu/source/common/unicode/umachine.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/pipeline.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/memory_tracker/tool.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/build/filelist_test.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/starboard/build/filelist.py",
-		"/usr/local/google/home/aabtop/src/cobalt/src/nb/analytics/memory_tracker_impl.h",
-		"/usr/local/google/home/aabtop/src/cobalt/src/nb/analytics/memory_tracker.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/nb/analytics/memory_tracker_impl.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/browser/memory_tracker/tool/log_writer_tool.cc",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/doc/device_authentication.md",
-		"/usr/local/google/home/aabtop/src/memleak/20/Aug15_devel_no_hud/memory_log.txt",
-		"/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout_tests/test_parser.cc"
-	],
-	"find":
-	{
-		"height": 39.0
-	},
-	"find_in_files":
-	{
-		"height": 161.0,
-		"where_history":
-		[
-			"*.cc, *.h",
-			"*.cc",
-			"*.py",
-			"*.c, *.cc, *.h,/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src",
-			"*.cc, *.h,/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl/src",
-			"*.cc, *.h",
-			"*.cc",
-			"*.gyp",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.cc, *.h",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.html, *.js,/usr/local/google/home/aabtop/src/cobalt/src/cobalt/layout_tests",
-			"*.html, *.js",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.py",
-			"*.cc, *.h",
-			"*.gyp, *.gypi",
-			"*.py, *.sh, *.txt",
-			"*.py, *.sh",
-			"*.py",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.py",
-			"*.md",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.idl",
-			"*.md",
-			"*.cc, *.py, *.gyp, *.gypi",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.idl",
-			"*.py",
-			"*.cc, *.h",
-			"*.py",
-			"*.h",
-			"*.py",
-			"*.cc, *.h",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.cc,/usr/local/google/home/aabtop/src/cobalt/src/starboard/linux",
-			"*.gyp, *.gypi",
-			"*.h",
-			"*.c",
-			"*.html",
-			"*.idl",
-			"*.gyp, *.gypi, *.py,",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.cc, *.h, *.c",
-			"*.cc, *.h",
-			"*.mk",
-			"*.*",
-			"*.c",
-			"*.c, *.h",
-			"*.cc",
-			"*.py",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.js",
-			"*.h",
-			"*.js",
-			"*.h",
-			"*.js",
-			"*.cc, *.h, *.c, *.cpp",
-			"*.cc, *.h, *.c",
-			"*.sh, *.py, *.gyp, *.gypi, *.cc, *.h, *.cpp, *.c",
-			"*.sh, *.py, *.gyp, *.gypi, *.cc, *.h",
-			"*.gyp, *.gypi",
-			"*.cpp, *.c, *.cc",
-			"*.py",
-			"*.py, *.gyp, *.gypi, *.sh",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.cc",
-			"*.js, *.html",
-			"*.cc, *.h",
-			"*.cc",
-			"*.cc,*.h,/usr/local/google/home/aabtop/src/cobalt/src/cobalt/",
-			"*.cc,*.h,/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/rasterizer/skia/skia/src/ports",
-			"*.cc,/usr/local/google/home/aabtop/src/cobalt/src/cobalt/renderer/rasterizer/skia/skia/src/ports",
-			"*.cc",
-			"*.gyp, *.gypi",
-			"*.cc, *.h",
-			"*.py",
-			"*.h",
-			"*.cc",
-			"*.py, *.gypi, *.cc, *.h",
-			"*.py, *.gypi",
-			"*.cc, *.h",
-			"*.js",
-			"*.cc, *.h",
-			"*.idl",
-			"*.cc, *.h",
-			"*.gyp, *.gypi",
-			"*.cc, *.h,,/usr/local/google/home/aabtop/src/cobalt/src/v8/src",
-			"*.cc, *.h,/usr/local/google/home/aabtop/src/cobalt/src/third_party/boringssl",
-			"*.cc, *.h",
-			"*.*",
-			"*.gyp, *.gypi, *.py, *.sh",
-			"*.gyp, *.gypi, *.py",
-			"*.gyp, *.gypi",
-			"*.gyp",
-			"*.cc, *.h",
-			"*.cc, *>h",
-			"*.gyp, *.gypi",
-			"*.py, *.sh",
-			"*.py",
-			"*.cc",
-			"*.h",
-			"*.py",
-			"*.cc",
-			"*.py",
-			"*.gyp, *.gypi",
-			"*.cc, *.h, *.c",
-			"*.cc, *.h, *.py",
-			"*.cc, *.h",
-			"*.h",
-			"*.cc",
-			"*.gyp, *.gypi"
-		]
-	},
-	"find_state":
-	{
-		"case_sensitive": false,
-		"find_history":
-		[
-			"OnSuspend",
-			"kStateSuspended",
-			"kSbEventTypeSuspend",
-			"DeleteStartData",
-			"SOCKET_ERROR_CONNECTION_RESET_SUPPORT",
-			"clear",
-			"SB_API_VERSION",
-			"socket",
-			"reset",
-			"econnreset",
-			"econn_reset",
-			"socket",
-			"disabled_",
-			"debug",
-			"DefaultTickClock::GetInstance()",
-			"TimeTicksNowIgnoringOverride",
-			"g_time_ticks_now_function",
-			"now()",
-			"dynamic",
-			"getstatus()",
-			"getstatus",
-			"DefaultTickClock",
-			"kDefault",
-			"called",
-			"0x3",
-			"getstores()",
-			"getstores",
-			"GetStores",
-			"RESULTS_STORE_DIR_NAME",
-			"GetStores\nGetStores",
-			"GetStores",
-			"GetStorePath",
-			"StoreFile",
-			"getstore",
-			"connect.c",
-			"OPENSSL_MD4",
-			"OPENSSL_NO_MD4",
-			"sources!",
-			"OPENSSL_NO_MD4",
-			"endian",
-			"ENDIAN",
-			"openssl_threads",
-			"OPENSSL_NO_THREADS",
-			"is_boringssl.h",
-			"max",
-			"gold",
-			"libjpeg-turbo/libjpeg.gyp:libjpeg",
-			"ImageFormat::kJPEG",
-			"gold",
-			"EncodeRGBAToBuffer",
-			"screenshot",
-			"jpeg_utils",
-			"png_utils",
-			"turbo",
-			"_FORWARDING_MACHINE_NAME",
-			"gettransformed",
-			"initial_deep_link",
-			"initial",
-			"rpath",
-			"chipset_model_number",
-			"GetAndroidSystemProperty",
-			"UserAgentPlatformInfo",
-			"decode_closure_",
-			"DecodeFrames",
-			"with",
-			"AssertAcquired",
-			"StartDecoding",
-			"decodeframes",
-			"current",
-			"iscurrent",
-			"decode_closure_",
-			"architecture_generation",
-			"revision",
-			"variant",
-			"armv8",
-			"banned",
-			"visibility",
-			"dispaly",
-			"banned",
-			"optimize_target_for_speed",
-			"shelf",
-			"struct",
-			"SbBlitterRect",
-			"struct",
-			"do_ninja_build",
-			"no_build",
-			"whitelist",
-			"ban",
-			"bann",
-			"orbis",
-			"cobalt_splash_screen_file",
-			"fallback_splash",
-			"GetCSSTransform",
-			"gettransform",
-			"upload_to_clusterfuzz",
-			"_CreateLinuxX86X11Builders",
-			"upload_to_clusterfuzz",
-			"\\",
-			"upload_to_clusterfuzz",
-			"kMaxStackSize",
-			"kNumAddressPrints",
-			"kAllocationLogger",
-			"\"allocation_logger\"",
-			"logwriter",
-			"allocation_log",
-			"banned",
-			"131",
-			"/google",
-			"banned",
-			"_CROW_COMMANDLINE",
-			"banned",
-			"crow",
-			"banned",
-			"johnx",
-			"banned",
-			"johnx",
-			"Banned",
-			"banned",
-			"(strobe)",
-			"banned",
-			"todo",
-			"johnx",
-			"banned",
-			"b/",
-			"niteris",
-			"banned",
-			"benchmark",
-			"layout_benchmarks"
-		],
-		"highlight": true,
-		"in_selection": false,
-		"preserve_case": false,
-		"regex": false,
-		"replace_history":
-		[
-			"microphone",
-			"());\n",
-			"));\n"
-		],
-		"reverse": false,
-		"show_context": true,
-		"use_buffer2": true,
-		"whole_word": false,
-		"wrap": true
-	},
-	"folders":
-	[
-		{
-			"path": "/usr/local/google/home/aabtop/src/cobalt_oss"
-		}
-	],
-	"groups":
-	[
-		{
-			"sheets":
-			[
-			]
-		},
-		{
-			"selected": 0,
-			"sheets":
-			[
-				{
-					"buffer": 0,
-					"file": "src/starboard/shared/starboard/application.cc",
-					"semi_transient": false,
-					"settings":
-					{
-						"buffer_size": 12106,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								11819,
-								11819
-							]
-						],
-						"settings":
-						{
-							"history_list_is_closing": true,
-							"syntax": "Packages/C++/C++.sublime-syntax",
-							"tab_size": 2,
-							"translate_tabs_to_spaces": true
-						},
-						"translation.x": 0.0,
-						"translation.y": 5677.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 1,
-					"type": "text"
-				}
-			]
-		},
-		{
-			"selected": 1,
-			"sheets":
-			[
-				{
-					"buffer": 0,
-					"file": "src/starboard/shared/starboard/application.cc",
-					"semi_transient": false,
-					"settings":
-					{
-						"buffer_size": 12106,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								9892,
-								9892
-							]
-						],
-						"settings":
-						{
-							"history_list_is_closing": true,
-							"syntax": "Packages/C++/C++.sublime-syntax",
-							"tab_size": 2,
-							"translate_tabs_to_spaces": true
-						},
-						"translation.x": 0.0,
-						"translation.y": 4957.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 3,
-					"type": "text"
-				},
-				{
-					"buffer": 1,
-					"file": "src/starboard/shared/wayland/application_wayland.cc",
-					"semi_transient": false,
-					"settings":
-					{
-						"buffer_size": 8003,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								3906,
-								3906
-							]
-						],
-						"settings":
-						{
-							"syntax": "Packages/C++/C++.sublime-syntax",
-							"tab_size": 2,
-							"translate_tabs_to_spaces": true
-						},
-						"translation.x": 0.0,
-						"translation.y": 1356.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 0,
-					"type": "text"
-				},
-				{
-					"buffer": 2,
-					"file": "src/starboard/shared/x11/application_x11.cc",
-					"semi_transient": false,
-					"settings":
-					{
-						"buffer_size": 41757,
-						"regions":
-						{
-						},
-						"selection":
-						[
-							[
-								1464,
-								1464
-							]
-						],
-						"settings":
-						{
-							"syntax": "Packages/C++/C++.sublime-syntax",
-							"tab_size": 2,
-							"translate_tabs_to_spaces": true
-						},
-						"translation.x": 0.0,
-						"translation.y": 0.0,
-						"zoom_level": 1.0
-					},
-					"stack_index": 2,
-					"type": "text"
-				}
-			]
-		},
-		{
-			"sheets":
-			[
-			]
-		}
-	],
-	"incremental_find":
-	{
-		"height": 27.0
-	},
-	"input":
-	{
-		"height": 0.0
-	},
-	"layout":
-	{
-		"cells":
-		[
-			[
-				0,
-				0,
-				1,
-				1
-			],
-			[
-				1,
-				0,
-				2,
-				1
-			],
-			[
-				2,
-				0,
-				3,
-				1
-			],
-			[
-				3,
-				0,
-				4,
-				1
-			]
-		],
-		"cols":
-		[
-			0.0,
-			0.25,
-			0.5,
-			0.75,
-			1.0
-		],
-		"rows":
-		[
-			0.0,
-			1.0
-		]
-	},
-	"menu_visible": true,
-	"output.find_results":
-	{
-		"height": 0.0
-	},
-	"pinned_build_system": "",
-	"project": "",
-	"replace":
-	{
-		"height": 50.0
-	},
-	"save_all_on_build": true,
-	"select_file":
-	{
-		"height": 0.0,
-		"last_filter": "",
-		"selected_items":
-		[
-			[
-				"application_x11",
-				"src/starboard/shared/x11/application_x11.cc"
-			],
-			[
-				"shared/starboard/application",
-				"src/starboard/shared/starboard/application.cc"
-			],
-			[
-				"net_errors_star",
-				"net/base/net_errors_starboard.cc"
-			],
-			[
-				"configuration.h",
-				"starboard/configuration.h"
-			],
-			[
-				"neterrorstarboard",
-				"net/base/net_errors_starboard.cc"
-			],
-			[
-				"clear/main.cc",
-				"starboard/examples/glclear/main.cc"
-			],
-			[
-				"lsan.cc",
-				"third_party/llvm-project/compiler-rt/lib/msan/msan.cc"
-			],
-			[
-				"sanitizer_options.cc",
-				"starboard/linux/x64directfb/sanitizer_options.cc"
-			],
-			[
-				"sanitizer.cc",
-				"starboard/ps4/sanitizer_options.cc"
-			],
-			[
-				"all.gyp",
-				"cobalt/build/all.gyp"
-			],
-			[
-				"mediacapture",
-				"cobalt/media_capture/media_capture_test.gyp"
-			],
-			[
-				"media/captur",
-				"third_party/web_platform_tests/html-media-capture/capture_reflect.html"
-			],
-			[
-				"cssom",
-				"cobalt/cssom/cssom.gyp"
-			],
-			[
-				"token.h",
-				"cobalt/base/token.h"
-			],
-			[
-				"dom.gyp",
-				"cobalt/dom/dom.gyp"
-			],
-			[
-				"cobalt/debug/",
-				"cobalt/debug/debug.gyp"
-			],
-			[
-				"host_resolver_imp",
-				"net/dns/host_resolver_impl.cc"
-			],
-			[
-				"default_tick",
-				"base/time/default_tick_clock.cc"
-			],
-			[
-				"timestarboard.",
-				"base/time/time_starboard.cc"
-			],
-			[
-				"xmlhttprequest.cc",
-				"cobalt/xhr/xml_http_request.cc"
-			],
-			[
-				"url_fetcher.cc",
-				"net/url_request/url_fetcher_impl.cc"
-			],
-			[
-				"url_fetcher_co",
-				"net/url_request/url_fetcher_core.cc"
-			],
-			[
-				"base.gyp",
-				"base/base.gyp"
-			],
-			[
-				"xhttp",
-				"cobalt/xhr/xml_http_request.cc"
-			],
-			[
-				"buildcop",
-				"buildbot/buildcop.config"
-			],
-			[
-				"gclient_confi",
-				"buildbot/slave_scripts/gclient_config.py"
-			],
-			[
-				"buildbot/results.py",
-				"cobalt/tools/buildbot/results/results.py"
-			],
-			[
-				"submitresult",
-				"cobalt/tools/buildbot/results/submit_results.py"
-			],
-			[
-				"glclearmain",
-				"starboard/examples/glclear/main.cc"
-			],
-			[
-				"connect.c",
-				"third_party/boringssl/src/crypto/bio/connect.c"
-			],
-			[
-				"boringssl",
-				"third_party/boringssl/boringssl.gyp"
-			],
-			[
-				"opensslconf",
-				"third_party/boringssl/src/config/android/openssl/opensslconf.h"
-			],
-			[
-				"opensslconf.h",
-				"third_party/boringssl/src/config/starboard/openssl/opensslconf.h"
-			],
-			[
-				"is_boring",
-				"third_party/boringssl/src/include/openssl/is_boringssl.h"
-			],
-			[
-				"player.h",
-				"starboard/player.h"
-			],
-			[
-				"browser.cc",
-				"cobalt/browser/browser_module.cc"
-			],
-			[
-				"window.idl",
-				"cobalt/dom/window.idl"
-			],
-			[
-				"window.cc",
-				"cobalt/dom/window.cc"
-			],
-			[
-				"screenshot.cc",
-				"cobalt/dom/screenshot.cc"
-			],
-			[
-				"screenshot.idl",
-				"cobalt/dom/screenshot.idl"
-			],
-			[
-				"png_utils",
-				"cobalt/renderer/test/png_utils/png_utils.gyp"
-			],
-			[
-				"libjpeg.gyp",
-				"third_party/libjpeg/libjpeg.gyp"
-			],
-			[
-				"jpegturbo.gyp",
-				"third_party/libjpeg-turbo/libjpeg.gyp"
-			],
-			[
-				"jpeg_encode.cc",
-				"cobalt/renderer/test/jpeg_utils/jpeg_encode.cc"
-			],
-			[
-				"jpeg_encode.h",
-				"cobalt/renderer/test/jpeg_utils/jpeg_encode.h"
-			],
-			[
-				"changelog.md",
-				"starboard/CHANGELOG.md"
-			],
-			[
-				"runblackbox",
-				"cobalt/tools/buildbot/run_black_box_tests.py"
-			],
-			[
-				"black_box_test",
-				"cobalt/black_box_tests/black_box_tests.py"
-			],
-			[
-				"box.cc",
-				"cobalt/layout/box.cc"
-			],
-			[
-				"application",
-				"cobalt/browser/application.cc"
-			],
-			[
-				"browser_mod",
-				"cobalt/browser/browser_module.cc"
-			],
-			[
-				"android/systemgetproper",
-				"starboard/android/shared/system_get_property.cc"
-			],
-			[
-				"user_agent",
-				"cobalt/browser/user_agent_string.cc"
-			],
-			[
-				"animated_webp",
-				"cobalt/loader/image/animated_webp_image.cc"
-			],
-			[
-				"webp",
-				"cobalt/loader/image/webp_image_decoder.cc"
-			],
-			[
-				"lock.h",
-				"base/synchronization/lock.h"
-			],
-			[
-				"task_runner.h",
-				"base/task_runner.h"
-			],
-			[
-				"web_modu",
-				"cobalt/browser/web_module.cc"
-			],
-			[
-				"image_decodertest.c",
-				"cobalt/loader/image/image_decoder_test.cc"
-			],
-			[
-				"animated_web",
-				"cobalt/loader/image/animated_webp_image.h"
-			],
-			[
-				"raspi/shared/gyp",
-				"starboard/raspi/shared/gyp_configuration.gypi"
-			],
-			[
-				"cpu_feature.h",
-				"starboard/cpu_features.h"
-			],
-			[
-				"cpufeatures.cc",
-				"starboard/shared/linux/cpu_features_get.cc"
-			],
-			[
-				"download_clang.sh",
-				"starboard/linux/x64x11/clang/3.6/download_clang.sh"
-			],
-			[
-				"layout_uni",
-				"cobalt/layout/layout_unit.h"
-			],
-			[
-				"cobaltsplash",
-				"cobalt/loader/embedded_resources/cobalt_splash_screen.css"
-			],
-			[
-				"grammar",
-				"cobalt/css_parser/grammar.y"
-			],
-			[
-				"html_ele",
-				"cobalt/dom/html_element.cc"
-			],
-			[
-				"rasterizer.gy",
-				"cobalt/renderer/rasterizer/rasterizer.gyp"
-			],
-			[
-				"turbojpeg.gyp",
-				"third_party/libjpeg-turbo/libjpeg.gyp"
-			],
-			[
-				"libjpeg",
-				"third_party/libjpeg/libjpeg.gyp"
-			],
-			[
-				"render_tre",
-				"cobalt/render_tree/render_tree.gyp"
-			],
-			[
-				"layout.gyp",
-				"cobalt/layout/layout.gyp"
-			],
-			[
-				"rasterizer.gyp",
-				"cobalt/renderer/rasterizer/rasterizer.gyp"
-			],
-			[
-				"log_writer_too",
-				"cobalt/browser/memory_tracker/tool/log_writer_tool.h"
-			],
-			[
-				"memlog",
-				"tools/lbshell/memlog_to_chart_data.py"
-			],
-			[
-				"css_selector",
-				"cobalt/webdriver_benchmarks/youtube/css_selectors.py"
-			],
-			[
-				"youtubetestrunner.",
-				"cobalt/webdriver_benchmarks/youtube/youtube_testrunner.py"
-			],
-			[
-				"v8/toolchain.gyp",
-				"v8/gypfiles/toolchain.gypi"
-			],
-			[
-				"unicodeuvernum.h",
-				"third_party/icu/source/common/unicode/uvernum.h"
-			],
-			[
-				"window.h",
-				"starboard/window.h"
-			],
-			[
-				"blitter.h",
-				"starboard/blitter.h"
-			],
-			[
-				"mutex.h",
-				"starboard/mutex.h"
-			],
-			[
-				"command_line.py",
-				"starboard/tools/command_line.py"
-			],
-			[
-				"launcher_clie",
-				"starboard/tools/example/app_launcher_client.py"
-			],
-			[
-				"switch/launch",
-				"starboard/nxswitch/launcher.py"
-			],
-			[
-				"builddeployr",
-				"starboard/nxswitch/tools/build_deploy_run.py"
-			],
-			[
-				"oss_re",
-				"tools/lbshell/oss_re.py"
-			],
-			[
-				"icu/readme.cobal",
-				"third_party/icu/README.cobalt"
-			],
-			[
-				"intrafillborder",
-				"third_party/libvpx_ps4/vp9-dec-core/vp9/decoder/kernels/intra_fillborder_c.pssl"
-			],
-			[
-				"libvpx",
-				"third_party/libvpx_ps4/libvpx_ps4.gyp"
-			],
-			[
-				"ossre",
-				"tools/lbshell/oss_re.py"
-			],
-			[
-				"android/gyp_conf",
-				"starboard/android/shared/gyp_configuration.gypi"
-			],
-			[
-				"renderer/pipeli",
-				"cobalt/renderer/pipeline.cc"
-			],
-			[
-				"unicode/umachine",
-				"third_party/icu/source/common/unicode/umachine.h"
-			],
-			[
-				"cobaltbuilds",
-				"buildbot/steel/cobalt_build_configs.py"
-			],
-			[
-				"starboard/build/file",
-				"starboard/build/filelist_test.py"
-			],
-			[
-				"device_auth",
-				"cobalt/doc/device_authentication.md"
-			],
-			[
-				"log_writer_tool",
-				"cobalt/browser/memory_tracker/tool/log_writer_tool.cc"
-			],
-			[
-				"memory_tracker_imp",
-				"nb/analytics/memory_tracker_impl.cc"
-			],
-			[
-				"memory_trackerI",
-				"nb/analytics/memory_tracker_impl.cc"
-			],
-			[
-				"memory_tracker_im",
-				"nb/analytics/memory_tracker_impl.cc"
-			],
-			[
-				"memory_track",
-				"nb/analytics/memory_tracker_impl.cc"
-			],
-			[
-				"filelist_test.",
-				"starboard/build/filelist_test.py"
-			],
-			[
-				"build/filelist.py",
-				"starboard/build/filelist.py"
-			],
-			[
-				"android/shared/launcher",
-				"starboard/android/shared/launcher.py"
-			],
-			[
-				"web_socket_imp",
-				"cobalt/websocket/web_socket_impl.h"
-			],
-			[
-				"web_socket_event_inter",
-				"cobalt/websocket/web_socket_event_interface.cc"
-			],
-			[
-				"cobalt_web_socke",
-				"cobalt/websocket/cobalt_web_socket_event_handler.cc"
-			],
-			[
-				"url_request_context",
-				"cobalt/network/url_request_context.cc"
-			],
-			[
-				"network/net_log_",
-				"cobalt/network/net_log_constants.cc"
-			],
-			[
-				"media/formats/mp4/mp4_stream",
-				"cobalt/media/formats/mp4/mp4_stream_parser.cc"
-			],
-			[
-				"xmlhttpreque/web_plat",
-				"cobalt/layout_tests/testdata/web-platform-tests/XMLHttpRequest/web_platform_tests.txt"
-			],
-			[
-				"debug/remote/content/inde",
-				"cobalt/debug/remote/content/index.html"
-			],
-			[
-				"__cobalt/readme",
-				"cobalt/build/cobalt_archive_content/__cobalt_archive/run/readme.md"
-			],
-			[
-				"cobalt_arch",
-				"cobalt/build/cobalt_archive.py"
-			],
-			[
-				"bindings/readm",
-				"cobalt/bindings/README.md"
-			],
-			[
-				"layout_tests.gyp",
-				"cobalt/layout_tests/layout_tests.gyp"
-			],
-			[
-				"layout_tests.",
-				"cobalt/layout_tests/layout_tests.cc"
-			],
-			[
-				"foo.txt",
-				"net/data/cert_net_fetcher_impl_unittest/foo.txt"
-			],
-			[
-				"osslint",
-				"tools/repo-hooks/osslint.py"
-			],
-			[
-				"steelpresubmitche",
-				"tools/repo-hooks/steel_presubmit_checks.py"
-			],
-			[
-				"cobalt/presubmit",
-				"cobalt/PRESUBMIT.py"
-			],
-			[
-				"gitscrub.",
-				"tools/lbshell/open_source_release/gitscrub.py"
-			],
-			[
-				"sanitize",
-				"tools/lbshell/open_source_release/sanitize.py"
-			],
-			[
-				"image_decoder_test",
-				"cobalt/loader/image/image_decoder_test.cc"
-			],
-			[
-				"web_mod",
-				"cobalt/browser/web_module.cc"
-			],
-			[
-				"animatedwebp",
-				"cobalt/loader/image/animated_webp_image.cc"
-			]
-		],
-		"width": 0.0
-	},
-	"select_project":
-	{
-		"height": 500.0,
-		"last_filter": "",
-		"selected_items":
-		[
-			[
-				"",
-				"~/src/sublime_projects/cobalt.sublime-project"
-			],
-			[
-				"19",
-				"~/src/cobalt_19/cobalt_19.sublime-workspace"
-			]
-		],
-		"width": 380.0
-	},
-	"select_symbol":
-	{
-		"height": 392.0,
-		"last_filter": "onsuspend",
-		"selected_items":
-		[
-			[
-				"onsuspend",
-				"OnSuspend"
-			],
-			[
-				"Suspend",
-				"Suspend"
-			],
-			[
-				"TimeTicksNowIgnoringOverride",
-				"TimeTicksNowIgnoringOverride"
-			],
-			[
-				"timeticks",
-				"TimeTicks"
-			],
-			[
-				"defaulttickcl",
-				"DefaultTickClock"
-			],
-			[
-				"urlfetcher",
-				"URLFetcher"
-			],
-			[
-				"DefaultTickClock",
-				"DefaultTickClock"
-			],
-			[
-				"submitresultstest",
-				"SubmitResultsTest"
-			],
-			[
-				"screenshotmana",
-				"ScreenshotManager"
-			],
-			[
-				"GetMarginBoxTransformFromContainingBlock",
-				"GetMarginBoxTransformFromContainingBlock"
-			],
-			[
-				"__system_property_get",
-				"__system_property_get"
-			],
-			[
-				"EnumerateLayoutTests",
-				"EnumerateLayoutTests"
-			],
-			[
-				"postblockingtask",
-				"PostBlockingTask"
-			],
-			[
-				"waitforfen",
-				"WaitForFence"
-			],
-			[
-				"THREAD_CHECKER",
-				"THREAD_CHECKER"
-			],
-			[
-				"animatedimage",
-				"AnimatedImage"
-			],
-			[
-				"urlsearchpa",
-				"URLSearchParams"
-			],
-			[
-				"decodeURIComponent",
-				"DecodeUriComponent"
-			],
-			[
-				"StringPieceReplacements",
-				"StringPieceReplacements"
-			],
-			[
-				"replacements",
-				"Replacements"
-			],
-			[
-				"EscapeQueryParamValue",
-				"EscapeQueryParamValue"
-			],
-			[
-				"escapequerypa",
-				"EscapeQueryParamValue"
-			],
-			[
-				"generate_url",
-				"generate_url"
-			],
-			[
-				"loadyoutube",
-				"LoadYouTube"
-			],
-			[
-				"uint8_t",
-				"uint8_t"
-			],
-			[
-				"SbSocketClearLastError",
-				"SbSocketClearLastError"
-			],
-			[
-				"SbSocketGetLastError",
-				"SbSocketGetLastError"
-			],
-			[
-				"Waitee",
-				"Waitee"
-			],
-			[
-				"MapLastSocketError",
-				"MapLastSocketError"
-			],
-			[
-				"mapsocketer",
-				"MapSocketError"
-			],
-			[
-				"SbSocketWaiterAdd",
-				"SbSocketWaiterAdd"
-			],
-			[
-				"watch",
-				"Watch"
-			],
-			[
-				"safe_buff",
-				"safe_buffer"
-			],
-			[
-				"modp_b64_decode",
-				"modp_b64_decode"
-			],
-			[
-				"base64dec",
-				"Base64Decode"
-			],
-			[
-				"EVP_sha256",
-				"EVP_sha256"
-			],
-			[
-				"GetDeviceAuthenticationSignedURLQueryStringFromComponents",
-				"GetDeviceAuthenticationSignedURLQueryStringFromComponents"
-			],
-			[
-				"splashscreen",
-				"SplashScreen"
-			],
-			[
-				"V8_INLINE",
-				"V8_INLINE"
-			],
-			[
-				"sb_api",
-				"SB_API_VERSION"
-			],
-			[
-				"base64urlen",
-				"Base64UrlEncode"
-			],
-			[
-				"base64encode",
-				"Base64Encode"
-			],
-			[
-				"base64end",
-				"Base64EncodeDecodeTest"
-			],
-			[
-				"base64enco",
-				"Base64Encode"
-			],
-			[
-				"getsystemproper",
-				"GetSystemProperty"
-			],
-			[
-				"base64deco",
-				"Base64Decode"
-			],
-			[
-				"Base64UrlEncodePolicy",
-				"Base64UrlEncodePolicy"
-			],
-			[
-				"hmac",
-				"HMAC"
-			],
-			[
-				"init_musl_hwcap",
-				"init_musl_hwcap"
-			],
-			[
-				"findconver",
-				"findConverter"
-			],
-			[
-				"generateauthto",
-				"GenerateAuthToken"
-			],
-			[
-				"CreateAuthHandlerFromString",
-				"CreateAuthHandlerFromString"
-			],
-			[
-				"TestCompletionCallback",
-				"TestCompletionCallback"
-			],
-			[
-				"base64encod",
-				"Base64Encode"
-			],
-			[
-				"generateauthtok",
-				"GenerateAuthToken"
-			],
-			[
-				"cvalkeyl",
-				"CValKeyList"
-			],
-			[
-				"gclient",
-				"GClient"
-			],
-			[
-				"fileopen",
-				"FileOpen"
-			],
-			[
-				"collectintoline",
-				"CollectItemIntoLine"
-			],
-			[
-				"ScanFont",
-				"ScanFont"
-			],
-			[
-				"MakeFromStream",
-				"MakeFromStream"
-			],
-			[
-				"CreateTypefaceFromRawData",
-				"CreateTypefaceFromRawData"
-			],
-			[
-				"sb_notre",
-				"SB_NOTREACHED"
-			],
-			[
-				"queryselectorallmetho",
-				"querySelectorAllMethod"
-			],
-			[
-				"handleapicall",
-				"HandleApiCallHelper"
-			],
-			[
-				"SpeechRecognitionAlternative",
-				"SpeechRecognitionAlternative"
-			],
-			[
-				"SpeechRecognitionResult",
-				"SpeechRecognitionResult"
-			],
-			[
-				"SpeechRecognitionResults",
-				"SpeechRecognitionResults"
-			],
-			[
-				"SpeechRecognitionResultList",
-				"SpeechRecognitionResultList"
-			],
-			[
-				"weakptr",
-				"WeakPtr"
-			],
-			[
-				"CpuFeatures",
-				"CpuFeatureScope"
-			],
-			[
-				"STARBOARD_WRAP",
-				"STARBOARD_WRAP_SIMPLE_MAIN"
-			],
-			[
-				"COBALT_WRAP_BASE_MAIN",
-				"COBALT_WRAP_BASE_MAIN"
-			],
-			[
-				"serializationdata",
-				"SerializationData"
-			],
-			[
-				"deserializer",
-				"DeserializeRegularExports"
-			],
-			[
-				"STARBOARD_WRAP_SIMPLE_MAIN",
-				"STARBOARD_WRAP_SIMPLE_MAIN"
-			],
-			[
-				"cobalt_wrap",
-				"COBALT_WRAP_MAIN"
-			],
-			[
-				"promisestate",
-				"PromiseState"
-			],
-			[
-				"sbcoredumphandler",
-				"SbCoreDumpRegisterHandler"
-			],
-			[
-				"setupdefaultlogg",
-				"SetupDefaultLoggingConfig"
-			],
-			[
-				"IsKeyActive",
-				"IsKeyActive"
-			],
-			[
-				"tlskey",
-				"TLSKeyManager"
-			],
-			[
-				"IsPromiseStatus",
-				"IsPromiseStatus"
-			],
-			[
-				"userlog",
-				"UserLog"
-			],
-			[
-				"Register",
-				"Register"
-			],
-			[
-				"HtmlElementCountLog",
-				"HtmlElementCountLog"
-			],
-			[
-				"CobaltArchiveSteps",
-				"CobaltArchiveSteps"
-			],
-			[
-				"changefilter",
-				"_changeFilter"
-			],
-			[
-				"sbblitterrect",
-				"SbBlitterRect"
-			],
-			[
-				"cvalstats",
-				"CValStats"
-			],
-			[
-				"notreached",
-				"NOTREACHED"
-			],
-			[
-				"wraprefcou",
-				"WrapRefCounted"
-			],
-			[
-				"tojsvalue",
-				"ToJSValue"
-			],
-			[
-				"ERR_print_errors_fp",
-				"ERR_print_errors_fp"
-			],
-			[
-				"err_print",
-				"ERR_print_errors_fp"
-			],
-			[
-				"iovec",
-				"iovec"
-			],
-			[
-				"mediasessionplayb",
-				"MediaSessionPlaybackState"
-			],
-			[
-				"OnMediaSessionChanged",
-				"OnMediaSessionChanged"
-			],
-			[
-				"setactionhand",
-				"SetActionHandler"
-			],
-			[
-				"intersectionobserverreg",
-				"IntersectionObserverRegistration"
-			],
-			[
-				"LockImpl",
-				"LockImpl"
-			],
-			[
-				"traceable",
-				"Traceable"
-			],
-			[
-				"IntersectionObserverRegistration",
-				"IntersectionObserverRegistration"
-			],
-			[
-				"domexcept",
-				"DOMException"
-			],
-			[
-				"version",
-				"version"
-			],
-			[
-				"transport_vers",
-				"transport_version"
-			],
-			[
-				"getquicvers",
-				"GetQuicVersion"
-			],
-			[
-				"sbmutexcreate",
-				"SbMutexCreate"
-			],
-			[
-				"buildnamed",
-				"BuildNamed"
-			],
-			[
-				"setuptexturena",
-				"SetupTextureAndRenderTarget"
-			],
-			[
-				"setuptextureandr",
-				"SetupTextureAndRenderTarget"
-			],
-			[
-				"offsetclo",
-				"OffsetClock"
-			],
-			[
-				"generaterequest",
-				"GenerateRequest"
-			],
-			[
-				"SbDrmGenerateSessionUpdateRequest",
-				"SbDrmGenerateSessionUpdateRequest"
-			],
-			[
-				"IntersectionObserverEntryInit",
-				"IntersectionObserverEntryInit"
-			],
-			[
-				"abort",
-				"abort"
-			],
-			[
-				"DynamicallyBuildOutDirectory",
-				"DynamicallyBuildOutDirectory"
-			],
-			[
-				"elementvecto",
-				"ElementVector"
-			],
-			[
-				"SbDecodeTargetRelease",
-				"SbDecodeTargetRelease"
-			],
-			[
-				"DecodeTargetReferenceCounted",
-				"DecodeTargetReferenceCounted"
-			],
-			[
-				"textureegl",
-				"TextureEGL"
-			],
-			[
-				"CreateImageFromSbDecodeTarget",
-				"CreateImageFromSbDecodeTarget"
-			],
-			[
-				"mapbufferrange",
-				"MapBufferRange"
-			],
-			[
-				"glMapBufferRange",
-				"glMapBufferRange"
-			],
-			[
-				"UnixEpoch",
-				"UnixEpoch"
-			],
-			[
-				"pixelstorei",
-				"PixelStorei"
-			],
-			[
-				"gl_call_sim",
-				"GL_CALL_SIMPLE"
-			],
-			[
-				"GetNavigationStartClock",
-				"GetNavigationStartClock"
-			]
-		],
-		"width": 758.0
-	},
-	"selected_group": 2,
-	"settings":
-	{
-	},
-	"show_minimap": true,
-	"show_open_files": false,
-	"show_tabs": true,
-	"side_bar_visible": false,
-	"side_bar_width": 582.0,
-	"status_bar_visible": true,
-	"template_settings":
-	{
-	}
-}
diff --git a/src/.pre-commit-config.yaml b/src/.pre-commit-config.yaml
new file mode 100644
index 0000000..7d2b389
--- /dev/null
+++ b/src/.pre-commit-config.yaml
@@ -0,0 +1,120 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+default_stages: [commit]
+
+default_language_version:
+    python: python3
+
+exclude: '^third_party/'
+
+repos:
+-   repo: https://cobalt.googlesource.com/pre-commit-hooks
+    rev: e1668fe86af3810fbca72b8653fe478e66a0afdc  # v3.2.0
+    hooks:
+    -   id: check-case-conflict
+    -   id: end-of-file-fixer
+    -   id: trailing-whitespace
+    -   id: mixed-line-ending
+
+-   repo: local
+    hooks:
+    -   id: sync-keyboxes
+        name: sync-keyboxes
+        entry: python ./precommit_hooks/sync_keyboxes_wrapper.py
+        language: python
+        stages: [post-checkout]
+        always_run: true
+    -   id: cpplint
+        name: cpplint
+        entry: cpplint
+        language: system
+        types: [c++]
+        args: [--verbose=4, --quiet]
+        exclude: '.*tests?.(cc|h)$'
+        exclude: '^cobalt/bindings/(templates|generated)/'
+    -   id: cpplint_test
+        name: cpplint_test
+        entry: cpplint
+        language: system
+        types: [c++]
+        args: [--verbose=5, --quiet]
+        files: '.*tests?.(cc|h)$'
+    -   id: yapf
+        name: yapf
+        entry: yapf
+        language: system
+        types: [python]
+        args: [--style=yapf, -i]
+        exclude: '\.gypi?$'
+    -   id: pylint
+        name: pylint
+        entry: pylint
+        language: system
+        types: [python]
+        args: [-d W0201]
+        exclude: '\.gypi?$'
+    -   id: clang-format
+        name: clang-format
+        entry: python ./precommit_hooks/clang_format_wrapper.py
+        language: python
+        types: [c++]
+        args: [-i, -style=file]
+    -   id: google-java-format
+        name: google-java-format
+        entry: python ./precommit_hooks/google_java_format_wrapper.py
+        language: python
+        types: [java]
+        args: [-i]
+    -   id: gcheckstyle
+        name: gcheckstyle
+        entry: python ./precommit_hooks/gcheckstyle_wrapper.py
+        language: python
+        types: [java]
+        verbose: true
+    -   id: check-copyright-year
+        name: check copyright year
+        entry: python ./precommit_hooks/custom_hooks/check_copyright_year.py
+        language: python
+        types: [file, text]
+        stages: [push]
+    -   id: check-if-starboard-interface-changed
+        name: check if starboard interface changed
+        entry: python ./precommit_hooks/custom_hooks/warn_that_starboard_interface_changed_wrapper.py
+        language: python
+        files: '^starboard/*.h$'
+        stages: [push]
+    -   id: download-resources
+        name: download resources
+        entry: python ./download_resources.py
+        language: python
+        stages: [post-checkout]
+        always_run: true
+    -   id: test-download-from-gcs-helper
+        name: test download from gcs helper
+        entry: python
+        language: python
+        pass_filenames: false
+        always_run: true
+        stages: [push]
+        args: [-m, unittest, tools/download_from_gcs_test.py]
+    -   id: test-python3-compatibility
+        name: Test Python 3 Compatibility
+        description: Checks that scripts can be run in Python 3
+        entry: python precommit_hooks/python3_check.py
+        language: python
+        types: [python]
+        verbose: true
+    -   id: check-bug-in-commit-message
+        name: Check Bug In Commit Message
+        description: Checks for a tracking bug in a commit message
+        entry: python precommit_hooks/check_bug_in_description_wrapper.py
+        language: python
+        stages: [push]
+        always_run: true
+    -   id: run-py2-tests
+        name: Run Python 2 Tests
+        description: Run Python 2 unittests
+        entry: python precommit_hooks/custom_hooks/run_python2_unittests.py
+        language: python
+        language_version: python2
+        types: [python]
diff --git a/src/base/base.gyp b/src/base/base.gyp
index e223b87..f8edb02 100644
--- a/src/base/base.gyp
+++ b/src/base/base.gyp
@@ -915,9 +915,8 @@
         'trace_event/trace_event_filter_test_utils.cc',
         'trace_event/trace_event_filter_test_utils.h',
         'trace_event/trace_event_system_stats_monitor_unittest.cc',
-        # TODO[Cobalt]:re-enable these.
-        # 'trace_event/blame_context_unittest.cc',
-        # 'trace_event/trace_event_unittest.cc',
+        'trace_event/blame_context_unittest.cc',
+        'trace_event/trace_event_unittest.cc',
         'tuple_unittest.cc',
         'unguessable_token_unittest.cc',
         'value_iterators_unittest.cc',
diff --git a/src/base/base_paths.h b/src/base/base_paths.h
index 9c712f8..5e1b9fd 100644
--- a/src/base/base_paths.h
+++ b/src/base/base_paths.h
@@ -16,7 +16,7 @@
 #include "base/base_paths_mac.h"
 #elif defined(OS_ANDROID)
 #include "base/base_paths_android.h"
-#elif defined(OS_STARBOARD)
+#elif defined(STARBOARD)
 #include "base/base_paths_starboard.h"
 #endif
 
diff --git a/src/base/command_line.cc b/src/base/command_line.cc
index 2c1ed1d..b3ffd42 100644
--- a/src/base/command_line.cc
+++ b/src/base/command_line.cc
@@ -221,7 +221,7 @@
   current_process_commandline_ = new CommandLine(NO_PROGRAM);
 #if defined(OS_WIN)
   current_process_commandline_->ParseFromString(::GetCommandLineW());
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   current_process_commandline_->InitFromArgv(argc, argv);
 #else
 #error Unsupported platform
@@ -280,7 +280,7 @@
 void CommandLine::SetProgram(const FilePath& program) {
 #if defined(OS_WIN)
   TrimWhitespace(program.value(), TRIM_ALL, &argv_[0]);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   TrimWhitespaceASCII(program.value(), TRIM_ALL, &argv_[0]);
 #else
 #error Unsupported platform
@@ -305,7 +305,7 @@
   }
 #if defined(OS_WIN)
   return UTF16ToASCII(value);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   return value;
 #endif
 }
diff --git a/src/base/containers/hash_tables.h b/src/base/containers/hash_tables.h
index 3b6c856..00966b7 100644
--- a/src/base/containers/hash_tables.h
+++ b/src/base/containers/hash_tables.h
@@ -17,7 +17,7 @@
 
 // Chromium has moved away from compiler specific hash methods and instead uses
 // std::hashes unconditionally. Starboard sadly does not guarantee std::hash.
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/configuration.h"
 #if SB_HAS(STD_UNORDERED_HASH)
 #define BASE_HASH_DEFINE_LONG_LONG_HASHES 0
diff --git a/src/base/files/file.cc b/src/base/files/file.cc
index 21a9926..36ae965 100644
--- a/src/base/files/file.cc
+++ b/src/base/files/file.cc
@@ -13,7 +13,7 @@
 #include <errno.h>
 #endif
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/common/log.h"
 #include "starboard/types.h"
 #endif
@@ -84,7 +84,7 @@
 #if !defined(OS_NACL)
 void File::Initialize(const FilePath& path, uint32_t flags) {
   if (path.ReferencesParent()) {
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 
 #else
 #if defined(OS_WIN)
@@ -94,7 +94,7 @@
 #else
 #error Unsupported platform
 #endif  // defined(OS_WIN)
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
     error_details_ = FILE_ERROR_ACCESS_DENIED;
     return;
   }
diff --git a/src/base/files/file_path.cc b/src/base/files/file_path.cc
index 92b31f6..9c224b0 100644
--- a/src/base/files/file_path.cc
+++ b/src/base/files/file_path.cc
@@ -681,7 +681,7 @@
 void FilePath::WriteToPickle(Pickle* pickle) const {
 #if defined(OS_WIN)
   pickle->WriteString16(path_);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   pickle->WriteString(path_);
 #else
 #error Unsupported platform
@@ -692,7 +692,7 @@
 #if defined(OS_WIN)
   if (!iter->ReadString16(&path_))
     return false;
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   if (!iter->ReadString(&path_))
     return false;
 #else
@@ -1286,7 +1286,7 @@
   return HFSFastUnicodeCompare(hfs1, hfs2);
 }
 
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
 
 // Generic Posix system comparisons.
 int FilePath::CompareIgnoreCase(StringPieceType string1,
diff --git a/src/base/files/file_util.h b/src/base/files/file_util.h
index 9a2d101..2998e23 100644
--- a/src/base/files/file_util.h
+++ b/src/base/files/file_util.h
@@ -77,7 +77,7 @@
 BASE_EXPORT bool DeleteFileAfterReboot(const FilePath& path);
 #endif
 
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
 // Moves the given path, whether it's a file or a directory.
 // If a simple rename is not possible, such as in the case where the paths are
 // on different volumes, this will attempt to copy and delete. Returns
@@ -350,7 +350,7 @@
 // Returns information about the given file path.
 BASE_EXPORT bool GetFileInfo(const FilePath& file_path, File::Info* info);
 
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
 // Sets the time of the last access and the time of the last modification.
 BASE_EXPORT bool TouchFile(const FilePath& path,
                            const Time& last_accessed,
diff --git a/src/base/files/file_util_unittest.cc b/src/base/files/file_util_unittest.cc
index 5858ba4..58828db 100644
--- a/src/base/files/file_util_unittest.cc
+++ b/src/base/files/file_util_unittest.cc
@@ -2914,7 +2914,7 @@
 #endif  // !defined(OS_WIN)
 
 #if !defined(OS_WIN) && !defined(OS_NACL) && !defined(OS_FUCHSIA) && \
-    !defined(OS_IOS) && !defined(OS_STARBOARD)
+    !defined(OS_IOS) && !defined(STARBOARD)
 #define ChildMain WriteToPipeChildMain
 #define ChildMainString "WriteToPipeChildMain"
 
@@ -3709,7 +3709,7 @@
 #else
 #define MAYBE_MultiThreadedTempFiles MultiThreadedTempFiles
 #endif
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
 TEST(FileUtilMultiThreadedTest, MAYBE_MultiThreadedTempFiles) {
   constexpr int kNumThreads = 64;
   constexpr int kNumWritesPerThread = 32;
@@ -3764,7 +3764,7 @@
   for (auto& thread : threads)
     thread->Stop();
 }
-#endif  // !defined(OS_STARBOARD)
+#endif  // !defined(STARBOARD)
 
 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
 
diff --git a/src/base/files/important_file_writer.cc b/src/base/files/important_file_writer.cc
index 30d0585..360b675 100644
--- a/src/base/files/important_file_writer.cc
+++ b/src/base/files/important_file_writer.cc
@@ -131,7 +131,7 @@
 
 }  // namespace
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 // static
 bool ImportantFileWriter::WriteFileAtomically(const FilePath& path,
                                               StringPiece data,
diff --git a/src/base/files/important_file_writer_unittest.cc b/src/base/files/important_file_writer_unittest.cc
index 764cebc..bd5007f 100644
--- a/src/base/files/important_file_writer_unittest.cc
+++ b/src/base/files/important_file_writer_unittest.cc
@@ -182,7 +182,7 @@
 
 // Disable the test as win32 SbFileOpen doesn't fail on relative path
 // like bad/../path.tmp
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
 TEST_F(ImportantFileWriterTest, FailedWriteWithObserver) {
   // Use an invalid file path (relative paths are invalid) to get a
   // FILE_ERROR_ACCESS_DENIED error when trying to write the file.
@@ -332,7 +332,7 @@
   EXPECT_FALSE(PathExists(writer.path()));
 }
 
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
 TEST_F(ImportantFileWriterTest, WriteFileAtomicallyHistogramSuffixTest) {
   base::HistogramTester histogram_tester;
   EXPECT_FALSE(PathExists(file_));
diff --git a/src/base/i18n/break_iterator_unittest.cc b/src/base/i18n/break_iterator_unittest.cc
index 6d0d6f1..b9dc161 100644
--- a/src/base/i18n/break_iterator_unittest.cc
+++ b/src/base/i18n/break_iterator_unittest.cc
@@ -147,7 +147,7 @@
 // Japanese is not shipped on mobile.
 // Cobalt does not support Chinese/Japanese word breaking yet. This feature
 // requires a big dictionary(cjdict.txt) to support.
-#if !(defined(OS_IOS) || defined(OS_ANDROID) || defined(OS_STARBOARD))
+#if !(defined(OS_IOS) || defined(OS_ANDROID) || defined(STARBOARD))
 
 TEST(BreakIteratorTest, BreakWordChinese) {
   // Terms in Traditional Chinese, without spaces in between.
diff --git a/src/base/i18n/file_util_icu.cc b/src/base/i18n/file_util_icu.cc
index 96ca9d2..d5418a5 100644
--- a/src/base/i18n/file_util_icu.cc
+++ b/src/base/i18n/file_util_icu.cc
@@ -118,7 +118,7 @@
     // Windows uses UTF-16 encoding for filenames.
     U16_NEXT(file_name->data(), cursor, static_cast<int>(file_name->length()),
              code_point);
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
     // Mac and Chrome OS use UTF-8 encoding for filenames.
     // Linux doesn't actually define file system encoding. Try to parse as
     // UTF-8.
diff --git a/src/base/logging.cc b/src/base/logging.cc
index e75d72e..77dfd76 100644
--- a/src/base/logging.cc
+++ b/src/base/logging.cc
@@ -150,7 +150,7 @@
 // first needed.
 #if defined(OS_WIN)
 typedef std::wstring PathString;
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
 typedef std::string PathString;
 #endif
 PathString* g_log_file_name = nullptr;
diff --git a/src/base/logging_unittest.cc b/src/base/logging_unittest.cc
index 95dbfae..22b0ef7 100644
--- a/src/base/logging_unittest.cc
+++ b/src/base/logging_unittest.cc
@@ -556,7 +556,7 @@
 #endif  // DCHECK_IS_CONFIGURABLE
 
 // https://crbug.com/709067 tracks test flakiness on iOS.
-#if defined(OS_IOS) || defined(OS_STARBOARD)
+#if defined(OS_IOS) || defined(STARBOARD)
 #define MAYBE_Dcheck DISABLED_Dcheck
 #else
 #define MAYBE_Dcheck Dcheck
diff --git a/src/base/memory/aligned_memory.cc b/src/base/memory/aligned_memory.cc
index 0ae2268..9a6d88f 100644
--- a/src/base/memory/aligned_memory.cc
+++ b/src/base/memory/aligned_memory.cc
@@ -20,7 +20,7 @@
   DCHECK_EQ(alignment & (alignment - 1), 0U);
   DCHECK_EQ(alignment % sizeof(void*), 0U);
   void* ptr = nullptr;
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
   ptr = SbMemoryAllocateAligned(alignment, size);
 #elif defined(COMPILER_MSVC)
   ptr = _aligned_malloc(size, alignment);
diff --git a/src/base/message_loop/message_loop.cc b/src/base/message_loop/message_loop.cc
index 11b4a69..bd9808a 100644
--- a/src/base/message_loop/message_loop.cc
+++ b/src/base/message_loop/message_loop.cc
@@ -631,7 +631,7 @@
   return MessageLoopCurrentForUI::IsSet();
 }
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 void MessageLoopForUI::Start() {
   // No Histogram support for UI message loop as it is managed by Starboard.
   static_cast<base::MessagePumpUIStarboard*>(pump_.get())->Start(this);
diff --git a/src/base/message_loop/message_pump_for_io.h b/src/base/message_loop/message_pump_for_io.h
index 5efcffb..3683513 100644
--- a/src/base/message_loop/message_pump_for_io.h
+++ b/src/base/message_loop/message_pump_for_io.h
@@ -37,7 +37,7 @@
 using MessagePumpForIO = MessagePumpFuchsia;
 #elif defined(OS_POSIX)
 using MessagePumpForIO = MessagePumpLibevent;
-#elif defined(OS_STARBOARD)
+#elif defined(STARBOARD)
 using MessagePumpForIO = MessagePumpIOStarboard;
 #else
 #error Platform does not define MessagePumpForIO
diff --git a/src/base/message_loop/message_pump_for_ui.h b/src/base/message_loop/message_pump_for_ui.h
index 6660937..9d4c6ca 100644
--- a/src/base/message_loop/message_pump_for_ui.h
+++ b/src/base/message_loop/message_pump_for_ui.h
@@ -24,7 +24,7 @@
 #include "base/message_loop/message_pump_libevent.h"
 #elif defined(OS_FUCHSIA)
 #include "base/message_loop/message_pump_fuchsia.h"
-#elif defined(OS_STARBOARD)
+#elif defined(STARBOARD)
 #include "base/message_loop/message_pump_ui_starboard.h"
 #endif
 
@@ -50,7 +50,7 @@
 using MessagePumpForUI = MessagePumpLibevent;
 #elif defined(OS_FUCHSIA)
 using MessagePumpForUI = MessagePumpFuchsia;
-#elif defined(OS_STARBOARD)
+#elif defined(STARBOARD)
 using MessagePumpForUI = MessagePumpUIStarboard;
 #else
 #error Platform does not define MessagePumpForUI
diff --git a/src/base/message_loop/message_pump_ui_starboard.cc b/src/base/message_loop/message_pump_ui_starboard.cc
index 0606fa0..9a30ca3 100644
--- a/src/base/message_loop/message_pump_ui_starboard.cc
+++ b/src/base/message_loop/message_pump_ui_starboard.cc
@@ -170,6 +170,14 @@
   // We expect to start with a delegate, so we can DCHECK it, but any task we
   // run could call Quit and remove it.
   DCHECK(delegate_);
+  if (!delegate_) {
+#if !defined(COBALT_BUILD_TYPE_GOLD)
+    // Abort if this is a QA build to signal that this is unexpected.
+    CHECK(delegate_);
+#endif
+    // Drop the work if there is no delegate for it.
+    return false;
+  }
 
   // Do immediate work.
   bool did_work = delegate_->DoWork();
diff --git a/src/base/path_service.cc b/src/base/path_service.cc
index 9d7ae8b..3310599 100644
--- a/src/base/path_service.cc
+++ b/src/base/path_service.cc
@@ -149,7 +149,7 @@
     providers = &base_provider_fuchsia;
 #elif defined(OS_POSIX)
     providers = &base_provider_posix;
-#elif defined(OS_STARBOARD)
+#elif defined(STARBOARD)
     providers = &base_provider_starboard;
 #endif
   }
@@ -280,7 +280,7 @@
   }
 
   // We need to have an absolute path.
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
   if (!is_absolute) {
     file_path = MakeAbsoluteFilePath(file_path);
     if (file_path.empty())
diff --git a/src/base/process/process_metrics_linux.cc b/src/base/process/process_metrics_linux.cc
index 66b45d9..4eceda6 100644
--- a/src/base/process/process_metrics_linux.cc
+++ b/src/base/process/process_metrics_linux.cc
@@ -25,7 +25,6 @@
 #include "base/strings/string_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
-#include "starboard/character.h"
 #include "starboard/common/string.h"
 #include "starboard/types.h"
 
@@ -715,7 +714,7 @@
 
   // mmcblk[0-9]+ case
   for (size_t i = SbStringGetLength(kMMCName); i < candidate.length(); ++i) {
-    if (!SbCharacterIsDigit(candidate[i]))
+    if (!isdigit(candidate[i]))
       return false;
   }
   return true;
diff --git a/src/base/strings/string_number_conversions.cc b/src/base/strings/string_number_conversions.cc
index 05d2b98..8a57e5e 100644
--- a/src/base/strings/string_number_conversions.cc
+++ b/src/base/strings/string_number_conversions.cc
@@ -108,7 +108,7 @@
 template<> class WhitespaceHelper<char> {
  public:
   static bool Invoke(char c) {
-    return 0 != SbCharacterIsSpace(static_cast<unsigned char>(c));
+    return 0 != isspace(static_cast<unsigned char>(c));
   }
 };
 
@@ -448,7 +448,7 @@
   //  - If the first character is a space, there was leading whitespace
   return errno == 0 && !input.empty() &&
          input.c_str() + input.length() == endptr &&
-         !SbCharacterIsSpace(input[0]);
+         !isspace(input[0]);
 }
 
 // Note: if you need to add String16ToDouble, first ask yourself if it's
diff --git a/src/base/synchronization/waitable_event.h b/src/base/synchronization/waitable_event.h
index 7055291..646a49e 100644
--- a/src/base/synchronization/waitable_event.h
+++ b/src/base/synchronization/waitable_event.h
@@ -229,7 +229,7 @@
   // the event, unlike the receive right, since a deleted event cannot be
   // signaled.
   mac::ScopedMachSendRight send_right_;
-#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(OS_STARBOARD)
+#elif defined(OS_POSIX) || defined(OS_FUCHSIA) || defined(STARBOARD)
   // On Windows, you must not close a HANDLE which is currently being waited on.
   // The MSDN documentation says that the resulting behaviour is 'undefined'.
   // To solve that issue each WaitableEventWatcher duplicates the given event
diff --git a/src/base/task/task_scheduler/task_scheduler.cc b/src/base/task/task_scheduler/task_scheduler.cc
index 864c07e..9f4a759 100644
--- a/src/base/task/task_scheduler/task_scheduler.cc
+++ b/src/base/task/task_scheduler/task_scheduler.cc
@@ -66,8 +66,11 @@
   const int num_cores = SysInfo::NumberOfProcessors();
   constexpr int kBackgroundMaxThreads = 1;
   constexpr int kBackgroundBlockingMaxThreads = 2;
-  const int kForegroundMaxThreads = std::max(1, num_cores - 1);
-  const int kForegroundBlockingMaxThreads = std::max(2, num_cores - 1);
+  constexpr int kMaxNumberOfThreads = 32;
+  const int kForegroundMaxThreads =
+      std::min(std::max(1, num_cores - 1), kMaxNumberOfThreads);
+  const int kForegroundBlockingMaxThreads =
+      std::min(std::max(2, num_cores - 1), kMaxNumberOfThreads);
 
   constexpr TimeDelta kSuggestedReclaimTime = TimeDelta::FromSeconds(30);
 
diff --git a/src/base/third_party/xdg_mime/README.chromium b/src/base/third_party/xdg_mime/README.chromium
index 8212752..8b1b4ed 100644
--- a/src/base/third_party/xdg_mime/README.chromium
+++ b/src/base/third_party/xdg_mime/README.chromium
@@ -12,3 +12,6 @@
       xdg_mime_get_mime_type_for_file() - use of pointer after being freed.
   - function_casts.patch: fix bad function casts.
   - Added a LICENSE file.
+
+Of the dual-licenses, it is licensed under the terms of the Academic Free
+License, version 2.0, in licenses_cobalt.txt.
diff --git a/src/base/threading/thread_collision_warner.h b/src/base/threading/thread_collision_warner.h
index b6993f6..bb1ade0 100644
--- a/src/base/threading/thread_collision_warner.h
+++ b/src/base/threading/thread_collision_warner.h
@@ -79,7 +79,7 @@
 // };
 //
 //
-// Example: Class that has to be contructed/destroyed on same thread, it has
+// Example: Class that has to be constructed/destroyed on same thread, it has
 //          a "shareable" method (with external synchronization) and a not
 //          shareable method (even with external synchronization).
 //
@@ -98,24 +98,22 @@
 //   DFAKE_MUTEX(shareable_section_);
 // };
 
-
 #if !defined(NDEBUG)
 
 // Defines a class member that acts like a mutex. It is used only as a
 // verification tool.
-#define DFAKE_MUTEX(obj) \
-     mutable base::ThreadCollisionWarner obj
+#define DFAKE_MUTEX(obj) mutable base::ThreadCollisionWarner obj
 // Asserts the call is never called simultaneously in two threads. Used at
 // member function scope.
 #define DFAKE_SCOPED_LOCK(obj) \
-     base::ThreadCollisionWarner::ScopedCheck s_check_##obj(&obj)
+  base::ThreadCollisionWarner::ScopedCheck s_check_##obj(&obj)
 // Asserts the call is never called simultaneously in two threads. Used at
 // member function scope. Same as DFAKE_SCOPED_LOCK but allows recursive locks.
 #define DFAKE_SCOPED_RECURSIVE_LOCK(obj) \
-     base::ThreadCollisionWarner::ScopedRecursiveCheck sr_check_##obj(&obj)
+  base::ThreadCollisionWarner::ScopedRecursiveCheck sr_check_##obj(&obj)
 // Asserts the code is always executed in the same thread.
 #define DFAKE_SCOPED_LOCK_THREAD_LOCKED(obj) \
-     base::ThreadCollisionWarner::Check check_##obj(&obj)
+  base::ThreadCollisionWarner::Check check_##obj(&obj)
 
 #else
 
@@ -146,13 +144,9 @@
  public:
   // The parameter asserter is there only for test purpose
   explicit ThreadCollisionWarner(AsserterBase* asserter = new DCheckAsserter())
-      : valid_thread_id_(0),
-        counter_(0),
-        asserter_(asserter) {}
+      : valid_thread_id_(0), counter_(0), asserter_(asserter) {}
 
-  ~ThreadCollisionWarner() {
-    delete asserter_;
-  }
+  ~ThreadCollisionWarner() { delete asserter_; }
 
   // This class is meant to be used through the macro
   // DFAKE_SCOPED_LOCK_THREAD_LOCKED
@@ -161,8 +155,7 @@
   // from one thread
   class BASE_EXPORT Check {
    public:
-    explicit Check(ThreadCollisionWarner* warner)
-        : warner_(warner) {
+    explicit Check(ThreadCollisionWarner* warner) : warner_(warner) {
       warner_->EnterSelf();
     }
 
@@ -178,14 +171,11 @@
   // DFAKE_SCOPED_LOCK
   class BASE_EXPORT ScopedCheck {
    public:
-    explicit ScopedCheck(ThreadCollisionWarner* warner)
-        : warner_(warner) {
+    explicit ScopedCheck(ThreadCollisionWarner* warner) : warner_(warner) {
       warner_->Enter();
     }
 
-    ~ScopedCheck() {
-      warner_->Leave();
-    }
+    ~ScopedCheck() { warner_->Leave(); }
 
    private:
     ThreadCollisionWarner* warner_;
@@ -202,9 +192,7 @@
       warner_->EnterSelf();
     }
 
-    ~ScopedRecursiveCheck() {
-      warner_->Leave();
-    }
+    ~ScopedRecursiveCheck() { warner_->Leave(); }
 
    private:
     ThreadCollisionWarner* warner_;
diff --git a/src/base/time/pr_time_unittest.cc b/src/base/time/pr_time_unittest.cc
index 1a28725..a0471a4 100644
--- a/src/base/time/pr_time_unittest.cc
+++ b/src/base/time/pr_time_unittest.cc
@@ -32,7 +32,7 @@
 class PRTimeTest : public testing::Test {
  protected:
   void SetUp() override {
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
     Time local_time = base::test::time_helpers::TestDateToTime(
         base::test::time_helpers::kTimeZoneLocal);
     comparison_time_local_ =
diff --git a/src/base/time/time.h b/src/base/time/time.h
index a88e735..88d1238 100644
--- a/src/base/time/time.h
+++ b/src/base/time/time.h
@@ -182,7 +182,7 @@
     return delta_ == std::numeric_limits<int64_t>::min();
   }
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
   SbTime ToSbTime() const;
 #endif
 
diff --git a/src/base/time/time_unittest.cc b/src/base/time/time_unittest.cc
index a3033c1..b29019e 100644
--- a/src/base/time/time_unittest.cc
+++ b/src/base/time/time_unittest.cc
@@ -101,14 +101,14 @@
 class TimeTest : public testing::Test {
  protected:
   void SetUp() override {
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
     // Since we don't have access to mktime, let's use time_helpers to do the
     // same thing in a portable way.
     comparison_time_local_ = base::test::time_helpers::TestDateToTime(
         base::test::time_helpers::kTimeZoneLocal);
     comparison_time_pdt_ = base::test::time_helpers::TestDateToTime(
         base::test::time_helpers::kTimeZonePacific);
-#else   // defined(OS_STARBOARD)
+#else   // defined(STARBOARD)
     // Use mktime to get a time_t, and turn it into a PRTime by converting
     // seconds to microseconds.  Use 15th Oct 2007 12:45:00 local.  This
     // must be a time guaranteed to be outside of a DST fallback hour in
diff --git a/src/build/build_config.h b/src/build/build_config.h
index 23e2665..c640843 100644
--- a/src/build/build_config.h
+++ b/src/build/build_config.h
@@ -5,7 +5,6 @@
 // This file adds defines about the platform we're currently building on.
 //  Operating System:
 //    OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX)
-//    OS_STARBOARD
 //  Compiler:
 //    COMPILER_MSVC / COMPILER_GCC
 //  Processor:
@@ -23,7 +22,7 @@
 
 // A set of macros to use for platform detection.
 #if defined(STARBOARD)
-#define OS_STARBOARD 1
+// noop
 #elif defined(__APPLE__)
 #define OS_MACOSX 1
 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
@@ -106,7 +105,7 @@
 //   http://msdn.microsoft.com/en-us/library/b0084kay.aspx
 //   http://www.agner.org/optimize/calling_conventions.pdf
 //   or with gcc, run: "echo | gcc -E -dM -"
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/configuration.h"
 #if SB_IS(32_BIT)
 # define ARCH_CPU_32_BITS 1
@@ -154,7 +153,7 @@
 #endif
 
 // Type detection for wchar_t.
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #  if SB_IS(WCHAR_T_UTF16)
 #    define WCHAR_T_IS_UTF16 1
 #  elif SB_IS(WCHAR_T_UTF32)
@@ -180,7 +179,7 @@
 #error Please add support for your compiler in build/build_config.h
 #endif
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #  if SB_IS(WCHAR_T_UNSIGNED)
 #    define WCHAR_T_IS_UNSIGNED 1
 #  elif SB_IS(WCHAR_T_SIGNED)
diff --git a/src/build/download_gold_plugin.py b/src/build/download_gold_plugin.py
deleted file mode 100755
index 11421e9..0000000
--- a/src/build/download_gold_plugin.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Script to download LLVM gold plugin from google storage."""
-
-import find_depot_tools
-import json
-import os
-import shutil
-import subprocess
-import sys
-import zipfile
-
-SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
-CHROME_SRC = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir))
-
-
-DEPOT_PATH = find_depot_tools.add_depot_tools_to_path()
-GSUTIL_PATH = os.path.join(DEPOT_PATH, 'gsutil.py')
-
-LLVM_BUILD_PATH = sys.argv[1] or os.path.join(CHROME_SRC, 'third_party',
-                                              'llvm-build', 'Release+Asserts')
-CLANG_UPDATE_PY = os.path.join(CHROME_SRC, 'tools', 'clang', 'scripts',
-                               'update.py')
-CLANG_REVISION = sys.argv[2] or os.popen(CLANG_UPDATE_PY +
-                                         ' --print-revision').read().rstrip()
-
-CLANG_BUCKET = 'gs://chromium-browser-clang/Linux_x64'
-
-def main():
-  targz_name = 'llvmgold-%s.tgz' % CLANG_REVISION
-  remote_path = '%s/%s' % (CLANG_BUCKET, targz_name)
-
-  os.chdir(LLVM_BUILD_PATH)
-
-  subprocess.check_call(['python', GSUTIL_PATH,
-                         'cp', remote_path, targz_name])
-  subprocess.check_call(['tar', 'xzf', targz_name])
-  os.remove(targz_name)
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/src/buildtools/LICENSE b/src/buildtools/LICENSE
new file mode 100644
index 0000000..972bb2e
--- /dev/null
+++ b/src/buildtools/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/buildtools/METADATA b/src/buildtools/METADATA
new file mode 100644
index 0000000..33b683b
--- /dev/null
+++ b/src/buildtools/METADATA
@@ -0,0 +1,20 @@
+name: "buildtools"
+description:
+  "Subtree at buildtools."
+
+third_party {
+  url {
+    type: LOCAL_SOURCE
+    value: "/buildtools_mirror"
+  }
+  url {
+    type: GIT
+    value: "https://chromium.googlesource.com/chromium/buildtools"
+  }
+  version: "5af0a3a8b89827a8634132080a39ab4b63dee489"
+  last_upgrade_date {
+    year: 2017
+    month: 8
+    day: 18
+  }
+}
diff --git a/src/buildtools/linux64/clang-format b/src/buildtools/linux64/clang-format
new file mode 100755
index 0000000..a79160c
--- /dev/null
+++ b/src/buildtools/linux64/clang-format
Binary files differ
diff --git a/src/buildtools/linux64/clang-format.sha1 b/src/buildtools/linux64/clang-format.sha1
new file mode 100644
index 0000000..dcf7df3
--- /dev/null
+++ b/src/buildtools/linux64/clang-format.sha1
@@ -0,0 +1 @@
+5349d1954e17f6ccafb6e6663b0f13cdb2bb33c8
\ No newline at end of file
diff --git a/src/buildtools/linux64/gn b/src/buildtools/linux64/gn
new file mode 100755
index 0000000..9485341
--- /dev/null
+++ b/src/buildtools/linux64/gn
Binary files differ
diff --git a/src/buildtools/linux64/gn.sha1 b/src/buildtools/linux64/gn.sha1
new file mode 100644
index 0000000..a7db55c
--- /dev/null
+++ b/src/buildtools/linux64/gn.sha1
@@ -0,0 +1 @@
+1984d9f627869e631a3e5e6b25032a202b805c6e
\ No newline at end of file
diff --git a/src/cobalt/CHANGELOG.md b/src/cobalt/CHANGELOG.md
index 644ecae..f8b8122 100644
--- a/src/cobalt/CHANGELOG.md
+++ b/src/cobalt/CHANGELOG.md
@@ -467,7 +467,7 @@
  - **Implemented Same Origin Policy and removed navigation whitelist**
 
    - Added Same Origin Policy (SOP) and Cross Origin Resource Sharing (CORS)
-     suport to Cobalt.  In particular, it is added to XHR, script elements,
+     support to Cobalt.  In particular, it is added to XHR, script elements,
      link elements, style elements, media elements and @font-face CSS rules.
    - Removed hardcoded YouTube navigation whitelist in favor of SOP and CSP.
 
diff --git a/src/cobalt/account/account_manager.h b/src/cobalt/account/account_manager.h
index 90a70b1..9f63bbc 100644
--- a/src/cobalt/account/account_manager.h
+++ b/src/cobalt/account/account_manager.h
@@ -23,7 +23,7 @@
 namespace cobalt {
 namespace account {
 
-// Glue for h5vcc to get properites for the current user.
+// Glue for h5vcc to get properties for the current user.
 // The AccountManager will be owned by BrowserModule.
 class AccountManager {
  public:
diff --git a/src/cobalt/audio/audio_context.h b/src/cobalt/audio/audio_context.h
index 536b2bd..5245af8 100644
--- a/src/cobalt/audio/audio_context.h
+++ b/src/cobalt/audio/audio_context.h
@@ -73,7 +73,7 @@
 
 // This represents a set of AudioNode objects and their connections. It allows
 // for arbitrary routing of signals to the AudioDestinationNode (what the user
-// ultimately hears). Nodes are created from the cotnext and are then connected
+// ultimately hears). Nodes are created from the context and are then connected
 // together. In most user cases, only a single AudioContext is used per
 // document.
 //   https://www.w3.org/TR/webaudio/#AudioContext-section
diff --git a/src/cobalt/audio/audio_file_reader_wav.cc b/src/cobalt/audio/audio_file_reader_wav.cc
index f92b8bd..6e75c56 100644
--- a/src/cobalt/audio/audio_file_reader_wav.cc
+++ b/src/cobalt/audio/audio_file_reader_wav.cc
@@ -127,7 +127,7 @@
         break;
       }
     } else {
-      DLOG(WARNING) << "Malformated audio chunk.";
+      DLOG(WARNING) << "Malformed audio chunk.";
       break;
     }
 
diff --git a/src/cobalt/audio/audio_helpers.h b/src/cobalt/audio/audio_helpers.h
index dc98086..7ed581e 100644
--- a/src/cobalt/audio/audio_helpers.h
+++ b/src/cobalt/audio/audio_helpers.h
@@ -17,7 +17,7 @@
 
 #include "cobalt/media/base/audio_bus.h"
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/audio_sink.h"
 #include "starboard/media.h"
 #endif
@@ -37,7 +37,7 @@
 
 const int kStandardOutputSampleRate = 48000;
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 // Get the size in bytes of an SbMediaAudioSampleType.
 inline size_t GetStarboardSampleTypeSize(SbMediaAudioSampleType sample_type) {
   switch (sample_type) {
@@ -68,7 +68,7 @@
 // an internal SampleType.  If we are not running on starboard or using the
 // starboard media pipeline, then the preferred sample type is always float32.
 inline SampleType GetPreferredOutputSampleType() {
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
   if (SbAudioSinkIsAudioSampleTypeSupported(kSbMediaAudioSampleTypeFloat32)) {
     return kSampleTypeFloat32;
   }
@@ -77,12 +77,12 @@
       << "At least one starboard audio sample type must be supported if using "
          "starboard media pipeline.";
   return kSampleTypeInt16;
-#else   // defined(OS_STARBOARD)
+#else   // defined(STARBOARD)
   return kSampleTypeFloat32;
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
 }
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 // The same as GetPreferredOutputSampleType, only as an SbMediaAudioSample
 // rather than an internal SampleType.
 inline SbMediaAudioSampleType GetPreferredOutputStarboardSampleType() {
diff --git a/src/cobalt/audio/audio_node.cc b/src/cobalt/audio/audio_node.cc
index ed2cc42..49ca8e6 100644
--- a/src/cobalt/audio/audio_node.cc
+++ b/src/cobalt/audio/audio_node.cc
@@ -88,7 +88,7 @@
     return;
   }
   // The output parameter is an index describing which output of the AudioNode
-  // from which to connect. If this paremeter is out-of-bound, an INDEX_SIZE_ERR
+  // from which to connect. If this parameter is out-of-bound, an INDEX_SIZE_ERR
   // exception MUST be thrown.
   if (output >= number_of_outputs()) {
     dom::DOMException::Raise(dom::DOMException::kIndexSizeErr, exception_state);
diff --git a/src/cobalt/base/application_state.h b/src/cobalt/base/application_state.h
index f1b889a..d536189 100644
--- a/src/cobalt/base/application_state.h
+++ b/src/cobalt/base/application_state.h
@@ -34,7 +34,7 @@
 
   // The state where the application is running on the background, but the
   // background tasks are still running, such as audio playback, or updating
-  // of recommandations. The application is expected to be able to move back
+  // of recommendations. The application is expected to be able to move back
   // into the Blurred state very quickly.
   kApplicationStateConcealed,
 
diff --git a/src/cobalt/base/c_val_test.cc b/src/cobalt/base/c_val_test.cc
index 0b0edb7..56477c0 100644
--- a/src/cobalt/base/c_val_test.cc
+++ b/src/cobalt/base/c_val_test.cc
@@ -505,7 +505,7 @@
   }
 
   // Make sure there's no interference from the previous hook which should
-  // be completely non-existant now
+  // be completely non-existent now
   {
     class TestHook : public base::CValManager::OnChangedHook {
      public:
diff --git a/src/cobalt/base/circular_buffer_shell.cc b/src/cobalt/base/circular_buffer_shell.cc
index ea93d8e..ece9817 100644
--- a/src/cobalt/base/circular_buffer_shell.cc
+++ b/src/cobalt/base/circular_buffer_shell.cc
@@ -11,7 +11,7 @@
 #include "base/logging.h"
 #include "build/build_config.h"
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/memory.h"
 #define malloc SbMemoryAllocate
 #define realloc SbMemoryReallocate
diff --git a/src/cobalt/base/circular_buffer_shell.h b/src/cobalt/base/circular_buffer_shell.h
index 5b1cb5f..add70ea 100644
--- a/src/cobalt/base/circular_buffer_shell.h
+++ b/src/cobalt/base/circular_buffer_shell.h
@@ -26,7 +26,7 @@
   void Clear();
 
   // Reads the requested amount of data into the given buffer, writing the
-  // number of bytes actually read into the bytes_read paramter. If there is
+  // number of bytes actually read into the bytes_read parameter. If there is
   // less data then requested, then the remaining data will be consumed.
   void Read(void* destination, size_t length, size_t* bytes_read);
 
diff --git a/src/cobalt/base/cobalt_paths.h b/src/cobalt/base/cobalt_paths.h
index e825626..fb4f28c 100644
--- a/src/cobalt/base/cobalt_paths.h
+++ b/src/cobalt/base/cobalt_paths.h
@@ -18,7 +18,7 @@
 namespace cobalt {
 namespace paths {
 
-// The following keys are used to retreive Cobalt-specific paths using
+// The following keys are used to retrieve Cobalt-specific paths using
 // base::PathService::Get().
 //
 // Example:
diff --git a/src/cobalt/base/fixed_size_lru_cache.h b/src/cobalt/base/fixed_size_lru_cache.h
index 5a4fde0..341c6c0 100644
--- a/src/cobalt/base/fixed_size_lru_cache.h
+++ b/src/cobalt/base/fixed_size_lru_cache.h
@@ -136,7 +136,7 @@
   // so that the starting_iterator now points to an empty value that can be
   // written to, and the value near the ending_iterator is overwritten.
   // The function does not call the destructor on any values, so it is advised
-  // that the destructor be called on the value that is to be ovewritten before
+  // that the destructor be called on the value that is to be overwritten before
   // this function is called.
   void ShiftValuesDown(iterator starting_iterator, iterator ending_iterator) {
     std::size_t distance = std::distance(starting_iterator, ending_iterator);
diff --git a/src/cobalt/base/polymorphic_equatable.h b/src/cobalt/base/polymorphic_equatable.h
index 2aca1a1..a05acfc 100644
--- a/src/cobalt/base/polymorphic_equatable.h
+++ b/src/cobalt/base/polymorphic_equatable.h
@@ -21,7 +21,7 @@
 namespace base {
 
 // Derive from this class from the base class of a class hierarchy in order to
-// provide your hierarchy with the functinoality to test for equivalence between
+// provide your hierarchy with the functionality to test for equivalence between
 // different instances without knowing what the type of each instance is.
 // You will also need to add the line
 //   DEFINE_POLYMORPHIC_EQUATABLE_TYPE(MyDerivedClass)
diff --git a/src/cobalt/base/token_test.cc b/src/cobalt/base/token_test.cc
index ec1035c..647dc34 100644
--- a/src/cobalt/base/token_test.cc
+++ b/src/cobalt/base/token_test.cc
@@ -47,7 +47,7 @@
   EXPECT_EQ(non_empty_1, non_empty_2);
 }
 
-TEST(TokenTest, CompareUnqual) {
+TEST(TokenTest, CompareUnequal) {
   std::string kTestString = "test";
 
   Token empty;
diff --git a/src/cobalt/base/wrap_main.h b/src/cobalt/base/wrap_main.h
index 958601f..7248992 100644
--- a/src/cobalt/base/wrap_main.h
+++ b/src/cobalt/base/wrap_main.h
@@ -27,7 +27,7 @@
 #include "base/run_loop.h"
 #include "build/build_config.h"
 #include "cobalt/base/init_cobalt.h"
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/event.h"
 #else
 typedef void SbEvent;
@@ -65,7 +65,7 @@
 }  // namespace wrap_main
 }  // namespace cobalt
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "cobalt/base/wrap_main_starboard.h"
 #else
 
@@ -128,6 +128,6 @@
 }  // namespace wrap_main
 }  // namespace cobalt
 
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
 
 #endif  // COBALT_BASE_WRAP_MAIN_H_
diff --git a/src/cobalt/bindings/IDLExtendedAttributes.txt b/src/cobalt/bindings/IDLExtendedAttributes.txt
index bd7bd59..ed7490c 100644
--- a/src/cobalt/bindings/IDLExtendedAttributes.txt
+++ b/src/cobalt/bindings/IDLExtendedAttributes.txt
@@ -1,4 +1,4 @@
-# This file desribes all Web IDL extended attributes that are supported by the
+# This file describes all Web IDL extended attributes that are supported by the
 # Cobalt bindings code generation pipeline. Using an extended attribute not
 # listed below will cause the build to fail.
 # Extended attributes include attributes listed in the Web IDL specification
diff --git a/src/cobalt/bindings/flatten_idls.py b/src/cobalt/bindings/flatten_idls.py
index a9f96e1..2d463a1 100644
--- a/src/cobalt/bindings/flatten_idls.py
+++ b/src/cobalt/bindings/flatten_idls.py
@@ -15,7 +15,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-
 """Flatten a set of IDLs.
 
 Scan the specified directories for IDL files, filter out any ignored IDLs, and
@@ -104,7 +103,7 @@
     return cls(lhs.name, operations, attributes, constants, constructors)
 
   def IsEmpty(self):
-    """Return True if this FlattendInterface has no properties."""
+    """Return True if this FlattenedInterface has no properties."""
     return not (self.operations or self.attributes or self.constants)
 
   @classmethod
@@ -139,12 +138,12 @@
   """Walk all directories under |dirname| for files with the .idl extension."""
 
   def MatchesIgnorePattern(idl_path):
-    return any((fnmatch.fnmatch(idl_path, pattern) for pattern in
-                ignore_patterns))
+    return any(
+        (fnmatch.fnmatch(idl_path, pattern) for pattern in ignore_patterns))
 
   for root, _, filenames in os.walk(dirname):
-    idl_paths = (os.path.join(root, file)
-                 for file in fnmatch.filter(filenames, '*.idl'))
+    idl_paths = (
+        os.path.join(root, file) for file in fnmatch.filter(filenames, '*.idl'))
     for idl_path in idl_paths:
       if not MatchesIgnorePattern(idl_path):
         yield idl_path
@@ -211,9 +210,11 @@
   # Convert the idl_definition.IdlInterface objects to FlattenedInterface
   # objects. Ignore interfaces that were on the right-hand-side of an implements
   # statement.
-  return [FlattenedInterface.FromIdlInterface(interface)
-          for name, interface in interfaces.items()
-          if name not in all_implemented_interfaces]
+  return [
+      FlattenedInterface.FromIdlInterface(interface)
+      for name, interface in interfaces.items()
+      if name not in all_implemented_interfaces
+  ]
 
 
 def main(argv):
@@ -228,11 +229,12 @@
       required=True,
       dest='directories',
       help='Directories to search (recursively) for .idl files.')
-  parser.add_argument('-i',
-                      '--ignore',
-                      action='append',
-                      default=[],
-                      help='Ignore IDLs whose path contains the argument.')
+  parser.add_argument(
+      '-i',
+      '--ignore',
+      action='append',
+      default=[],
+      help='Ignore IDLs whose path contains the argument.')
   parser.add_argument(
       '-o',
       '--output_path',
@@ -241,8 +243,8 @@
   parser.add_argument(
       '--blink_scripts_dir',
       required=True,
-      help=
-      'Specify the directory from which blink\'s scripts should be imported.')
+      help='Specify the directory from which blink\'s scripts should be imported.'
+  )
 
   options = parser.parse_args(argv)
 
diff --git a/src/cobalt/bindings/name_conversion.py b/src/cobalt/bindings/name_conversion.py
index 0b7f959..00673c8 100644
--- a/src/cobalt/bindings/name_conversion.py
+++ b/src/cobalt/bindings/name_conversion.py
@@ -21,14 +21,14 @@
 # (?<!^) ensures that we don't match the first character in the string
 #     as a word boundary
 # (?<![A-Z])(?=[A-Z]) will match an uppercase character that is
-#     preceeded by a non-uppercase character: FooBar -> Foo Bar
+#     preceded by a non-uppercase character: FooBar -> Foo Bar
 # (?=[A-Z][a-z]) will match an uppercase character that is followed by
 #     a lowercase character: FOOBar -> FOO Bar
 titlecase_word_delimiter_re = re.compile(
     '(?<!^)((?<![A-Z])(?=[A-Z])|(?=[A-Z][a-z]))')
 
 # Terms that should always be marked as words regardless of the case of
-# neigboring characters.
+# neighboring characters.
 word_list = ['html']
 
 # List of special tokens which are always be marked as words.
@@ -46,9 +46,8 @@
   cobalt_name = titlecase_word_delimiter_re.sub('_', class_name).lower()
   for term in word_list:
     replacement = [
-        token
-        for token in re.split('_?(%s)_?' % term, cobalt_name, re.IGNORECASE)
-        if token
+        token for token in re.split('_?(%s)_?' %
+                                    term, cobalt_name, re.IGNORECASE) if token
     ]
     cobalt_name = '_'.join(replacement)
   return cobalt_name
@@ -75,8 +74,8 @@
 
 
 def convert_to_cobalt_constant_name(constant_name):
-  return 'k' + ''.join((token.capitalize()
-                        for token in constant_name.split('_')))
+  return 'k' + ''.join(
+      (token.capitalize() for token in constant_name.split('_')))
 
 
 def convert_to_cobalt_enumeration_value(enum_type, enum_value):
diff --git a/src/cobalt/bindings/testing/numeric_type_bindings_test.cc b/src/cobalt/bindings/testing/numeric_type_bindings_test.cc
index 2233ec7..3906ebc 100644
--- a/src/cobalt/bindings/testing/numeric_type_bindings_test.cc
+++ b/src/cobalt/bindings/testing/numeric_type_bindings_test.cc
@@ -17,7 +17,6 @@
 #include "base/strings/stringprintf.h"
 #include "cobalt/bindings/testing/bindings_test_base.h"
 #include "cobalt/bindings/testing/numeric_types_test_interface.h"
-#include "starboard/double.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -51,7 +50,8 @@
 typedef ::testing::Types<ByteTypeTest, OctetTypeTest, ShortTypeTest,
                          UnsignedShortTypeTest, LongTypeTest,
                          UnsignedLongTypeTest, LongLongTypeTest,
-                         UnsignedLongLongTypeTest, DoubleTypeTest> NumericTypes;
+                         UnsignedLongLongTypeTest, DoubleTypeTest>
+    NumericTypes;
 
 typedef ::testing::Types<LongLongTypeTest, UnsignedLongLongTypeTest>
     LargeIntegerTypes;
@@ -60,13 +60,15 @@
 #else
 typedef ::testing::Types<ByteTypeTest, OctetTypeTest, ShortTypeTest,
                          UnsignedShortTypeTest, LongTypeTest,
-                         UnsignedLongTypeTest, DoubleTypeTest> NumericTypes;
+                         UnsignedLongTypeTest, DoubleTypeTest>
+    NumericTypes;
 #endif  // ENGINE_SUPPORTS_INT64
 // Not including long longs in IntegerTypes, due to different casting
 // behaviours.
 typedef ::testing::Types<ByteTypeTest, OctetTypeTest, ShortTypeTest,
                          UnsignedShortTypeTest, LongTypeTest,
-                         UnsignedLongTypeTest> IntegerTypes;
+                         UnsignedLongTypeTest>
+    IntegerTypes;
 
 typedef ::testing::Types<DoubleTypeTest, UnrestrictedDoubleTypeTest>
     FloatingPointTypes;
@@ -80,9 +82,9 @@
 #pragma warning(push)
 // On Windows isnan() returns an int.
 // warning C4800: 'int' : forcing value to bool 'true' or 'false'
-#pragma warning(disable:4800)
+#pragma warning(disable : 4800)
 #endif
-  return SbDoubleIsNan(number);
+  return std::isnan(number);
 #if defined(_MSC_VER)
 #pragma warning(pop)
 #endif
diff --git a/src/cobalt/black_box_tests/testdata/black_box_js_test_utils.js b/src/cobalt/black_box_tests/testdata/black_box_js_test_utils.js
index a68f498..4780ce7 100644
--- a/src/cobalt/black_box_tests/testdata/black_box_js_test_utils.js
+++ b/src/cobalt/black_box_tests/testdata/black_box_js_test_utils.js
@@ -1,5 +1,5 @@
 // This file provides JavaScript-side environment and test utility functions.
-// The foolowing constants and logics are used in communication with the python
+// The following constants and logics are used in communication with the python
 // tests. Anyone making changes here should also ensure corresponding changes
 // are made in black_box_cobalt_runner.py.
 
@@ -80,4 +80,4 @@
   let span_ele = document.createElement('span');
   span_ele.id = SETUP_DONE_MESSAGE;
   document.appendChild(span_ele);
-}
\ No newline at end of file
+}
diff --git a/src/cobalt/black_box_tests/tests/cancel_sync_loads_when_suspended.py b/src/cobalt/black_box_tests/tests/cancel_sync_loads_when_suspended.py
index def8cba..19c6879 100644
--- a/src/cobalt/black_box_tests/tests/cancel_sync_loads_when_suspended.py
+++ b/src/cobalt/black_box_tests/tests/cancel_sync_loads_when_suspended.py
@@ -11,7 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-"""Tests cancelation of synchronous loading of scripts on Suspend."""
+"""Tests cancellation of synchronous loading of scripts on Suspend."""
 
 # This test script works by splitting the work over 3 threads, so that they
 # can each make progress even if they come across blocking operations.
@@ -79,7 +79,7 @@
 
 
 class CancelSyncLoadsWhenSuspended(black_box_tests.BlackBoxTestCase):
-  """Tests cancelation of synchronous loading of scripts on Suspend."""
+  """Tests cancellation of synchronous loading of scripts on Suspend."""
 
   def _LoadPage(self, webdriver, url):
     """Instructs webdriver to navigate to url."""
diff --git a/src/cobalt/black_box_tests/tests/retry_async_script_loads_after_suspend.py b/src/cobalt/black_box_tests/tests/retry_async_script_loads_after_suspend.py
index 822b864..70ad4c0 100644
--- a/src/cobalt/black_box_tests/tests/retry_async_script_loads_after_suspend.py
+++ b/src/cobalt/black_box_tests/tests/retry_async_script_loads_after_suspend.py
@@ -90,7 +90,7 @@
 
 
 class RetryAsyncScriptLoadsAfterSuspend(black_box_tests.BlackBoxTestCase):
-  """Tests cancelation of synchronous loading of scripts on Suspend."""
+  """Tests cancellation of synchronous loading of scripts on Suspend."""
 
   def _LoadPage(self, webdriver, url):
     """Instructs webdriver to navigate to url."""
diff --git a/src/cobalt/browser/application.cc b/src/cobalt/browser/application.cc
index b9cb809..0b7e216 100644
--- a/src/cobalt/browser/application.cc
+++ b/src/cobalt/browser/application.cc
@@ -21,6 +21,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/command_line.h"
@@ -62,6 +63,7 @@
 #include "cobalt/browser/switches.h"
 #include "cobalt/browser/user_agent_string.h"
 #include "cobalt/configuration/configuration.h"
+#include "cobalt/extension/crash_handler.h"
 #include "cobalt/extension/installation_manager.h"
 #include "cobalt/loader/image/image_decoder.h"
 #include "cobalt/math/size.h"
@@ -75,6 +77,10 @@
 #include "starboard/system.h"
 #include "url/gurl.h"
 
+#if SB_IS(EVERGREEN)
+#include "cobalt/updater/utils.h"
+#endif
+
 using cobalt::cssom::ViewportSize;
 
 namespace cobalt {
@@ -155,8 +161,8 @@
 
 #if defined(ENABLE_WEBDRIVER)
 int GetWebDriverPort() {
-  // The default port on which the webdriver server should listen for incoming
-  // connections.
+// The default port on which the webdriver server should listen for incoming
+// connections.
 #if defined(SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT)
   const int kDefaultWebDriverPort = SB_OVERRIDE_DEFAULT_WEBDRIVER_PORT;
 #else
@@ -520,6 +526,56 @@
     "available trackers.";
 #endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
 
+#if SB_API_VERSION >= 11
+bool AddCrashHandlerAnnotations() {
+  auto crash_handler_extension =
+      SbSystemGetExtension(kCobaltExtensionCrashHandlerName);
+  if (!crash_handler_extension) {
+    LOG(INFO) << "No crash handler extension, not sending annotations.";
+    return false;
+  }
+
+  auto platform_info = cobalt::browser::GetUserAgentPlatformInfoFromSystem();
+  std::string user_agent =
+      cobalt::browser::CreateUserAgentString(platform_info);
+  std::string version = "";
+#if SB_IS(EVERGREEN)
+  version = cobalt::updater::GetCurrentEvergreenVersion();
+  std::string product = "Cobalt_Evergreen";
+#else
+  std::string product = "Cobalt";
+#endif
+  if (version.empty()) {
+    base::StringAppendF(&version, "%s.%s-%s",
+                        platform_info.cobalt_version.c_str(),
+                        platform_info.cobalt_build_version_number.c_str(),
+                        platform_info.build_configuration.c_str());
+  }
+
+  user_agent.push_back('\0');
+  product.push_back('\0');
+  version.push_back('\0');
+
+  CrashpadAnnotations crashpad_annotations;
+  SbMemorySet(&crashpad_annotations, sizeof(CrashpadAnnotations), 0);
+  SbStringCopy(crashpad_annotations.user_agent_string, user_agent.c_str(),
+               USER_AGENT_STRING_MAX_SIZE);
+  SbStringCopy(crashpad_annotations.product, product.c_str(),
+               CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
+  SbStringCopy(crashpad_annotations.version, version.c_str(),
+               CRASHPAD_ANNOTATION_DEFAULT_LENGTH);
+  bool result = static_cast<const CobaltExtensionCrashHandlerApi*>(
+                    crash_handler_extension)
+                    ->OverrideCrashpadAnnotations(&crashpad_annotations);
+  if (result) {
+    LOG(INFO) << "Sent annotations to crash handler";
+  } else {
+    LOG(ERROR) << "Could not send annotations to crash handler.";
+  }
+  return result;
+}
+#endif  // SB_API_VERSION >= 11
+
 }  // namespace
 
 // Helper stub to disable histogram tracking in StatisticsRecorder
@@ -683,8 +739,7 @@
   if (command_line->HasSwitch(
           browser::switches::kForceMigrationForStoragePartitioning) ||
       partition_key == default_key) {
-    storage_manager_options.savegame_options.fallback_to_default_id =
-        true;
+    storage_manager_options.savegame_options.fallback_to_default_id = true;
   }
 
   // User can specify an extra search path entry for files loaded via file://.
@@ -761,8 +816,7 @@
   security_flags.csp_header_policy = csp::kCSPRequired;
 #endif  // defined(COBALT_FORCE_CSP)
 
-  network_module_options.https_requirement =
-      security_flags.https_requirement;
+  network_module_options.https_requirement = security_flags.https_requirement;
   options.web_module_options.require_csp = security_flags.csp_header_policy;
   options.web_module_options.csp_enforcement_mode = dom::kCspEnforcementEnable;
 
@@ -776,8 +830,11 @@
 
   network_module_.reset(new network::NetworkModule(
       CreateUserAgentString(GetUserAgentPlatformInfoFromSystem()),
-      storage_manager_.get(), &event_dispatcher_,
-      network_module_options));
+      storage_manager_.get(), &event_dispatcher_, network_module_options));
+
+#if SB_API_VERSION >= 11
+  AddCrashHandlerAnnotations();
+#endif
 
 #if SB_IS(EVERGREEN)
   if (SbSystemGetExtension(kCobaltExtensionInstallationManagerName)) {
@@ -798,7 +855,7 @@
 
   app_status_ = (should_preload ? kConcealedAppStatus : kRunningAppStatus);
 
-  // Register event callbacks.
+// Register event callbacks.
 #if SB_API_VERSION >= 8
   window_size_change_event_callback_ = base::Bind(
       &Application::OnWindowSizeChangedEvent, base::Unretained(this));
@@ -893,15 +950,15 @@
 }
 
 Application::~Application() {
-  // explicitly reset here because the destruction of the object is complex
-  // and involves a thread join. If this were to hang the app then having
-  // the destruction at this point gives a real file-line number and a place
-  // for the debugger to land.
+// explicitly reset here because the destruction of the object is complex
+// and involves a thread join. If this were to hang the app then having
+// the destruction at this point gives a real file-line number and a place
+// for the debugger to land.
 #if defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
   memory_tracker_tool_.reset(NULL);
 #endif  // defined(ENABLE_DEBUGGER) && defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
 
-  // Unregister event callbacks.
+// Unregister event callbacks.
 #if SB_API_VERSION >= 8
   event_dispatcher_.RemoveEventCallback(base::WindowSizeChangedEvent::TypeId(),
                                         window_size_change_event_callback_);
diff --git a/src/cobalt/browser/application.h b/src/cobalt/browser/application.h
index 6f8ed3c..08fc7cc 100644
--- a/src/cobalt/browser/application.h
+++ b/src/cobalt/browser/application.h
@@ -112,7 +112,7 @@
   // Main components of the Cobalt browser application.
   std::unique_ptr<BrowserModule> browser_module_;
 
-  // Event callbacks.
+// Event callbacks.
 #if SB_API_VERSION >= 8
   base::EventCallback window_size_change_event_callback_;
 #endif  // SB_API_VERSION >= 8
@@ -221,7 +221,7 @@
   // Called when deep links are consumed.
   void OnDeepLinkConsumedCallback(const std::string& link);
 
-  // Dispach events for deep links.
+  // Dispatch events for deep links.
   void DispatchDeepLink(const char* link);
   void DispatchDeepLinkIfNotConsumed();
 
diff --git a/src/cobalt/browser/browser_bindings_gen.gyp b/src/cobalt/browser/browser_bindings_gen.gyp
index 37b0179..11d207d 100644
--- a/src/cobalt/browser/browser_bindings_gen.gyp
+++ b/src/cobalt/browser/browser_bindings_gen.gyp
@@ -132,6 +132,7 @@
         '../dom/on_error_event_listener.idl',
         '../dom/on_screen_keyboard.idl',
         '../dom/performance.idl',
+        '../dom/performance_entry.idl',
         '../dom/performance_timing.idl',
         '../dom/plugin_array.idl',
         '../dom/pointer_event.idl',
@@ -338,7 +339,7 @@
         '../dom/non_document_type_child_node.idl',
         '../dom/non_element_parent_node.idl',
         '../dom/parent_node.idl',
-        '../dom/performance__high_resolution_time.idl',
+        '../dom/performance_high_resolution_time.idl',
         '../dom/speech_synthesis_getter.idl',
         '../dom/url_mse.idl',
         '../dom/url_utils.idl',
diff --git a/src/cobalt/browser/browser_module.cc b/src/cobalt/browser/browser_module.cc
index 55e3102..d793cfe 100644
--- a/src/cobalt/browser/browser_module.cc
+++ b/src/cobalt/browser/browser_module.cc
@@ -158,7 +158,7 @@
 // by treating them as unsupported
 const char kDisableMediaCodecsCommand[] = "disable_media_codecs";
 const char kDisableMediaCodecsCommandShortHelp[] =
-    "Specify a semicolon-seperated list of disabled media codecs.";
+    "Specify a semicolon-separated list of disabled media codecs.";
 const char kDisableMediaCodecsCommandLongHelp[] =
     "Disabling Media Codecs will force the app to claim they are not "
     "supported. This "
@@ -585,7 +585,7 @@
     }
   }
 
-  // Create new WebModule.
+// Create new WebModule.
 #if !defined(COBALT_FORCE_CSP)
   options_.web_module_options.csp_insecure_allowed_token =
       dom::CspDelegateFactory::GetInsecureAllowedToken();
@@ -625,9 +625,9 @@
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kWaitForWebDebugger)) {
     int wait_for_generation =
-        SbStringAToI(base::CommandLine::ForCurrentProcess()
-                         ->GetSwitchValueASCII(switches::kWaitForWebDebugger)
-                         .c_str());
+        atoi(base::CommandLine::ForCurrentProcess()
+                 ->GetSwitchValueASCII(switches::kWaitForWebDebugger)
+                 .c_str());
     if (wait_for_generation < 1) wait_for_generation = 1;
     options.wait_for_web_debugger =
         (wait_for_generation == main_web_module_generation_);
@@ -1623,8 +1623,8 @@
   if (media_module_) {
 #if SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION || \
     SB_HAS(CONCEALED_STATE)
-    media_module_->UpdateSystemWindowAndResourceProvider(
-        system_window_.get(), GetResourceProvider());
+    media_module_->UpdateSystemWindowAndResourceProvider(system_window_.get(),
+                                                         GetResourceProvider());
 #else
     media_module_->Resume(GetResourceProvider());
 #endif  // SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION ||
@@ -1780,8 +1780,8 @@
     SB_HAS(CONCEALED_STATE)
     input_device_manager_.reset();
     system_window_.reset();
-    media_module_->UpdateSystemWindowAndResourceProvider(
-        NULL, GetResourceProvider());
+    media_module_->UpdateSystemWindowAndResourceProvider(NULL,
+                                                         GetResourceProvider());
 #endif  // SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION ||
         // SB_HAS(CONCEALED_STATE)
   }
@@ -1821,8 +1821,8 @@
 
 void BrowserModule::UnfreezeInternal() {
   TRACE_EVENT0("cobalt::browser", "BrowserModule::UnfreezeInternal()");
-  // Set the Stub resource provider to media module and to web module
-  // at Concealed state.
+// Set the Stub resource provider to media module and to web module
+// at Concealed state.
 #if SB_API_VERSION >= SB_ADD_CONCEALED_STATE_SUPPORT_VERSION || \
     SB_HAS(CONCEALED_STATE)
   media_module_->Resume(GetResourceProvider());
diff --git a/src/cobalt/browser/browser_module.h b/src/cobalt/browser/browser_module.h
index d49f817..6309e32 100644
--- a/src/cobalt/browser/browser_module.h
+++ b/src/cobalt/browser/browser_module.h
@@ -714,7 +714,7 @@
   base::Optional<int64_t> javascript_gc_threshold_in_bytes_;
 
   // Save the current window size before transitioning to Concealed state,
-  // and resuse this vaule to recreate the window.
+  // and reuse this value to recreate the window.
   math::Size window_size_;
 };
 
diff --git a/src/cobalt/browser/main.cc b/src/cobalt/browser/main.cc
index 1fbadc8..d844312 100644
--- a/src/cobalt/browser/main.cc
+++ b/src/cobalt/browser/main.cc
@@ -110,7 +110,7 @@
 
 }  // namespace
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 COBALT_WRAP_MAIN(PreloadApplication, StartApplication, HandleStarboardEvent,
                  StopApplication);
 #else
diff --git a/src/cobalt/browser/memory_settings/constrainer.h b/src/cobalt/browser/memory_settings/constrainer.h
index a19b2da..97d4e04 100644
--- a/src/cobalt/browser/memory_settings/constrainer.h
+++ b/src/cobalt/browser/memory_settings/constrainer.h
@@ -28,7 +28,7 @@
 namespace browser {
 namespace memory_settings {
 
-// Constrains the memory in the memmory_settings vector so that the target is
+// Constrains the memory in the memory_settings vector so that the target is
 // such that the sum of memory consumption is below max_cpu_memory and
 // max_gpu_memory.
 //
diff --git a/src/cobalt/browser/memory_settings/scaling_function.cc b/src/cobalt/browser/memory_settings/scaling_function.cc
index b71da34..a9d879f 100644
--- a/src/cobalt/browser/memory_settings/scaling_function.cc
+++ b/src/cobalt/browser/memory_settings/scaling_function.cc
@@ -36,7 +36,7 @@
     min_memory = std::min(min_memory, max_memory);
     const double min_factor =
         static_cast<double>(min_memory) / static_cast<double>(max_memory);
-    // From 95% -> 0%, the memory will stay the same. This effectivly
+    // From 95% -> 0%, the memory will stay the same. This effectively
     // clamps the minimum value.
     interp_table_.Add(0.0, min_factor);
 
diff --git a/src/cobalt/browser/memory_tracker/tool.cc b/src/cobalt/browser/memory_tracker/tool.cc
index d262e2f..0db436a 100644
--- a/src/cobalt/browser/memory_tracker/tool.cc
+++ b/src/cobalt/browser/memory_tracker/tool.cc
@@ -14,6 +14,7 @@
 
 #include "cobalt/browser/memory_tracker/tool.h"
 
+#include <cmath>
 #include <cstdlib>
 #include <map>
 #include <memory>
@@ -36,7 +37,6 @@
 #include "starboard/common/log.h"
 #include "starboard/configuration.h"
 #include "starboard/configuration_constants.h"
-#include "starboard/double.h"
 #include "starboard/file.h"
 
 namespace cobalt {
@@ -377,7 +377,7 @@
       double num_mins = 1.0;
       if (!tool_arg.empty()) {
         if (!base::StringToDouble(tool_arg, &num_mins) ||
-            SbDoubleIsNan(num_mins) || num_mins <= 0) {
+            std::isnan(num_mins) || num_mins <= 0) {
           num_mins = 1.0;
         }
       }
@@ -403,8 +403,8 @@
 
         // TotalSamplingTime(1) outputs 60,000 milliseconds, or 1 minute.
         static int ToMilliseconds(double mins) {
-          const double millseconds = mins * 60. * 1000.;
-          return static_cast<int>(millseconds);
+          const double milliseconds = mins * 60. * 1000.;
+          return static_cast<int>(milliseconds);
         }
       };
 
diff --git a/src/cobalt/browser/memory_tracker/tool/histogram_table_csv_base.h b/src/cobalt/browser/memory_tracker/tool/histogram_table_csv_base.h
index b6eab2d..3a96a34 100644
--- a/src/cobalt/browser/memory_tracker/tool/histogram_table_csv_base.h
+++ b/src/cobalt/browser/memory_tracker/tool/histogram_table_csv_base.h
@@ -43,14 +43,14 @@
 //  my_histogram.BeginRow(time_delta);
 //  my_histogram.AddRowValue("ColumnA", 0);
 //  my_histogram.AddRowValue("ColumnB", 0);
-//  my_histogram.FinilizeRow();
+//  my_histogram.FinalizeRow();
 //
 //  // Add second row.
 //  my_histogram.BeginRow(time_delta);
 //  my_histogram.AddRowValue("ColumnA", 1);
 //  my_histogram.AddRowValue("ColumnB", 2);
 //  my_histogram.AddRowValue("ColumnC", 1);  // Ok, ColumnC will be autofilled.
-//  my_histogram.FinilizeRow();
+//  my_histogram.FinalizeRow();
 //
 //  Print(my_histogram.ToString());
 template <typename ValueType>
diff --git a/src/cobalt/browser/memory_tracker/tool/log_writer_tool.h b/src/cobalt/browser/memory_tracker/tool/log_writer_tool.h
index 6c10ad8..dfd7b42 100644
--- a/src/cobalt/browser/memory_tracker/tool/log_writer_tool.h
+++ b/src/cobalt/browser/memory_tracker/tool/log_writer_tool.h
@@ -39,7 +39,7 @@
   LogWriterTool();
   virtual ~LogWriterTool();
 
-  // Interface AbstrctMemoryTrackerTool
+  // Interface AbstractMemoryTrackerTool
   std::string tool_name() const override;
   void Run(Params* params) override;
 
diff --git a/src/cobalt/browser/memory_tracker/tool/tool_impl_test.cc b/src/cobalt/browser/memory_tracker/tool/tool_impl_test.cc
index 7913948..96f44ee 100644
--- a/src/cobalt/browser/memory_tracker/tool/tool_impl_test.cc
+++ b/src/cobalt/browser/memory_tracker/tool/tool_impl_test.cc
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 #include "cobalt/browser/memory_tracker/tool/tool_impl.h"
-#include "build/build_config.h"  // defines OS_STARBOARD
+#include "build/build_config.h"
 
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/src/cobalt/browser/render_tree_combiner.h b/src/cobalt/browser/render_tree_combiner.h
index 2e5ee78..81bd106 100644
--- a/src/cobalt/browser/render_tree_combiner.h
+++ b/src/cobalt/browser/render_tree_combiner.h
@@ -33,7 +33,7 @@
   // Layer represents the render layer corresponding to the main web
   // module, the splash screen, or the debug console and are used to
   // create and submit a combined tree to the RendererModule's
-  // pipeline. Layers are combined in order of the |z_index| specifed
+  // pipeline. Layers are combined in order of the |z_index| specified
   // at the Layers' creation. The RenderTreeCombiner stores pointers
   // to Layers. The Layers are owned by the caller of
   // RenderTreeCombiner::CreateLayer.
diff --git a/src/cobalt/browser/url_handler.h b/src/cobalt/browser/url_handler.h
index 40db6a2..bd2cd73 100644
--- a/src/cobalt/browser/url_handler.h
+++ b/src/cobalt/browser/url_handler.h
@@ -28,7 +28,7 @@
 class URLHandler {
  public:
   // Type for a callback to potentially handle a URL before it is used to
-  // intialize a new WebModule. The callback should return true if it handled
+  // initialize a new WebModule. The callback should return true if it handled
   // the URL, false otherwise.
   typedef base::Callback<bool(const GURL& url)> URLHandlerCallback;
 
diff --git a/src/cobalt/browser/web_module.cc b/src/cobalt/browser/web_module.cc
index e948d99..e31dbb7 100644
--- a/src/cobalt/browser/web_module.cc
+++ b/src/cobalt/browser/web_module.cc
@@ -265,10 +265,10 @@
   void InjectCustomWindowAttributes(
       const Options::InjectedWindowAttributes& attributes);
 
-  // Called by |layout_mananger_| after it runs the animation frame callbacks.
+  // Called by |layout_manager_| after it runs the animation frame callbacks.
   void OnRanAnimationFrameCallbacks();
 
-  // Called by |layout_mananger_| when it produces a render tree. May modify
+  // Called by |layout_manager_| when it produces a render tree. May modify
   // the render tree (e.g. to add a debug overlay), then runs the callback
   // specified in the constructor, |render_tree_produced_callback_|.
   void OnRenderTreeProduced(const LayoutResults& layout_results);
@@ -1173,7 +1173,6 @@
   synchronous_loader_interrupt_.Reset();
   DCHECK(resource_provider);
 
-  // TODO: Investigate the loader_factory and resource_provider issues.
   loader_factory_->Resume(resource_provider);
   SetApplicationState(base::kApplicationStateConcealed);
 }
@@ -1185,11 +1184,11 @@
   SetResourceProvider(resource_provider);
 
   window_->document()->PurgeCachedResources();
+  PurgeResourceCaches(should_retain_remote_typeface_cache_on_freeze_);
 
   loader_factory_->UpdateResourceProvider(resource_provider_);
   layout_manager_->Resume();
 
-  PurgeResourceCaches(should_retain_remote_typeface_cache_on_freeze_);
   SetApplicationState(base::kApplicationStateBlurred);
 }
 
diff --git a/src/cobalt/browser/web_module.h b/src/cobalt/browser/web_module.h
index ca84be8..2828ccd 100644
--- a/src/cobalt/browser/web_module.h
+++ b/src/cobalt/browser/web_module.h
@@ -80,7 +80,7 @@
 // when it calls the on_render_tree_produced_ callback (provided upon
 // construction).
 // At creation, the WebModule starts a dedicated thread, on which a private
-// implementation object is construted that manages all internal components.
+// implementation object is constructed that manages all internal components.
 // All methods of the WebModule post tasks to the implementation object on that
 // thread, so all internal functions are executed synchronously with respect to
 // each other.
diff --git a/src/cobalt/build/all.gyp b/src/cobalt/build/all.gyp
index 5c2f484..c178c7e 100644
--- a/src/cobalt/build/all.gyp
+++ b/src/cobalt/build/all.gyp
@@ -89,6 +89,7 @@
         '<(DEPTH)/third_party/zlib/zlib.gyp:zip_unittests_deploy',
         '<(DEPTH)/net/net.gyp:net_unittests_deploy',
         '<(DEPTH)/sql/sql.gyp:sql_unittests_deploy',
+        '<(DEPTH)/starboard/client_porting/cwrappers/cwrappers_test.gyp:cwrappers_test_deploy',
         '<(DEPTH)/starboard/common/common_test.gyp:common_test_deploy',
         '<(DEPTH)/starboard/elf_loader/elf_loader.gyp:elf_loader_test_deploy',
         '<(DEPTH)/starboard/loader_app/loader_app.gyp:loader_app_tests_deploy',
@@ -109,6 +110,7 @@
         }],
         ['sb_evergreen==1', {
           'dependencies': [
+            '<(DEPTH)/cobalt/updater/one_app_only_sandbox.gyp:*',
             '<(DEPTH)/components/update_client/update_client.gyp:cobalt_slot_management_test_deploy',
             '<(DEPTH)/third_party/musl/musl.gyp:musl_unittests',
             '<(DEPTH)/starboard/loader_app/installation_manager.gyp:*',
diff --git a/src/cobalt/build/build.id b/src/cobalt/build/build.id
index 0d364a4..a1d19cb 100644
--- a/src/cobalt/build/build.id
+++ b/src/cobalt/build/build.id
@@ -1 +1 @@
-292047
\ No newline at end of file
+299983
\ No newline at end of file
diff --git a/src/cobalt/build/cobalt_configuration.gypi b/src/cobalt/build/cobalt_configuration.gypi
index 38e7cf2..805a744 100644
--- a/src/cobalt/build/cobalt_configuration.gypi
+++ b/src/cobalt/build/cobalt_configuration.gypi
@@ -212,9 +212,6 @@
     # Set to 1 to build with DIAL support.
     'in_app_dial%': 0,
 
-    # Set to 1 to enable a custom MediaSessionClient.
-    'custom_media_session_client%': 0,
-
     # Set to 1 to enable H5vccAccountManager.
     'enable_account_manager%': 0,
 
diff --git a/src/cobalt/build/cobalt_configuration.py b/src/cobalt/build/cobalt_configuration.py
index b178ed5..5592bda 100644
--- a/src/cobalt/build/cobalt_configuration.py
+++ b/src/cobalt/build/cobalt_configuration.py
@@ -46,9 +46,15 @@
     except (ValueError, TypeError):
       use_fastbuild = 0
 
+    try:
+      build_in_docker = int(os.environ.get('IS_DOCKER', 0))
+    except (ValueError, TypeError):
+      build_in_docker = 0
+
     variables = {
         # This is used to omit large debuginfo in files on CI environment
         'cobalt_fastbuild': use_fastbuild,
+        'cobalt_docker_build': build_in_docker,
 
         # This is here rather than cobalt_configuration.gypi so that it's
         # available for browser_bindings_gen.gyp.
@@ -152,6 +158,7 @@
         'graphics_system_test',
         'layout_test',
         'layout_tests',
+        'cwrappers_test',
         'loader_test',
         'math_test',
         'media_capture_test',
diff --git a/src/cobalt/build/config/base.gni b/src/cobalt/build/config/base.gni
index 415251b..83bb2ad 100644
--- a/src/cobalt/build/config/base.gni
+++ b/src/cobalt/build/config/base.gni
@@ -183,11 +183,6 @@
   enable_in_app_dial = false
 }
 
-# Set to true to enable a custom MediaSessionClient.
-if (!defined(enable_custom_media_session_client)) {
-  enable_custom_media_session_client = false
-}
-
 # Set to true to enable H5vccAccountManager.
 if (!defined(enable_account_manager)) {
   enable_account_manager = false
diff --git a/src/cobalt/build/gyp_cobalt.bat b/src/cobalt/build/gyp_cobalt.bat
index bc80bfe..33a6d5a 100644
--- a/src/cobalt/build/gyp_cobalt.bat
+++ b/src/cobalt/build/gyp_cobalt.bat
@@ -21,35 +21,7 @@
 :: commands.
 
 setlocal
-
 set SCRIPT_DIR=%~dp0
-
-:: Locate depot_tool by searching for the location of git.bat.
-for %%F in (git.bat) do set DEPOT_TOOLS_DIR=%%~dp$PATH:F
-
-if "%DEPOT_TOOLS_DIR%" EQU "" (
-  echo Can't locate depot_tools.
-  goto EOF
-)
-
-:: Search for the git directory in depot_tools.
-dir /B /A:D %DEPOT_TOOLS_DIR%git-*_bin >%SCRIPT_DIR%git_bin_path.txt 2>NUL
-set /P GIT_BIN_DIR=<%SCRIPT_DIR%git_bin_path.txt
-del %SCRIPT_DIR%git_bin_path.txt
-
-if "%GIT_BIN_DIR%" EQU "" (
-  echo Could not locate git binaries in depot_tools.
-  goto EOF
-)
-
-:: Full path to the git directory.
-set GIT_BIN_DIR=%DEPOT_TOOLS_DIR%%GIT_BIN_DIR%\bin\
-
-:: Put git from depot_tools in path
-set PATH=%PATH%;%GIT_BIN_DIR%
-
 set ARGS=%*
 
 python2 %SCRIPT_DIR%gyp_cobalt %ARGS%
-
-:EOF
diff --git a/src/cobalt/build/gyp_utils.py b/src/cobalt/build/gyp_utils.py
index 986d81c..fc61343 100644
--- a/src/cobalt/build/gyp_utils.py
+++ b/src/cobalt/build/gyp_utils.py
@@ -25,7 +25,7 @@
 import _env  # pylint: disable=unused-import
 from cobalt.tools import paths
 
-_REVINFO_KEY = 'cobalt_src'
+_SUBREPO_PATHS = ['starboard/keyboxes']
 _VERSION_SERVER_URL = 'https://carbon-airlock-95823.appspot.com/build_version/generate'  # pylint:disable=line-too-long
 _XSSI_PREFIX = ")]}'\n"
 
@@ -33,31 +33,48 @@
 BUILD_ID_PATH = os.path.join(paths.BUILD_ROOT, 'build.id')
 
 
+def CheckRevInfo(key, cwd=None):
+  cwd = cwd if cwd else '.'
+  git_prefix = ['git', '-C', cwd]
+  git_get_remote_args = git_prefix + ['config', '--get', 'remote.origin.url']
+  remote = subprocess.check_output(git_get_remote_args).strip()
+
+  git_get_revision_args = git_prefix + ['rev-parse', 'HEAD']
+  revision = subprocess.check_output(git_get_revision_args).strip()
+  return {key: '{}@{}'.format(remote, revision)}
+
+
 def GetRevinfo():
   """Get absolute state of all git repos."""
-
-  git_get_remote_args = ['config', '--get', 'remote.origin.url']
-  git_get_revision_args = ['rev-parse', 'HEAD']
-
   try:
-    cobalt_remote = subprocess.check_output(['git'] +
-                                            git_get_remote_args).strip()
-    cobalt_rev = subprocess.check_output(['git'] +
-                                         git_get_revision_args).strip()
-    return {_REVINFO_KEY: '{}@{}'.format(cobalt_remote, cobalt_rev)}
-  except subprocess.CalledProcessError:
-    logging.info(
-        'Failed to get revision information. Trying again in src/ directory...')
+    repo_root = subprocess.check_output(['git', 'rev-parse',
+                                         '--show-toplevel']).strip()
+  except subprocess.CalledProcessError as e:
+    logging.info('Could not get repo root. Trying again in src/')
     try:
-      cobalt_remote = subprocess.check_output(['git', '-C', 'src'] +
-                                              git_get_remote_args).strip()
-      cobalt_rev = subprocess.check_output(['git', '-C', 'src'] +
-                                           git_get_revision_args).strip()
-      return {_REVINFO_KEY: '{}@{}'.format(cobalt_remote, cobalt_rev)}
+      repo_root = subprocess.check_output(
+          ['git', '-C', 'src', 'rev-parse', '--show-toplevel']).strip()
     except subprocess.CalledProcessError as e:
       logging.warning('Failed to get revision information: %s', e)
       return {}
 
+  # First make sure we can add the cobalt_src repo.
+  try:
+    repos = CheckRevInfo('.', cwd=repo_root)
+  except subprocess.CalledProcessError as e:
+    logging.warning('Failed to get revision information: %s', e)
+    return {}
+
+  for rel_path in _SUBREPO_PATHS:
+    path = os.path.join(repo_root, rel_path)
+    try:
+      repos.update(CheckRevInfo(rel_path, cwd=path))
+    except subprocess.CalledProcessError as e:
+      logging.warning('Failed to get revision information for subrepo: %s', e)
+      continue
+
+  return repos
+
 
 def GetBuildNumber(version_server=_VERSION_SERVER_URL):
   """Send a request to the build version server for a build number."""
diff --git a/src/cobalt/build/sync_to_build_id.py b/src/cobalt/build/sync_to_build_id.py
index 389da8b..d873a00 100755
--- a/src/cobalt/build/sync_to_build_id.py
+++ b/src/cobalt/build/sync_to_build_id.py
@@ -13,6 +13,7 @@
 import json
 import os
 import platform
+import shutil
 import subprocess
 import sys
 import requests
@@ -22,22 +23,11 @@
 _BUILD_ID_QUERY_PARAMETER_NAME = "build_number"
 
 
-def _GetGClientRoot(repo_path):
-  """Finds the root of this gclient repo, or returns repo_path if failed."""
-  current_path = os.path.normpath(repo_path)
-  while not os.access(os.path.join(current_path, ".gclient"), os.R_OK):
-    next_path = os.path.dirname(current_path)
-    if next_path == current_path:
-      return repo_path
-    current_path = next_path
-  return current_path
-
-
 class SubprocessFailedException(Exception):
   """Exception for non-zero subprocess exits."""
 
   def __init__(self, command):
-    super(SubprocessFailedException, self).__init__()
+    super(SubprocessFailedException, self).__init__()  # pylint: disable=super-with-arguments
     self.command = command
 
   def __str__(self):
@@ -87,12 +77,15 @@
   arg_parser = argparse.ArgumentParser(
       description="Syncs to a given Cobalt build id")
   arg_parser.add_argument("buildid", nargs=1)
+  arg_parser.add_argument(
+      "--force",
+      default=False,
+      action="store_true",
+      help="Deletes directories that don't match the requested format.")
   args = arg_parser.parse_args()
   r = requests.get(
       _BUILD_ID_QUERY_URL,
-      params={
-          _BUILD_ID_QUERY_PARAMETER_NAME: args.buildid[0]
-      })
+      params={_BUILD_ID_QUERY_PARAMETER_NAME: args.buildid[0]})
   if not r.ok:
     print(
         "HTTP request failed\n{0} {1}\n{2}".format(r.status_code, r.reason,
@@ -102,30 +95,43 @@
   # The response starts with a security-related close expression line
   outer_json = json.loads(r.text.splitlines()[1])
   hashes = json.loads(outer_json["deps"])
-  gclient_root = _GetGClientRoot(os.getcwd())
+  git_root = os.getcwd()
 
   for relpath, rep_hash in hashes.iteritems():
-    path = os.path.join(gclient_root, relpath)
+    path = os.path.normpath(os.path.join(git_root, relpath))
     if not os.path.exists(path):
       # No warning in this case, we will attempt to clone the repository in
       # the next pass through the repos.
       continue
     is_dirty = (
         bool(
+            _RunGitCommandReturnExitCode(["diff", "--no-ext-diff", "--quiet"],
+                                         cwd=path,
+                                         stderr=dev_null)[0]) or
+        bool(
             _RunGitCommandReturnExitCode(
-                ["diff", "--no-ext-diff", "--quiet"], cwd=path,
-                stderr=dev_null)[0]) or bool(
-                    _RunGitCommandReturnExitCode(
-                        ["diff", "--no-ext-diff", "--quiet", "--cached"],
-                        cwd=path,
-                        stderr=dev_null)[0]))
+                ["diff", "--no-ext-diff", "--quiet", "--cached"],
+                cwd=path,
+                stderr=dev_null)[0]))
 
     if is_dirty:
       print("{0} is dirty, please resolve".format(relpath))
       return 1
 
+    (requested_repo, _) = rep_hash.split("@")
+    remote_url = _RunGitCommand(["config", "--get", "remote.origin.url"],
+                                cwd=path)[0] + ".git"
+    if remote_url != requested_repo:
+      if args.force:
+        shutil.rmtree(path)
+      else:
+        print(("{0} exists but does not point to the requested repo for that "
+               "path, {1}. Either replace that directory manually or run this "
+               "script with --force.").format(path, requested_repo))
+        return 1
+
   for relpath, rep_hash in hashes.iteritems():
-    path = os.path.join(gclient_root, relpath)
+    path = os.path.normpath(os.path.join(git_root, relpath))
 
     # repo_hash has a repo path prefix like this:
     # 'https://chromium.googlesource.com/chromium/llvm-project/libcxx.git
@@ -149,9 +155,9 @@
       continue
     symbolic_ref = None
     try:
-      symbolic_ref = _RunGitCommand(
-          ["symbolic-ref", "--short", "-q", "HEAD"], cwd=path,
-          stderr=dev_null)[0]
+      symbolic_ref = _RunGitCommand(["symbolic-ref", "--short", "-q", "HEAD"],
+                                    cwd=path,
+                                    stderr=dev_null)[0]
     except SubprocessFailedException:
       pass
 
diff --git a/src/cobalt/content/fonts/config/android/fonts.xml b/src/cobalt/content/fonts/config/android/fonts.xml
index a39f238..3305769 100644
--- a/src/cobalt/content/fonts/config/android/fonts.xml
+++ b/src/cobalt/content/fonts/config/android/fonts.xml
@@ -516,4 +516,29 @@
     <family>
         <font weight="400" style="normal">NotoSansPhagsPa-Regular.ttf</font>
     </family>
+
+
+    <!--
+        Include font files on android version R under /system/fonts directory.
+        The program will find the first font file that contains the glyph for the character,
+        when no font file has the glyph, it will show broken string, to avoid this, include fonts
+        files on the android OS.
+    -->
+    <family>
+            <font weight="400" style="normal">NotoSansAdlam-VF.ttf</font>
+            <font weight="700" style="normal">NotoSansAdlam-VF.ttf</font>
+    </family>
+    <family>
+            <font weight="400" style="normal">NotoSansGeorgian-VF.ttf</font>
+            <font weight="700" style="normal">NotoSansGeorgian-VF.ttf</font>
+    </family>
+    <family>
+            <font weight="400" style="normal">NotoSansOsage-Regular.ttf</font>
+    </family>
+    <family>
+            <font weight="400" style="normal">RobotoCondensed-Medium.ttf</font>
+    </family>
+    <family>
+            <font weight="400" style="normal">RobotoCondensed-MediumItalic.ttf</font>
+    </family>
 </familyset>
diff --git a/src/cobalt/content/licenses/platform/android/licenses_cobalt.txt b/src/cobalt/content/licenses/platform/android/licenses_cobalt.txt
index e431145..ef96d48 100644
--- a/src/cobalt/content/licenses/platform/android/licenses_cobalt.txt
+++ b/src/cobalt/content/licenses/platform/android/licenses_cobalt.txt
@@ -850,205 +850,6 @@
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-  xdg_mime
-
-
-  Licensed under the Academic Free License version 2.0 (below)
-  Or under the following terms:
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the
-  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-  Boston, MA 02111-1307, USA.
-
-
-  --------------------------------------------------------------------------------
-  Academic Free License v. 2.0
-  --------------------------------------------------------------------------------
-
-  This Academic Free License (the "License") applies to any original work of
-  authorship (the "Original Work") whose owner (the "Licensor") has placed the
-  following notice immediately following the copyright notice for the Original
-  Work:
-
-  Licensed under the Academic Free License version 2.0
-  1) Grant of Copyright License. Licensor hereby grants You a world-wide,
-  royalty-free, non-exclusive, perpetual, sublicenseable license to do the
-  following:
-
-  a) to reproduce the Original Work in copies;
-  b) to prepare derivative works ("Derivative Works") based upon the Original
-     Work;
-  c) to distribute copies of the Original Work and Derivative Works to the
-     public;
-  d) to perform the Original Work publicly; and
-  e) to display the Original Work publicly.
-
-  2) Grant of Patent License. Licensor hereby grants You a world-wide,
-  royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
-  claims owned or controlled by the Licensor that are embodied in the Original
-  Work as furnished by the Licensor, to make, use, sell and offer for sale the
-  Original Work and Derivative Works.
-
-  3) Grant of Source Code License. The term "Source Code" means the preferred
-  form of the Original Work for making modifications to it and all available
-  documentation describing how to modify the Original Work. Licensor hereby
-  agrees to provide a machine-readable copy of the Source Code of the Original
-  Work along with each copy of the Original Work that Licensor distributes.
-  Licensor reserves the right to satisfy this obligation by placing a
-  machine-readable copy of the Source Code in an information repository
-  reasonably calculated to permit inexpensive and convenient access by You for as
-  long as Licensor continues to distribute the Original Work, and by publishing
-  the address of that information repository in a notice immediately following
-  the copyright notice that applies to the Original Work.
-
-  4) Exclusions From License Grant. Neither the names of Licensor, nor the names
-  of any contributors to the Original Work, nor any of their trademarks or
-  service marks, may be used to endorse or promote products derived from this
-  Original Work without express prior written permission of the Licensor. Nothing
-  in this License shall be deemed to grant any rights to trademarks, copyrights,
-  patents, trade secrets or any other intellectual property of Licensor except as
-  expressly stated herein. No patent license is granted to make, use, sell or
-  offer to sell embodiments of any patent claims other than the licensed claims
-  defined in Section 2. No right is granted to the trademarks of Licensor even if
-  such marks are included in the Original Work. Nothing in this License shall be
-  interpreted to prohibit Licensor from licensing under different terms from this
-  License any Original Work that Licensor otherwise would have a right to
-  license.
-
-  5) This section intentionally omitted.
-
-  6) Attribution Rights. You must retain, in the Source Code of any Derivative
-  Works that You create, all copyright, patent or trademark notices from the
-  Source Code of the Original Work, as well as any notices of licensing and any
-  descriptive text identified therein as an "Attribution Notice." You must cause
-  the Source Code for any Derivative Works that You create to carry a prominent
-  Attribution Notice reasonably calculated to inform recipients that You have
-  modified the Original Work.
-
-  7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
-  the copyright in and to the Original Work and the patent rights granted herein
-  by Licensor are owned by the Licensor or are sublicensed to You under the terms
-  of this License with the permission of the contributor(s) of those copyrights
-  and patent rights. Except as expressly stated in the immediately proceeding
-  sentence, the Original Work is provided under this License on an "AS IS" BASIS
-  and WITHOUT WARRANTY, either express or implied, including, without limitation,
-  the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
-  This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
-  license to Original Work is granted hereunder except under this disclaimer.
-
-  8) Limitation of Liability. Under no circumstances and under no legal theory,
-  whether in tort (including negligence), contract, or otherwise, shall the
-  Licensor be liable to any person for any direct, indirect, special, incidental,
-  or consequential damages of any character arising as a result of this License
-  or the use of the Original Work including, without limitation, damages for loss
-  of goodwill, work stoppage, computer failure or malfunction, or any and all
-  other commercial damages or losses. This limitation of liability shall not
-  apply to liability for death or personal injury resulting from Licensor's
-  negligence to the extent applicable law prohibits such limitation. Some
-  jurisdictions do not allow the exclusion or limitation of incidental or
-  consequential damages, so this exclusion and limitation may not apply to You.
-
-  9) Acceptance and Termination. If You distribute copies of the Original Work or
-  a Derivative Work, You must make a reasonable effort under the circumstances to
-  obtain the express assent of recipients to the terms of this License. Nothing
-  else but this License (or another written agreement between Licensor and You)
-  grants You permission to create Derivative Works based upon the Original Work
-  or to exercise any of the rights granted in Section 1 herein, and any attempt
-  to do so except under the terms of this License (or another written agreement
-  between Licensor and You) is expressly prohibited by U.S. copyright law, the
-  equivalent laws of other countries, and by international treaty. Therefore, by
-  exercising any of the rights granted to You in Section 1 herein, You indicate
-  Your acceptance of this License and all of its terms and conditions.
-
-  10) Termination for Patent Action. This License shall terminate automatically
-  and You may no longer exercise any of the rights granted to You by this License
-  as of the date You commence an action, including a cross-claim or counterclaim,
-  for patent infringement (i) against Licensor with respect to a patent
-  applicable to software or (ii) against any entity with respect to a patent
-  applicable to the Original Work (but excluding combinations of the Original
-  Work with other software or hardware).
-
-  11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
-  License may be brought only in the courts of a jurisdiction wherein the
-  Licensor resides or in which Licensor conducts its primary business, and under
-  the laws of that jurisdiction excluding its conflict-of-law provisions. The
-  application of the United Nations Convention on Contracts for the International
-  Sale of Goods is expressly excluded. Any use of the Original Work outside the
-  scope of this License or after its termination shall be subject to the
-  requirements and penalties of the U.S. Copyright Act, 17 U.S.C. 101 et seq.,
-  the equivalent laws of other countries, and international treaty. This section
-  shall survive the termination of this License.
-
-  12) Attorneys Fees. In any action to enforce the terms of this License or
-  seeking damages relating thereto, the prevailing party shall be entitled to
-  recover its costs and expenses, including, without limitation, reasonable
-  attorneys' fees and costs incurred in connection with such action, including
-  any appeal of such action. This section shall survive the termination of this
-  License.
-
-  13) Miscellaneous. This License represents the complete agreement concerning
-  the subject matter hereof. If any provision of this License is held to be
-  unenforceable, such provision shall be reformed only to the extent necessary to
-  make it enforceable.
-
-  14) Definition of "You" in This License. "You" throughout this License, whether
-  in upper or lower case, means an individual or a legal entity exercising rights
-  under, and complying with all of the terms of, this License. For legal
-  entities, "You" includes any entity that controls, is controlled by, or is
-  under common control with you. For purposes of this definition, "control" means
-  (i) the power, direct or indirect, to cause the direction or management of such
-  entity, whether by contract or otherwise, or (ii) ownership of fifty percent
-  (50%) or more of the outstanding shares, or (iii) beneficial ownership of such
-  entity.
-
-  15) Right to Use. You may use the Original Work in all ways not otherwise
-  restricted or conditioned by this License or by law, and Licensor promises not
-  to interfere with or be responsible for such uses by You.
-
-  This license is Copyright (C) 2003 Lawrence E. Rosen. All rights reserved.
-  Permission is hereby granted to copy and distribute this license without
-  modification. This license may not be modified without the express written
-  permission of its copyright owner.
-
-
-  xdg_user_dirs
-
-
-  Copyright (c) 2007 Red Hat, inc
-
-  Permission is hereby granted, free of charge, to any person
-  obtaining a copy of this software and associated documentation files
-  (the "Software"), to deal in the Software without restriction,
-  including without limitation the rights to use, copy, modify, merge,
-  publish, distribute, sublicense, and/or sell copies of the Software,
-  and to permit persons to whom the Software is furnished to do so,
-  subject to the following conditions: 
-
-  The above copyright notice and this permission notice shall be
-  included in all copies or substantial portions of the Software. 
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-  SOFTWARE.
-
-
   uri_template
 
 
diff --git a/src/cobalt/content/licenses/platform/default/licenses_cobalt.txt b/src/cobalt/content/licenses/platform/default/licenses_cobalt.txt
index 757106b..5b4bc55 100644
--- a/src/cobalt/content/licenses/platform/default/licenses_cobalt.txt
+++ b/src/cobalt/content/licenses/platform/default/licenses_cobalt.txt
@@ -853,25 +853,6 @@
   xdg_mime
 
 
-  Licensed under the Academic Free License version 2.0 (below)
-  Or under the following terms:
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the
-  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-  Boston, MA 02111-1307, USA.
-
-
   --------------------------------------------------------------------------------
   Academic Free License v. 2.0
   --------------------------------------------------------------------------------
diff --git a/src/cobalt/css_parser/animation_shorthand_property_parse_structures.cc b/src/cobalt/css_parser/animation_shorthand_property_parse_structures.cc
index 15d9be9..093a420 100644
--- a/src/cobalt/css_parser/animation_shorthand_property_parse_structures.cc
+++ b/src/cobalt/css_parser/animation_shorthand_property_parse_structures.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-// While the inital values for animation_duration, animation_timing_function
+// While the initial values for animation_duration, animation_timing_function
 // and animation_delay are well defined, they are lists of single objects,
 // and right here what we really need are those single objects.  These wrapper
 // functions extract the single element out of the initial list values for
diff --git a/src/cobalt/css_parser/css_parser.gyp b/src/cobalt/css_parser/css_parser.gyp
index aa4ae4a..11b8c0a 100644
--- a/src/cobalt/css_parser/css_parser.gyp
+++ b/src/cobalt/css_parser/css_parser.gyp
@@ -19,7 +19,7 @@
     # Define the platform specific Bison binary.
     'conditions': [
       ['host_os=="win"', {
-        'bison_exe': '<(DEPTH)/third_party/winflexbison/bin/Release/win_bison',
+        'bison_exe': 'win_bison',
       }, {
         'bison_exe': 'bison',
       }],
diff --git a/src/cobalt/css_parser/grammar.h b/src/cobalt/css_parser/grammar.h
index 251b2b4..faf3adf 100644
--- a/src/cobalt/css_parser/grammar.h
+++ b/src/cobalt/css_parser/grammar.h
@@ -26,7 +26,7 @@
 //     the same way as headers that comply with style guide;
 //
 //   - files generated by Bison should be included inside our namespace
-//     to avoid a polution of a global namespace;
+//     to avoid a pollution of a global namespace;
 //
 //   - as a corollary to the previous problem, header files that contain
 //     namespaces cannot be included from grammar (.y) as this will cause double
@@ -105,7 +105,7 @@
 #define YYLTYPE_IS_DECLARED 1
 #define YYLTYPE_IS_TRIVIAL 0
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/memory.h"
 #define YYFREE SbMemoryDeallocate
 #define YYMALLOC SbMemoryAllocate
diff --git a/src/cobalt/css_parser/parser.cc b/src/cobalt/css_parser/parser.cc
index 78c5ce3..f0903f4 100644
--- a/src/cobalt/css_parser/parser.cc
+++ b/src/cobalt/css_parser/parser.cc
@@ -97,12 +97,7 @@
 
 uint32_t ParseHexToken(const TrivialStringPiece& string_piece) {
   char* value_end(const_cast<char*>(string_piece.end));
-#if defined(OS_STARBOARD)
-  uint64 long_integer =
-      SbStringParseUnsignedInteger(string_piece.begin, &value_end, 16);
-#else
   uint64 long_integer = strtoul(string_piece.begin, &value_end, 16);
-#endif
   DCHECK_LE(long_integer, std::numeric_limits<uint32_t>::max());
   DCHECK_EQ(value_end, string_piece.end);
   return static_cast<uint32_t>(long_integer);
diff --git a/src/cobalt/css_parser/parser_test.cc b/src/cobalt/css_parser/parser_test.cc
index d510f2c..d57b564 100644
--- a/src/cobalt/css_parser/parser_test.cc
+++ b/src/cobalt/css_parser/parser_test.cc
@@ -8031,7 +8031,7 @@
             animation_direction->value()[1]);
 }
 
-TEST_F(ParserTest, ParsesAnimationDirectionWithInvaildValue) {
+TEST_F(ParserTest, ParsesAnimationDirectionWithInvalidValue) {
   EXPECT_CALL(parser_observer_,
               OnError("[object ParserTest]:1:22: error: unsupported property "
                       "value for animation-direction"));
diff --git a/src/cobalt/css_parser/scanner.cc b/src/cobalt/css_parser/scanner.cc
index f9b3010..132dbcb 100644
--- a/src/cobalt/css_parser/scanner.cc
+++ b/src/cobalt/css_parser/scanner.cc
@@ -14,9 +14,7 @@
 
 #include "cobalt/css_parser/scanner.h"
 
-#if defined(OS_STARBOARD)
-#include "starboard/client_porting/poem/stdlib_poem.h"
-#endif
+#include "starboard/client_porting/cwrappers/pow_wrapper.h"
 
 #include <limits>
 
@@ -383,7 +381,7 @@
       if ((first_input_iterator == ')' && brace_stack.top() == '(') ||
           (first_input_iterator == '}' && brace_stack.top() == '{') ||
           (first_input_iterator == ']' && brace_stack.top() == '[')) {
-        // Pop the open brace from stack when encourtering a match.
+        // Pop the open brace from stack when encountering a match.
         brace_stack.pop();
 
         continue;
@@ -432,9 +430,10 @@
     char first_character(*input_iterator_);
     HandleBraceIfExists(first_character);
     CharacterType character_type(
-        first_character >= 0 ? kTypesOfAsciiCharacters
-                                   [static_cast<unsigned char>(first_character)]
-                             : kIdentifierStartCharacter);
+        first_character >= 0
+            ? kTypesOfAsciiCharacters[static_cast<unsigned char>(
+                  first_character)]
+            : kIdentifierStartCharacter);
     switch (character_type) {
       case kCaselessUCharacter:
         return ScanFromCaselessU(token_value);
@@ -1069,8 +1068,7 @@
 Token Scanner::ScanFromLess() {
   ++input_iterator_;
 
-  if (input_iterator_[0] == '!' &&
-      input_iterator_[1] == '-' &&
+  if (input_iterator_[0] == '!' && input_iterator_[1] == '-' &&
       input_iterator_[2] == '-') {
     input_iterator_ += 3;
     return kSgmlCommentDelimiterToken;
@@ -3431,7 +3429,7 @@
         }
       } else if (length == 12) {
         // Checking the last character first could further reduce
-        // the possibile cases.
+        // the possible cases.
         if (IsAsciiAlphaCaselessEqual(name.begin[11], 'e') &&
             IsEqualToCssIdentifier(name.begin + 2, "eft-middl")) {
           *at_token = kLeftMiddleToken;
@@ -3479,7 +3477,7 @@
         }
       } else if (length == 13) {
         // Checking the last character first could further reduce
-        // the possibile cases.
+        // the possible cases.
         if (IsAsciiAlphaCaselessEqual(name.begin[12], 'e') &&
             IsEqualToCssIdentifier(name.begin + 2, "ight-middl")) {
           *at_token = kRightMiddleToken;
diff --git a/src/cobalt/css_parser/transition_shorthand_property_parse_structures.cc b/src/cobalt/css_parser/transition_shorthand_property_parse_structures.cc
index daaf162..95aa20e 100644
--- a/src/cobalt/css_parser/transition_shorthand_property_parse_structures.cc
+++ b/src/cobalt/css_parser/transition_shorthand_property_parse_structures.cc
@@ -21,7 +21,7 @@
 
 namespace {
 
-// While the inital values for transition_duration, transition_timing_function
+// While the initial values for transition_duration, transition_timing_function
 // and transition_delay are well defined, they are lists of single objects,
 // and right here what we really need are those single objects.  These wrapper
 // functions extract the single element out of the initial list values for
diff --git a/src/cobalt/cssom/calc_value.h b/src/cobalt/cssom/calc_value.h
index 1e8a546..da8af5d 100644
--- a/src/cobalt/cssom/calc_value.h
+++ b/src/cobalt/cssom/calc_value.h
@@ -27,7 +27,7 @@
 namespace cobalt {
 namespace cssom {
 
-// Represets the result of the mathematical calculation it contains, using
+// Represents the result of the mathematical calculation it contains, using
 // standard operator precedence rules.
 // TODO: Implement the complete version of CalcValue. The
 // current CalcValue is just a simplified implementation.
diff --git a/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.cc b/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.cc
index b29ec28..5d0356b 100644
--- a/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.cc
+++ b/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.cc
@@ -44,7 +44,9 @@
     const math::SizeF& used_size,
     const scoped_refptr<ui_navigation::NavItem>& used_ui_nav_focus) const {
   ui_navigation::NativeMatrix4 matrix;
-  if (used_ui_nav_focus && used_ui_nav_focus->GetFocusTransform(&matrix)) {
+  if ((used_ui_nav_focus && used_ui_nav_focus->GetFocusTransform(&matrix)) ||
+      (!used_ui_nav_focus &&
+       ui_navigation::NavItem::GetGlobalFocusTransform(&matrix))) {
     return math::InterpolateMatrices(
         math::Matrix3F::FromValues(
             // Since the UI is only rendered in 2D, ignore any scaling or
diff --git a/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.h b/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.h
index ed31665..4e33d8d 100644
--- a/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.h
+++ b/src/cobalt/cssom/cobalt_ui_nav_focus_transform_function.h
@@ -31,7 +31,9 @@
 // queries the closest hybrid navigation focus item (i.e. this element or
 // an ancestor element with tabindex set appropriately). If that navigation
 // item does not have focus, or the system does not provide interaction
-// animations, then this transform function will evaluate to identity.
+// animations, then this transform function will evaluate to identity. If
+// no ancestor is a hybrid navigation focus item, then the currently-focused
+// item (which may be in a different subtree) is queried.
 class CobaltUiNavFocusTransformFunction : public TransformFunction {
  public:
   // |progress_to_identity| is used to support transitions to or from CSS
diff --git a/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.cc b/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.cc
index cf14411..d2c5b25 100644
--- a/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.cc
+++ b/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.cc
@@ -39,15 +39,16 @@
     const scoped_refptr<ui_navigation::NavItem>& used_ui_nav_focus) const {
   float scale = progress_to_identity_;
   float focus_x = 0.0f, focus_y = 0.0f;
-  if (used_ui_nav_focus &&
-      used_ui_nav_focus->GetFocusVector(&focus_x, &focus_y)) {
+  if ((used_ui_nav_focus &&
+       used_ui_nav_focus->GetFocusVector(&focus_x, &focus_y)) ||
+      (!used_ui_nav_focus &&
+       ui_navigation::NavItem::GetGlobalFocusVector(&focus_x, &focus_y))) {
     // Translation must be mapped from [-1,+1] to [-50%,+50%].
     focus_x *= (1.0f - progress_to_identity_) * 0.5f * used_size.width();
     focus_y *= (1.0f - progress_to_identity_) * 0.5f * used_size.height();
     scale = 1.0f;
   }
-  return math::Matrix3F::FromValues(scale, 0.0f, focus_x,
-                                    0.0f, scale, focus_y,
+  return math::Matrix3F::FromValues(scale, 0.0f, focus_x, 0.0f, scale, focus_y,
                                     0.0f, 0.0f, 1.0f);
 }
 
diff --git a/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.h b/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.h
index 81e3483..d23896b 100644
--- a/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.h
+++ b/src/cobalt/cssom/cobalt_ui_nav_spotlight_transform_function.h
@@ -35,7 +35,9 @@
 // not have focus, or the platform does not provide focus movement
 // information, then this transform function will evaluate to the zero
 // scale. Otherwise the transform will evaluate to a translation ranging
-// from -50% to +50% in the X and Y directions.
+// from -50% to +50% in the X and Y directions. If no ancestor is a hybrid
+// navigation focus item, then the currently-focused item (which may be in
+// a different subtree) is queried.
 class CobaltUiNavSpotlightTransformFunction : public TransformFunction {
  public:
   // |progress_to_identity| is used to support transitions to or from CSS
@@ -53,8 +55,8 @@
   std::string ToString() const override;
 
   math::Matrix3F ToMatrix(const math::SizeF& used_size,
-      const scoped_refptr<ui_navigation::NavItem>& used_ui_nav_focus)
-      const override;
+                          const scoped_refptr<ui_navigation::NavItem>&
+                              used_ui_nav_focus) const override;
 
   bool operator==(const CobaltUiNavSpotlightTransformFunction& other) const {
     return progress_to_identity_ == other.progress_to_identity_;
diff --git a/src/cobalt/cssom/css_transition.h b/src/cobalt/cssom/css_transition.h
index fd28edf..b6c0521 100644
--- a/src/cobalt/cssom/css_transition.h
+++ b/src/cobalt/cssom/css_transition.h
@@ -27,7 +27,7 @@
 
 class PropertyValue;
 
-// A Transition object represents a persistant transition from one CSS style
+// A Transition object represents a persistent transition from one CSS style
 // value to another.  Most of the data members of this class are defined with
 // names based off of the concepts named here:
 //   https://www.w3.org/TR/2013/WD-css3-transitions-20131119/#starting
diff --git a/src/cobalt/cssom/css_transition_set.cc b/src/cobalt/cssom/css_transition_set.cc
index 3ce5957..8a6787d 100644
--- a/src/cobalt/cssom/css_transition_set.cc
+++ b/src/cobalt/cssom/css_transition_set.cc
@@ -105,11 +105,12 @@
   // half-way through by making the reverse transition occur over half as much
   // time.
   if (old_transition.reversing_adjusted_start_value()->Equals(*new_end_value)) {
-    *new_reversing_shortening_factor =
-        std::min<float>(1.0f, std::max<float>(0.0f,
-            std::abs(old_transition.Progress(current_time) *
-                         old_transition.reversing_shortening_factor() +
-                     1 - old_transition.reversing_shortening_factor())));
+    *new_reversing_shortening_factor = std::min<float>(
+        1.0f,
+        std::max<float>(
+            0.0f, std::abs(old_transition.Progress(current_time) *
+                               old_transition.reversing_shortening_factor() +
+                           1 - old_transition.reversing_shortening_factor())));
 
     *new_reversing_adjusted_start_value = old_transition.end_value();
   } else {
@@ -133,7 +134,7 @@
     const base::TimeDelta& delay,
     const scoped_refptr<TimingFunction>& timing_function,
     const scoped_refptr<PropertyValue>& end_value) {
-  // Since we're updating an old transtion, we'll need to know the animated
+  // Since we're updating an old transition, we'll need to know the animated
   // CSS style value from the old transition at this point in time.
   scoped_refptr<PropertyValue> current_value_within_old_transition =
       old_transition.Evaluate(current_time);
diff --git a/src/cobalt/cssom/css_transition_set.h b/src/cobalt/cssom/css_transition_set.h
index 48f69f7..2a4251a 100644
--- a/src/cobalt/cssom/css_transition_set.h
+++ b/src/cobalt/cssom/css_transition_set.h
@@ -31,7 +31,7 @@
 
 // Maintains a mapping from the set of all unique CSS style properties to
 // active transitions.  Not all style properties may have active transitions.
-// This class is used to maintain persistance of active transitions and is
+// This class is used to maintain persistence of active transitions and is
 // expected to be modified over time as events such as CSS style modifications
 // occur.
 class TransitionSet {
diff --git a/src/cobalt/cssom/interpolate_property_value_test.cc b/src/cobalt/cssom/interpolate_property_value_test.cc
index 1550392..548594a 100644
--- a/src/cobalt/cssom/interpolate_property_value_test.cc
+++ b/src/cobalt/cssom/interpolate_property_value_test.cc
@@ -41,7 +41,7 @@
 const float kErrorEpsilon = 0.00015f;
 
 // Helper function to animate a propertyby a given progress between a given
-// start and end point.  The aniamted value is returned, casted to the passed in
+// start and end point.  The animated value is returned, casted to the passed in
 // template type parameter.
 template <typename T>
 scoped_refptr<T> InterpolatePropertyTyped(
@@ -126,7 +126,7 @@
 }
 
 TEST(InterpolatePropertyValueTest,
-     TransfromFromNoneToCobaltUiNavFocusTransformValuesInterpolate) {
+     TransformFromNoneToCobaltUiNavFocusTransformValuesInterpolate) {
   struct MakeSingleFocusTransform {
     static scoped_refptr<PropertyValue> Start() {
       return KeywordValue::GetNone();
@@ -161,7 +161,7 @@
 }
 
 TEST(InterpolatePropertyValueTest,
-     TransfromSingleCobaltUiNavFocusTransformValuesInterpolate) {
+     TransformSingleCobaltUiNavFocusTransformValuesInterpolate) {
   struct MakeSingleFocusTransform {
     static scoped_refptr<PropertyValue> Start() {
       TransformFunctionListValue::Builder functions;
@@ -200,7 +200,7 @@
 }
 
 TEST(InterpolatePropertyValueTest,
-     TransfromFromNoneToCobaltUiNavSpotlightTransformValuesInterpolate) {
+     TransformFromNoneToCobaltUiNavSpotlightTransformValuesInterpolate) {
   struct MakeSingleSpotlightTransform {
     static scoped_refptr<PropertyValue> Start() {
       return KeywordValue::GetNone();
@@ -233,7 +233,7 @@
 }
 
 TEST(InterpolatePropertyValueTest,
-     TransfromSingleCobaltUiNavSpotlightTransformValuesInterpolate) {
+     TransformSingleCobaltUiNavSpotlightTransformValuesInterpolate) {
   struct MakeSingleSpotlightTransform {
     static scoped_refptr<PropertyValue> Start() {
       TransformFunctionListValue::Builder functions;
diff --git a/src/cobalt/cssom/selector_tree_test.cc b/src/cobalt/cssom/selector_tree_test.cc
index ea17268..38f7cac 100644
--- a/src/cobalt/cssom/selector_tree_test.cc
+++ b/src/cobalt/cssom/selector_tree_test.cc
@@ -50,8 +50,9 @@
   //   kDescendantCombinator -> node_1("div")
   std::unique_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
   scoped_refptr<CSSStyleRule> css_style_rule_1 =
-      css_parser->ParseRule("div {}", base::SourceLocation(
-                                          "[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("div {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   selector_tree.AppendRule(css_style_rule_1);
 
@@ -91,14 +92,14 @@
   //   kDescendantCombinator -> node_1(".class#id")
   std::unique_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
   scoped_refptr<CSSStyleRule> css_style_rule_1 =
-      css_parser->ParseRule(
-                    ".class#id {}",
-                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule(".class#id {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   scoped_refptr<CSSStyleRule> css_style_rule_2 =
-      css_parser->ParseRule(
-                    "#id.class {}",
-                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("#id.class {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   selector_tree.AppendRule(css_style_rule_1);
   selector_tree.AppendRule(css_style_rule_2);
@@ -131,12 +132,14 @@
   //   kDescendantCombinator -> node_1("div")
   std::unique_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
   scoped_refptr<CSSStyleRule> css_style_rule_1 =
-      css_parser->ParseRule("div {}", base::SourceLocation(
-                                          "[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("div {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   scoped_refptr<CSSStyleRule> css_style_rule_2 =
-      css_parser->ParseRule("div {}", base::SourceLocation(
-                                          "[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("div {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   selector_tree.AppendRule(css_style_rule_1);
   selector_tree.AppendRule(css_style_rule_2);
@@ -169,7 +172,7 @@
   EXPECT_EQ(Specificity(0, 0, 1), node_1->cumulative_specificity());
 }
 
-TEST(SelectorTreeTest, AppendRuleSimpleShouldTakeTwoDesendantSelectors) {
+TEST(SelectorTreeTest, AppendRuleSimpleShouldTakeTwoDescendantSelectors) {
   SelectorTree selector_tree;
 
   // Selector Tree:
@@ -178,13 +181,14 @@
   //     kChildCombinator -> node_2("span")
   std::unique_ptr<css_parser::Parser> css_parser = css_parser::Parser::Create();
   scoped_refptr<CSSStyleRule> css_style_rule_1 =
-      css_parser->ParseRule("div {}", base::SourceLocation(
-                                          "[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("div {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   scoped_refptr<CSSStyleRule> css_style_rule_2 =
-      css_parser->ParseRule(
-                    "div span {}",
-                    base::SourceLocation("[object SelectorTreeTest]", 1, 1))
+      css_parser
+          ->ParseRule("div span {}",
+                      base::SourceLocation("[object SelectorTreeTest]", 1, 1))
           ->AsCSSStyleRule();
   selector_tree.AppendRule(css_style_rule_1);
   selector_tree.AppendRule(css_style_rule_2);
diff --git a/src/cobalt/cssom/timing_function.h b/src/cobalt/cssom/timing_function.h
index 2112d3d..b88ca93 100644
--- a/src/cobalt/cssom/timing_function.h
+++ b/src/cobalt/cssom/timing_function.h
@@ -42,7 +42,7 @@
   // value).
   virtual float Evaluate(float x) const = 0;
 
-  // Functions to retreive specific timing functions that are named by CSS
+  // Functions to retrieve specific timing functions that are named by CSS
   // keywords.
   static const scoped_refptr<TimingFunction>& GetEase();
   static const scoped_refptr<TimingFunction>& GetEaseIn();
diff --git a/src/cobalt/debug/backend/script_debugger_agent.cc b/src/cobalt/debug/backend/script_debugger_agent.cc
index 4b8fe1b..d9f024a 100644
--- a/src/cobalt/debug/backend/script_debugger_agent.cc
+++ b/src/cobalt/debug/backend/script_debugger_agent.cc
@@ -81,7 +81,7 @@
   pending_commands_.emplace(command_id, std::move(command));
   if (script_debugger_->DispatchProtocolMessage(method,
                                                 JSONStringify(message))) {
-    // The command has been dispached; keep ownership of it in the map.
+    // The command has been dispatched; keep ownership of it in the map.
     return base::nullopt;
   }
 
diff --git a/src/cobalt/debug/console/debug_hub.cc b/src/cobalt/debug/console/debug_hub.cc
index f8c0b7c..41f3ce1 100644
--- a/src/cobalt/debug/console/debug_hub.cc
+++ b/src/cobalt/debug/console/debug_hub.cc
@@ -109,17 +109,16 @@
 
 const script::Sequence<ConsoleCommand> DebugHub::console_commands() const {
   script::Sequence<ConsoleCommand> result;
-  ConsoleCommandManager* command_mananger =
-      ConsoleCommandManager::GetInstance();
-  DCHECK(command_mananger);
-  if (command_mananger) {
-    std::set<std::string> commands = command_mananger->GetRegisteredCommands();
+  ConsoleCommandManager* command_manager = ConsoleCommandManager::GetInstance();
+  DCHECK(command_manager);
+  if (command_manager) {
+    std::set<std::string> commands = command_manager->GetRegisteredCommands();
     for (std::set<std::string>::const_iterator it = commands.begin();
          it != commands.end(); ++it) {
       ConsoleCommand console_command;
       console_command.set_command(*it);
-      console_command.set_short_help(command_mananger->GetShortHelp(*it));
-      console_command.set_long_help(command_mananger->GetLongHelp(*it));
+      console_command.set_short_help(command_manager->GetShortHelp(*it));
+      console_command.set_long_help(command_manager->GetLongHelp(*it));
       result.push_back(console_command);
     }
   }
diff --git a/src/cobalt/demos/content/background-mode-demo/background-mode-demo.js b/src/cobalt/demos/content/background-mode-demo/background-mode-demo.js
index 6de9271..2245eb4 100644
--- a/src/cobalt/demos/content/background-mode-demo/background-mode-demo.js
+++ b/src/cobalt/demos/content/background-mode-demo/background-mode-demo.js
@@ -24,6 +24,7 @@
 
 let playlist = getPlaylist();
 let index = 0;
+let defaultSkipTime = 10;
 
 var kAdaptiveAudioChunkSize = 720 * 1024;
 
@@ -92,7 +93,7 @@
   startAdaptiveVideo();
 }
 
-function main() {
+function checkMediaType() {
   var get_parameters = window.location.search.substr(1).split('&');
   for (var param of get_parameters) {
     splitted = param.split('=');
@@ -104,77 +105,74 @@
   if (type != 'audio' && type != 'video') {
     throw "invalid type " + type;
   }
+}
 
+function main() {
+  checkMediaType();
   video = createVideoElement();
   startNextVideo();
+  setUpMediaSessionHandlers();
   updateMetadata();
 }
 
-main();
-
-// MeidaSession
+// MediaSession
 function updateMetadata() {
   let track = playlist[index];
 
   navigator.mediaSession.metadata = new MediaMetadata({
     title: track.title,
     artist: track.artist,
-    //artwork: track.artwork
   });
   navigator.mediaSession.playbackState = "playing";
 }
 
-let defaultSkipTime = 10;
-
-navigator.mediaSession.setActionHandler('seekbackward', function(event) {
-  const skipTime = event.seekOffset || defaultSkipTime;
-  video.currentTime = Math.max(video.currentTime - skipTime, 0);
-  updatePositionState();
-});
-
-navigator.mediaSession.setActionHandler('seekforward', function(event) {
-  const skipTime = event.seekOffset || defaultSkipTime;
-  video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
-  updatePositionState();
-});
-
-navigator.mediaSession.setActionHandler('play', function() {
-  log_info('TimeStamp: ' + getTime() + ' seconds' + ' play');
-  video.play();
-  navigator.mediaSession.playbackState = "playing";
-});
-
-navigator.mediaSession.setActionHandler('pause', function() {
-  log_info('TimeStamp: ' + getTime() + ' seconds' + ' pause');
-  video.pause();
-  navigator.mediaSession.playbackState = "paused";
-});
-
-
-try {
-  navigator.mediaSession.setActionHandler('stop', function() {
-    log_info('TimeStamp: ' + getTime() + ' seconds' + ' stop');
-  });
-} catch(error) {
-}
-
-try {
-  navigator.mediaSession.setActionHandler('seekto', function(event) {
-    if (event.fastSeek && ('fastSeek' in video)) {
-      video.fastSeek(event.seekTime);
-      return;
-    }
-    video.currentTime = event.seekTime;
+function setUpMediaSessionHandlers() {
+  navigator.mediaSession.setActionHandler('seekbackward', function(event) {
+    const skipTime = event.seekOffset || defaultSkipTime;
+    video.currentTime = Math.max(video.currentTime - skipTime, 0);
     updatePositionState();
   });
-} catch(error) {
+
+  navigator.mediaSession.setActionHandler('seekforward', function(event) {
+    const skipTime = event.seekOffset || defaultSkipTime;
+    video.currentTime = Math.min(video.currentTime + skipTime, video.duration);
+    updatePositionState();
+  });
+
+  navigator.mediaSession.setActionHandler('play', function() {
+    log_info('TimeStamp: ' + getTime() + ' seconds' + ' play');
+    video.play();
+    navigator.mediaSession.playbackState = "playing";
+  });
+
+  navigator.mediaSession.setActionHandler('pause', function() {
+    log_info('TimeStamp: ' + getTime() + ' seconds' + ' pause');
+    video.pause();
+    navigator.mediaSession.playbackState = "paused";
+  });
+
+  try {
+    navigator.mediaSession.setActionHandler('stop', function() {
+      log_info('TimeStamp: ' + getTime() + ' seconds' + ' stop');
+    });
+  } catch(error) {
+  }
+
+  try {
+    navigator.mediaSession.setActionHandler('seekto', function(event) {
+      if (event.fastSeek && ('fastSeek' in video)) {
+        video.fastSeek(event.seekTime);
+        return;
+      }
+      video.currentTime = event.seekTime;
+      updatePositionState();
+    });
+  } catch(error) {
+  }
 }
 
 function getPlaylist() {
-  return [{
-      title: 'Background mode demo',
-      artist: 'Cobalt',
-    }];
+  return [{title: 'Background mode demo', artist: 'Cobalt',}];
 }
 
 function log_info(message) {
@@ -186,3 +184,4 @@
   return Math.floor(Date.now() / 1000 | 0);
 }
 
+main();
diff --git a/src/cobalt/demos/content/hybrid-navigation/hybrid-navigation-grid.html b/src/cobalt/demos/content/hybrid-navigation/hybrid-navigation-grid.html
index 130c1ba..3b7d58b 100644
--- a/src/cobalt/demos/content/hybrid-navigation/hybrid-navigation-grid.html
+++ b/src/cobalt/demos/content/hybrid-navigation/hybrid-navigation-grid.html
@@ -17,7 +17,8 @@
  | (i.e. this element or an ancestor element with tabindex set appropriately).
  | If that navigation item does not have focus, or the system does not provide
  | interaction animations, then this transform function will evaluate to
- | identity.
+ | identity. If no ancestor is a hybrid navigation focus item, then the
+ | currently-focused item (which may be in a different subtree) is used.
  |
  | "-cobalt-ui-nav-spotlight-transform()" is a Cobalt-specific transform
  | function for hybrid navigation which tracks the direction in which focus is
@@ -28,7 +29,8 @@
  | not have focus, or the platform does not provide focus movement information,
  | then this transform function will evaluate to the zero scale. Otherwise the
  | transform will evaluate to a translation ranging from -50% to +50% in the X
- | and Y directions.
+ | and Y directions. If no ancestor is a hybrid navigation focus item, then the
+ | currently-focused item (which may be in a different subtree) is queried.
  -->
 <html>
   <head>
@@ -134,7 +136,7 @@
   <body class="body">
     <div class="vscroll">
       <div class="hscroll">
-        <div class="focusItem" tabindex="-2" style="transform: translateX(0px)">
+        <div id="start" class="focusItem" tabindex="-2" style="transform: translateX(0px)">
           <div class="focusContent">A0</div>
         </div>
         <div class="focusItem" tabindex="-2" style="transform: translateX(300px)">
@@ -231,4 +233,9 @@
       </div>
     </div>
   </body>
+  <script>
+    window.onload = function() {
+      document.getElementById("start").focus();
+    }
+  </script>
 </html>
diff --git a/src/cobalt/dom/captions/caption_state.idl b/src/cobalt/dom/captions/caption_state.idl
index 1d72cef..f5a9c74 100644
--- a/src/cobalt/dom/captions/caption_state.idl
+++ b/src/cobalt/dom/captions/caption_state.idl
@@ -28,7 +28,7 @@
   // take priority over app defaults. If SystemCaptionSettings.supportsOverride
   // contains true, this value should be interpreted as explicitly saying
   // "do not override." If it contains false, it is up to the application to
-  // intepret any additional meaning of this value.
+  // interpret any additional meaning of this value.
   "set",
 
   // This property should take priority over everything but application-level
diff --git a/src/cobalt/dom/captions/system_caption_settings.idl b/src/cobalt/dom/captions/system_caption_settings.idl
index 46a5bc0..5b51256 100644
--- a/src/cobalt/dom/captions/system_caption_settings.idl
+++ b/src/cobalt/dom/captions/system_caption_settings.idl
@@ -16,7 +16,7 @@
 
 // This is an API for accessing system-level closed caption settings and
 // exposing them to HTML5 apps. It supports detecting if captions are enabled at
-// a system level, and retreiving values of various captioning style
+// a system level, and retrieving values of various captioning style
 // properties assigned by the system.
 
 // For each captioning style property that this API supports, there are two
@@ -85,8 +85,8 @@
   // There are separate checks for reading and writing to the enabled attribute,
   // as some systems allow the value to be queried but not written to. Setting
   // the enabled attribute will change the system-wide enabled setting.
-  // Attemping to read isEnabled when supportsIsEnabled is false will
-  // always return false. Attemping to set isEnabled when supportsSetEnabled is
+  // Attempting to read isEnabled when supportsIsEnabled is false will
+  // always return false. Attempting to set isEnabled when supportsSetEnabled is
   // false will fail silently.
   readonly attribute boolean supportsIsEnabled;
   readonly attribute boolean supportsSetEnabled;
diff --git a/src/cobalt/dom/csp_delegate_factory.cc b/src/cobalt/dom/csp_delegate_factory.cc
index b4d1de5..ad30781 100644
--- a/src/cobalt/dom/csp_delegate_factory.cc
+++ b/src/cobalt/dom/csp_delegate_factory.cc
@@ -47,7 +47,7 @@
 
 CspDelegate* CreateInsecureDelegate(
     std::unique_ptr<CspViolationReporter> violation_reporter, const GURL& url,
-    csp::CSPHeaderPolicy requre_csp,
+    csp::CSPHeaderPolicy require_csp,
     const base::Closure& policy_changed_callback, int insecure_allowed_token) {
   if (InsecureAllowed(insecure_allowed_token)) {
     return new CspDelegateInsecure();
diff --git a/src/cobalt/dom/csp_delegate_factory.h b/src/cobalt/dom/csp_delegate_factory.h
index ced517a..0e1541c 100644
--- a/src/cobalt/dom/csp_delegate_factory.h
+++ b/src/cobalt/dom/csp_delegate_factory.h
@@ -51,7 +51,7 @@
   typedef CspDelegate* (*CspDelegateCreator)(
       std::unique_ptr<CspViolationReporter> violation_reporter, const GURL& url,
       csp::CSPHeaderPolicy require_csp,
-      const base::Closure& policy_chagned_callback, int insecure_allowed_token);
+      const base::Closure& policy_changed_callback, int insecure_allowed_token);
 
 #if !defined(COBALT_FORCE_CSP)
   // Allow tests to have the factory create a different delegate type.
diff --git a/src/cobalt/dom/document.cc b/src/cobalt/dom/document.cc
index cce2d9a..8545de1 100644
--- a/src/cobalt/dom/document.cc
+++ b/src/cobalt/dom/document.cc
@@ -874,10 +874,21 @@
       active_element() ? active_element()->AsHTMLElement() : nullptr;
   if (active_html_element && ui_nav_focus_needs_update_) {
     ui_nav_focus_needs_update_ = false;
-    active_html_element->UpdateUiNavigationFocus(/* force_update */ false);
+    active_html_element->UpdateUiNavigationFocus();
   }
 }
 
+bool Document::TrySetUiNavFocusElement(const void* focus_element,
+                                       SbTimeMonotonic time) {
+  if (ui_nav_focus_element_update_time_ > time) {
+    // A later focus update was already issued.
+    return false;
+  }
+  ui_nav_focus_element_update_time_ = time;
+  ui_nav_focus_element_ = focus_element;
+  return true;
+}
+
 void Document::SampleTimelineTime() { default_timeline_->Sample(); }
 
 #if defined(ENABLE_PARTIAL_LAYOUT_CONTROL)
@@ -1019,7 +1030,7 @@
         active_element() ? active_element()->AsHTMLElement() : nullptr;
     if (active_html_element) {
       ui_nav_focus_needs_update_ = false;
-      active_html_element->UpdateUiNavigationFocus(/* force_update */ true);
+      active_html_element->UpdateUiNavigationFocus();
     }
   }
 }
diff --git a/src/cobalt/dom/document.h b/src/cobalt/dom/document.h
index 627cfae..1483954 100644
--- a/src/cobalt/dom/document.h
+++ b/src/cobalt/dom/document.h
@@ -55,6 +55,7 @@
 #include "cobalt/network_bridge/net_poster.h"
 #include "cobalt/script/exception_state.h"
 #include "cobalt/script/wrappable.h"
+#include "starboard/time.h"
 #include "url/gurl.h"
 
 namespace cobalt {
@@ -349,11 +350,9 @@
 
   // Track UI navigation system's focus element.
   const void* ui_nav_focus_element() const { return ui_nav_focus_element_; }
-  void set_ui_nav_focus_element(const void* focus_element) {
-    ui_nav_focus_element_ = focus_element;
-  }
+  bool TrySetUiNavFocusElement(const void* focus_element, SbTimeMonotonic time);
 
-  // Track HTML elements that are UI navigtion items. This facilitates updating
+  // Track HTML elements that are UI navigation items. This facilitates updating
   // their layout information as needed.
   void AddUiNavigationElement(HTMLElement* element) {
     ui_nav_elements_.insert(element);
@@ -624,6 +623,10 @@
   // not meant to be dereferenced.
   const void* ui_nav_focus_element_ = nullptr;
 
+  // Since UI navigation involves multiple threads, use a timestamp to help
+  // filter out obsolete focus changes.
+  SbTimeMonotonic ui_nav_focus_element_update_time_ = 0;
+
   // Track all HTMLElements in this document which are UI navigation items.
   // These should be raw pointers to avoid affecting the elements' ref counts.
   // The elements will explicitly add and remove themselves from this set.
diff --git a/src/cobalt/dom/document_page_lifecycle.idl b/src/cobalt/dom/document_page_lifecycle.idl
index e96b6ad..2c821ff 100644
--- a/src/cobalt/dom/document_page_lifecycle.idl
+++ b/src/cobalt/dom/document_page_lifecycle.idl
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Page Lifecyle API
+// Page Lifecycle API
 // https://wicg.github.io/page-lifecycle/#sec-api
 
 partial interface Document {
diff --git a/src/cobalt/dom/dom.gyp b/src/cobalt/dom/dom.gyp
index 366eaab..22e1fb3 100644
--- a/src/cobalt/dom/dom.gyp
+++ b/src/cobalt/dom/dom.gyp
@@ -256,8 +256,11 @@
         'application_lifecycle_state.h',
         'performance.cc',
         'performance.h',
+        'performance_entry.cc',
+        'performance_entry.h',
         'performance_timing.cc',
         'performance_timing.h',
+        'performance_high_resolution_time.h',
         'plugin_array.cc',
         'plugin_array.h',
         'pointer_event.cc',
diff --git a/src/cobalt/dom/dom_test.gyp b/src/cobalt/dom/dom_test.gyp
index 53e43cc..53d4fb1 100644
--- a/src/cobalt/dom/dom_test.gyp
+++ b/src/cobalt/dom/dom_test.gyp
@@ -18,7 +18,7 @@
   },
   'targets': [
     {
-      # For the convenince, some tests depend on dom_parser.gyp:dom_parser. To
+      # For the convenience, some tests depend on dom_parser.gyp:dom_parser. To
       # avoid the dependency cycle between the two gyp files, dom_test is
       # separated into its own gyp file.
       'target_name': 'dom_test',
diff --git a/src/cobalt/dom/event_target.h b/src/cobalt/dom/event_target.h
index 23411b5..66b4a3f 100644
--- a/src/cobalt/dom/event_target.h
+++ b/src/cobalt/dom/event_target.h
@@ -121,7 +121,7 @@
       const base::Location& location, const scoped_refptr<Event>& event,
       const base::Closure& dispatched_callback);
 
-  // Check if target has event listener (atrtibute or not attribute).
+  // Check if target has event listener (attribute or not attribute).
   bool HasEventListener(base::Token type);
 
   // Web API: GlobalEventHandlers (implements)
diff --git a/src/cobalt/dom/html_element.cc b/src/cobalt/dom/html_element.cc
index c02f298..359ea9c 100644
--- a/src/cobalt/dom/html_element.cc
+++ b/src/cobalt/dom/html_element.cc
@@ -80,6 +80,17 @@
 // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
 const int32 kUiNavFocusTabIndexThreshold = -2;
 
+// This custom data attribute can be used to force UI navigation to remain
+// focused on the element for a specified duration.
+const char kUiNavFocusDurationAttribute[] = "data-cobalt-ui-nav-focus-duration";
+
+void UiNavCallbackHelper(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    base::Callback<void(SbTimeMonotonic)> callback) {
+  task_runner->PostTask(FROM_HERE,
+                        base::Bind(callback, SbTimeGetMonotonicNow()));
+}
+
 struct NonTrivialStaticFields {
   NonTrivialStaticFields() {
     cssom::PropertyKeyVector computed_style_invalidation_properties;
@@ -1169,23 +1180,25 @@
   directionality_ = base::nullopt;
 }
 
-void HTMLElement::OnUiNavBlur() {
+void HTMLElement::OnUiNavBlur(SbTimeMonotonic time) {
   if (node_document() && node_document()->ui_nav_focus_element() == this) {
-    node_document()->set_ui_nav_focus_element(nullptr);
-    Blur();
+    if (node_document()->TrySetUiNavFocusElement(nullptr, time)) {
+      Blur();
+    }
   }
 }
 
-void HTMLElement::OnUiNavFocus() {
+void HTMLElement::OnUiNavFocus(SbTimeMonotonic time) {
   // Suppress the focus event if this is already focused -- i.e. the HTMLElement
   // initiated the focus change that resulted in this call to OnUiNavFocus.
   if (node_document() && node_document()->ui_nav_focus_element() != this) {
-    node_document()->set_ui_nav_focus_element(this);
-    Focus();
+    if (node_document()->TrySetUiNavFocusElement(this, time)) {
+      Focus();
+    }
   }
 }
 
-void HTMLElement::OnUiNavScroll() {
+void HTMLElement::OnUiNavScroll(SbTimeMonotonic /* time */) {
   Document* document = node_document();
   scoped_refptr<Window> window(document ? document->window() : nullptr);
   DispatchEvent(new UIEvent(base::Tokens::scroll(), Event::kBubbles,
@@ -1268,6 +1281,8 @@
     SetDir(value);
   } else if (name == "tabindex") {
     SetTabIndex(value);
+  } else if (name == kUiNavFocusDurationAttribute) {
+    SetUiNavFocusDuration(value);
   }
 
   // Always clear the matching state when an attribute changes. Any attribute
@@ -1280,6 +1295,8 @@
     SetDir("");
   } else if (name == "tabindex") {
     SetTabIndex("");
+  } else if (name == kUiNavFocusDurationAttribute) {
+    SetUiNavFocusDuration("");
   }
 
   // Always clear the matching state when an attribute changes. Any attribute
@@ -1402,7 +1419,7 @@
   ClearRuleMatchingState();
 }
 
-void HTMLElement::UpdateUiNavigationFocus(bool force_focus) {
+void HTMLElement::UpdateUiNavigationFocus() {
   if (!node_document()) {
     return;
   }
@@ -1424,17 +1441,15 @@
         html_element->ui_nav_item_->IsContainer()) {
       continue;
     }
-    if (node_document()->ui_nav_focus_element() == html_element &&
-        !force_focus) {
-      // UI navigation is already focused on the correct element.
-      break;
-    }
+
     // Updating the UI navigation focus element has the additional effect of
     // suppressing the Blur call for the previously focused HTMLElement and the
     // Focus call for this HTMLElement as a result of OnUiNavBlur / OnUiNavFocus
     // callbacks that result from initiating the UI navigation focus change.
-    node_document()->set_ui_nav_focus_element(html_element);
-    html_element->ui_nav_item_->Focus();
+    if (node_document()->TrySetUiNavFocusElement(html_element,
+                                                 SbTimeGetMonotonicNow())) {
+      html_element->ui_nav_item_->Focus();
+    }
     break;
   }
 }
@@ -1477,6 +1492,25 @@
   ui_nav_needs_update_ = true;
 }
 
+void HTMLElement::SetUiNavFocusDuration(const std::string& value) {
+  double duration;
+  if (base::StringToDouble(value, &duration)) {
+    ui_nav_focus_duration_ = static_cast<float>(duration);
+    if (!std::isfinite(*ui_nav_focus_duration_) ||
+        *ui_nav_focus_duration_ < 0.0f) {
+      ui_nav_focus_duration_ = 0.0f;
+    }
+    if (ui_nav_item_) {
+      ui_nav_item_->SetFocusDuration(*ui_nav_focus_duration_);
+    }
+  } else {
+    ui_nav_focus_duration_ = base::nullopt;
+    if (ui_nav_item_) {
+      ui_nav_item_->SetFocusDuration(0.0f);
+    }
+  }
+}
+
 namespace {
 // This is similar to base rtl.h's GetStringDirection; however, this takes a
 // utf8 string and only pays attention to L, AL, and R character types.
@@ -2111,7 +2145,7 @@
   return false;
 }
 
-bool HTMLElement::CanbeDesignatedByPointerIfDisplayed() const {
+bool HTMLElement::CanBeDesignatedByPointerIfDisplayed() const {
   return computed_style()->pointer_events() != cssom::KeywordValue::GetNone() &&
          computed_style()->visibility() == cssom::KeywordValue::GetVisible();
 }
@@ -2149,29 +2183,32 @@
     ui_nav_item_ = new ui_navigation::NavItem(
         *ui_nav_item_type,
         base::Bind(
-            base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
-            base::Unretained(base::MessageLoop::current()->task_runner().get()),
-            FROM_HERE,
+            &UiNavCallbackHelper, base::MessageLoop::current()->task_runner(),
             base::Bind(&HTMLElement::OnUiNavBlur, base::AsWeakPtr(this))),
         base::Bind(
-            base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
-            base::Unretained(base::MessageLoop::current()->task_runner().get()),
-            FROM_HERE,
+            &UiNavCallbackHelper, base::MessageLoop::current()->task_runner(),
             base::Bind(&HTMLElement::OnUiNavFocus, base::AsWeakPtr(this))),
         base::Bind(
-            base::IgnoreResult(&base::SingleThreadTaskRunner::PostTask),
-            base::Unretained(base::MessageLoop::current()->task_runner().get()),
-            FROM_HERE,
+            &UiNavCallbackHelper, base::MessageLoop::current()->task_runner(),
             base::Bind(&HTMLElement::OnUiNavScroll, base::AsWeakPtr(this))));
     ui_nav_item_->SetDir(ui_nav_item_dir);
+    if (ui_nav_focus_duration_) {
+      ui_nav_item_->SetFocusDuration(*ui_nav_focus_duration_);
+    }
 
     node_document()->AddUiNavigationElement(this);
     node_document()->set_ui_nav_needs_layout(true);
     InvalidateLayoutBoxRenderTreeNodes();
+    if (layout_boxes_) {
+      layout_boxes_->SetUiNavItem(ui_nav_item_);
+    }
   } else if (ui_nav_item_) {
     // This navigation item is no longer relevant.
     ReleaseUiNavigationItem();
     InvalidateLayoutBoxRenderTreeNodes();
+    if (layout_boxes_) {
+      layout_boxes_->SetUiNavItem(ui_nav_item_);
+    }
   }
 }
 
@@ -2183,8 +2220,10 @@
       node_document()->RemoveUiNavigationElement(this);
       node_document()->set_ui_nav_needs_layout(true);
       if (node_document()->ui_nav_focus_element() == this) {
-        node_document()->set_ui_nav_focus_element(nullptr);
-        ui_nav_item_->UnfocusAll();
+        if (node_document()->TrySetUiNavFocusElement(nullptr,
+                                                     SbTimeGetMonotonicNow())) {
+          ui_nav_item_->UnfocusAll();
+        }
       }
     }
     ui_nav_item_->SetEnabled(false);
diff --git a/src/cobalt/dom/html_element.h b/src/cobalt/dom/html_element.h
index 2eddb38..4ddc196 100644
--- a/src/cobalt/dom/html_element.h
+++ b/src/cobalt/dom/html_element.h
@@ -45,6 +45,7 @@
 #include "cobalt/dom/pseudo_element.h"
 #include "cobalt/loader/image/image_cache.h"
 #include "cobalt/ui_navigation/nav_item.h"
+#include "starboard/time.h"
 
 namespace cobalt {
 namespace dom {
@@ -353,7 +354,7 @@
 
   // Returns whether the element can be designated by a pointer.
   //   https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty
-  bool CanbeDesignatedByPointerIfDisplayed() const;
+  bool CanBeDesignatedByPointerIfDisplayed() const;
 
   // Returns true if this node and all of its ancestors do NOT have display set
   // to 'none'.
@@ -366,7 +367,7 @@
 
   // Update the UI navigation system to focus on the relevant navigation item
   // for this HTML element (if any).
-  void UpdateUiNavigationFocus(bool force_focus);
+  void UpdateUiNavigationFocus();
 
   // Returns true if the element is the root element as defined in
   // https://www.w3.org/TR/html50/semantics.html#the-root-element.
@@ -415,6 +416,9 @@
   // Update the cached value of tabindex.
   void SetTabIndex(const std::string& value);
 
+  // Update cached UI navigation focus duration.
+  void SetUiNavFocusDuration(const std::string& value);
+
   // Invalidate the matching rules and rule matching state in this element and
   // its descendants. In the case where this is the the initial invalidation,
   // it will also invalidate the rule matching state of its siblings.
@@ -446,9 +450,9 @@
   void InvalidateLayoutBoxes();
 
   // Handle UI navigation events.
-  void OnUiNavBlur();
-  void OnUiNavFocus();
-  void OnUiNavScroll();
+  void OnUiNavBlur(SbTimeMonotonic time);
+  void OnUiNavFocus(SbTimeMonotonic time);
+  void OnUiNavScroll(SbTimeMonotonic time);
 
   bool locked_for_focus_;
 
@@ -521,6 +525,10 @@
   // boxes without requiring a new layout.
   scoped_refptr<ui_navigation::NavItem> ui_nav_item_;
 
+  // Specify how long focus should remain on this navigation item once it
+  // becomes focused.
+  base::Optional<float> ui_nav_focus_duration_;
+
   // Signal whether the UI navigation item may need to be updated.
   bool ui_nav_needs_update_ = false;
 
diff --git a/src/cobalt/dom/html_media_element.cc b/src/cobalt/dom/html_media_element.cc
index 13fbcc8..84edb94 100644
--- a/src/cobalt/dom/html_media_element.cc
+++ b/src/cobalt/dom/html_media_element.cc
@@ -15,6 +15,7 @@
 #include "cobalt/dom/html_media_element.h"
 
 #include <algorithm>
+#include <cmath>
 #include <limits>
 #include <memory>
 #include <utility>
@@ -41,7 +42,6 @@
 #include "cobalt/media/fetcher_buffered_data_source.h"
 #include "cobalt/media/web_media_player_factory.h"
 #include "cobalt/script/script_value_factory.h"
-#include "starboard/double.h"
 
 #include "cobalt/dom/eme/media_encrypted_event.h"
 #include "cobalt/dom/eme/media_encrypted_event_init.h"
@@ -314,6 +314,9 @@
     // re-create the entire player.
     if (player_) {
       ClearMediaPlayer();
+      // |media_keys_| is used in CreateMediaPlayer(). Reset it before calling
+      // CreateMediaPlayer().
+      media_keys_.reset();
       CreateMediaPlayer();
     }
   }
@@ -640,7 +643,7 @@
 
 void HTMLMediaElement::ScheduleEvent(const scoped_refptr<Event>& event) {
   TRACE_EVENT0("cobalt::dom", "HTMLMediaElement::ScheduleEvent()");
-  LOG(INFO) << "Schedule event " << event->type() << ".";
+  MLOG() << "Schedule event " << event->type() << ".";
   event_queue_.Enqueue(event);
 }
 
@@ -1406,7 +1409,7 @@
 
 bool HTMLMediaElement::EndedPlayback() const {
   float dur = duration();
-  if (!player_ || SbDoubleIsNan(dur)) {
+  if (!player_ || std::isnan(dur)) {
     return false;
   }
 
@@ -1538,7 +1541,7 @@
   // when the direction of playback is forwards, then the user agent must follow
   // these steps:
   eos_played |=
-      !SbDoubleIsNan(dur) && (0.0f != dur) && now >= dur && playback_rate_ > 0;
+      !std::isnan(dur) && (0.0f != dur) && now >= dur && playback_rate_ > 0;
   if (eos_played) {
     LOG(INFO) << "End of stream is played.";
     // If the media element has a loop attribute specified and does not have a
@@ -1750,7 +1753,7 @@
     const std::string& max_video_capabilities,
     script::ExceptionState* exception_state) {
   if (GetAttribute("src").value_or("").length() > 0) {
-    LOG(WARNING) << "Cannot set maxmium capabilities after src is defined.";
+    LOG(WARNING) << "Cannot set maximum capabilities after src is defined.";
     DOMException::Raise(DOMException::kInvalidStateErr, exception_state);
     return;
   }
diff --git a/src/cobalt/dom/html_script_element.h b/src/cobalt/dom/html_script_element.h
index bd2fc18..d9c41c0 100644
--- a/src/cobalt/dom/html_script_element.h
+++ b/src/cobalt/dom/html_script_element.h
@@ -154,7 +154,7 @@
   loader::RequestMode request_mode_;
 
   // Will be compared with document's origin to derive mute_errors flag
-  // javascript parser takes in to record if the error reqort should be muted
+  // javascript parser takes in to record if the error report should be muted
   // due to cross-origin fetched script.
   loader::Origin fetched_last_url_origin_;
 
diff --git a/src/cobalt/dom/layout_boxes.h b/src/cobalt/dom/layout_boxes.h
index 69c160e..440e982 100644
--- a/src/cobalt/dom/layout_boxes.h
+++ b/src/cobalt/dom/layout_boxes.h
@@ -20,6 +20,7 @@
 #include "cobalt/dom/dom_rect_list.h"
 #include "cobalt/math/rect_f.h"
 #include "cobalt/math/vector2d_f.h"
+#include "cobalt/ui_navigation/nav_item.h"
 
 namespace cobalt {
 namespace dom {
@@ -88,6 +89,10 @@
   // Invalidate the layout box's render tree nodes.
   virtual void InvalidateRenderTreeNodes() = 0;
 
+  // Update the navigation item associated with the layout boxes.
+  virtual void SetUiNavItem(
+      const scoped_refptr<ui_navigation::NavItem>& item) = 0;
+
  protected:
   LayoutBoxes() {}
 };
diff --git a/src/cobalt/dom/media_key_complete_event.cc b/src/cobalt/dom/media_key_complete_event.cc
deleted file mode 100644
index d155a74..0000000
--- a/src/cobalt/dom/media_key_complete_event.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/media_key_complete_event.h"
-
-#include "cobalt/base/tokens.h"
-
-namespace cobalt {
-namespace dom {
-
-MediaKeyCompleteEvent::MediaKeyCompleteEvent(const std::string& key_system,
-                                             const std::string& session_id)
-    : Event(base::Tokens::keyadded(), kNotBubbles, kNotCancelable),
-      key_system_(key_system),
-      session_id_(session_id) {}
-
-}  // namespace dom
-}  // namespace cobalt
diff --git a/src/cobalt/dom/media_key_complete_event.h b/src/cobalt/dom/media_key_complete_event.h
deleted file mode 100644
index d5582e5..0000000
--- a/src/cobalt/dom/media_key_complete_event.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_MEDIA_KEY_COMPLETE_EVENT_H_
-#define COBALT_DOM_MEDIA_KEY_COMPLETE_EVENT_H_
-
-#include <string>
-
-#include "cobalt/dom/event.h"
-#include "cobalt/script/wrappable.h"
-
-namespace cobalt {
-namespace dom {
-
-// The MediaKeyCompleteEvent indicates that a key has been added as the result
-// of an addKey() call.
-//   https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeycompleteevent
-class MediaKeyCompleteEvent : public Event {
- public:
-  MediaKeyCompleteEvent(const std::string& key_system,
-                        const std::string& session_id);
-
-  const std::string& key_system() const { return key_system_; }
-  const std::string& session_id() const { return session_id_; }
-
-  DEFINE_WRAPPABLE_TYPE(MediaKeyCompleteEvent);
-
- private:
-  std::string key_system_;
-  std::string session_id_;
-};
-
-}  // namespace dom
-}  // namespace cobalt
-
-#endif  // COBALT_DOM_MEDIA_KEY_COMPLETE_EVENT_H_
diff --git a/src/cobalt/dom/media_key_complete_event.idl b/src/cobalt/dom/media_key_complete_event.idl
deleted file mode 100644
index 9a2dfaf..0000000
--- a/src/cobalt/dom/media_key_complete_event.idl
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-interface MediaKeyCompleteEvent : Event {
-  readonly attribute DOMString keySystem;
-  readonly attribute DOMString sessionId;
-};
diff --git a/src/cobalt/dom/media_key_error.h b/src/cobalt/dom/media_key_error.h
deleted file mode 100644
index bee77b9..0000000
--- a/src/cobalt/dom/media_key_error.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_MEDIA_KEY_ERROR_H_
-#define COBALT_DOM_MEDIA_KEY_ERROR_H_
-
-#include "cobalt/script/wrappable.h"
-
-namespace cobalt {
-namespace dom {
-
-// The MediaKeyError represents an error in Encrypted Media Extension.
-//   https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeyerror
-class MediaKeyError : public script::Wrappable {
- public:
-  // Web API: MediaKeyError
-  //
-  enum Code {
-    kMediaKeyerrUnknown = 1,
-    kMediaKeyerrClient = 2,
-    kMediaKeyerrService = 3,
-    kMediaKeyerrOutput = 4,
-    kMediaKeyerrHardwarechange = 5,
-    kMediaKeyerrDomain = 6,
-  };
-
-  DEFINE_WRAPPABLE_TYPE(MediaKeyError);
-};
-
-}  // namespace dom
-}  // namespace cobalt
-
-#endif  // COBALT_DOM_MEDIA_KEY_ERROR_H_
diff --git a/src/cobalt/dom/media_key_error.idl b/src/cobalt/dom/media_key_error.idl
deleted file mode 100644
index 8f115a2..0000000
--- a/src/cobalt/dom/media_key_error.idl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-interface MediaKeyError {
-  const unsigned short MEDIA_KEYERR_UNKNOWN = 1;
-  const unsigned short MEDIA_KEYERR_CLIENT = 2;
-  const unsigned short MEDIA_KEYERR_SERVICE = 3;
-  const unsigned short MEDIA_KEYERR_OUTPUT = 4;
-  const unsigned short MEDIA_KEYERR_HARDWARECHANGE = 5;
-  const unsigned short MEDIA_KEYERR_DOMAIN = 6;
-};
diff --git a/src/cobalt/dom/media_key_error_event.cc b/src/cobalt/dom/media_key_error_event.cc
deleted file mode 100644
index 3a5a1f9..0000000
--- a/src/cobalt/dom/media_key_error_event.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/media_key_error_event.h"
-
-#include "cobalt/base/tokens.h"
-
-namespace cobalt {
-namespace dom {
-
-MediaKeyErrorEvent::MediaKeyErrorEvent(const std::string& key_system,
-                                       const std::string& session_id,
-                                       MediaKeyError::Code error_code,
-                                       uint16 system_code)
-    : Event(base::Tokens::keyerror(), kNotBubbles, kNotCancelable),
-      key_system_(key_system),
-      session_id_(session_id),
-      error_code_(static_cast<uint16>(error_code)),
-      system_code_(system_code) {}
-
-}  // namespace dom
-}  // namespace cobalt
diff --git a/src/cobalt/dom/media_key_error_event.h b/src/cobalt/dom/media_key_error_event.h
deleted file mode 100644
index 047dfb2..0000000
--- a/src/cobalt/dom/media_key_error_event.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_MEDIA_KEY_ERROR_EVENT_H_
-#define COBALT_DOM_MEDIA_KEY_ERROR_EVENT_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "cobalt/dom/event.h"
-#include "cobalt/dom/media_key_error.h"
-#include "cobalt/script/wrappable.h"
-
-namespace cobalt {
-namespace dom {
-
-// The MediaKeyErrorEvent indicates that an error occurs in one of the new
-// methods or CDM.
-//   https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeyerrorevent
-class MediaKeyErrorEvent : public Event {
- public:
-  MediaKeyErrorEvent(const std::string& key_system,
-                     const std::string& session_id,
-                     MediaKeyError::Code error_code, uint16 system_code);
-
-  const std::string& key_system() const { return key_system_; }
-  const std::string& session_id() const { return session_id_; }
-  uint16 error_code() const { return error_code_; }
-  uint16 system_code() const { return system_code_; }
-
-  DEFINE_WRAPPABLE_TYPE(MediaKeyErrorEvent);
-
- private:
-  std::string key_system_;
-  std::string session_id_;
-  uint16 error_code_;
-  uint16 system_code_;
-};
-
-}  // namespace dom
-}  // namespace cobalt
-
-#endif  // COBALT_DOM_MEDIA_KEY_ERROR_EVENT_H_
diff --git a/src/cobalt/dom/media_key_error_event.idl b/src/cobalt/dom/media_key_error_event.idl
deleted file mode 100644
index dc88c37..0000000
--- a/src/cobalt/dom/media_key_error_event.idl
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-interface MediaKeyErrorEvent : Event {
-  readonly attribute DOMString keySystem;
-  readonly attribute DOMString sessionId;
-  readonly attribute MediaKeyError errorCode;
-  readonly attribute unsigned short systemCode;
-};
diff --git a/src/cobalt/dom/media_key_message_event.cc b/src/cobalt/dom/media_key_message_event.cc
deleted file mode 100644
index c692af5..0000000
--- a/src/cobalt/dom/media_key_message_event.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/media_key_message_event.h"
-
-#include "cobalt/base/tokens.h"
-
-namespace cobalt {
-namespace dom {
-
-MediaKeyMessageEvent::MediaKeyMessageEvent(
-    const std::string& key_system, const std::string& session_id,
-    const script::Handle<script::Uint8Array>& message,
-    const std::string& default_url)
-    : Event(base::Tokens::keymessage(), kNotBubbles, kNotCancelable),
-      key_system_(key_system),
-      session_id_(session_id),
-      default_url_(default_url),
-      message_reference_(this, message) {}
-
-}  // namespace dom
-}  // namespace cobalt
diff --git a/src/cobalt/dom/media_key_message_event.h b/src/cobalt/dom/media_key_message_event.h
deleted file mode 100644
index 7b5f2d3..0000000
--- a/src/cobalt/dom/media_key_message_event.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_MEDIA_KEY_MESSAGE_EVENT_H_
-#define COBALT_DOM_MEDIA_KEY_MESSAGE_EVENT_H_
-
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "cobalt/dom/event.h"
-#include "cobalt/script/typed_arrays.h"
-#include "cobalt/script/wrappable.h"
-
-namespace cobalt {
-namespace dom {
-
-// The MediaKeyMessageEvent indicates that a message has been generated (and
-// likely needs to be sent to a key server).
-//   https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
-class MediaKeyMessageEvent : public Event {
- public:
-  MediaKeyMessageEvent(const std::string& key_system,
-                       const std::string& session_id,
-                       const script::Handle<script::Uint8Array>& message,
-                       const std::string& default_url);
-
-  const std::string& key_system() const { return key_system_; }
-  const std::string& session_id() const { return session_id_; }
-  const script::Handle<script::Uint8Array> message() const {
-    return script::Handle<script::Uint8Array>(message_reference_);
-  }
-  const std::string& default_url() const { return default_url_; }
-
-  DEFINE_WRAPPABLE_TYPE(MediaKeyMessageEvent);
-
- private:
-  std::string key_system_;
-  std::string session_id_;
-  std::string default_url_;
-  script::ScriptValue<script::Uint8Array>::Reference message_reference_;
-};
-
-}  // namespace dom
-}  // namespace cobalt
-
-#endif  // COBALT_DOM_MEDIA_KEY_MESSAGE_EVENT_H_
diff --git a/src/cobalt/dom/media_key_message_event.idl b/src/cobalt/dom/media_key_message_event.idl
deleted file mode 100644
index 77ec765..0000000
--- a/src/cobalt/dom/media_key_message_event.idl
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeymessageevent
-
-interface MediaKeyMessageEvent : Event {
-  readonly attribute DOMString keySystem;
-  readonly attribute DOMString sessionId;
-  readonly attribute Uint8Array message;
-  readonly attribute DOMString defaultURL;
-};
diff --git a/src/cobalt/dom/media_key_needed_event.cc b/src/cobalt/dom/media_key_needed_event.cc
deleted file mode 100644
index 4043b25..0000000
--- a/src/cobalt/dom/media_key_needed_event.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "cobalt/dom/media_key_needed_event.h"
-
-#include "cobalt/base/tokens.h"
-
-namespace cobalt {
-namespace dom {
-
-MediaKeyNeededEvent::MediaKeyNeededEvent(
-    const std::string& key_system, const std::string& session_id,
-    const script::Handle<script::Uint8Array>& init_data)
-    : Event(base::Tokens::needkey(), kNotBubbles, kNotCancelable),
-      key_system_(key_system),
-      session_id_(session_id),
-      init_data_reference_(this, init_data) {}
-
-}  // namespace dom
-}  // namespace cobalt
diff --git a/src/cobalt/dom/media_key_needed_event.h b/src/cobalt/dom/media_key_needed_event.h
deleted file mode 100644
index 61a4c4c..0000000
--- a/src/cobalt/dom/media_key_needed_event.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_DOM_MEDIA_KEY_NEEDED_EVENT_H_
-#define COBALT_DOM_MEDIA_KEY_NEEDED_EVENT_H_
-
-#include <string>
-
-#include "base/memory/ref_counted.h"
-#include "cobalt/dom/event.h"
-#include "cobalt/script/typed_arrays.h"
-#include "cobalt/script/wrappable.h"
-
-namespace cobalt {
-namespace dom {
-
-// The MediaKeyNeededEvent indicates that the user agent needs a key or license
-// to begin or continue playback.
-//   https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
-class MediaKeyNeededEvent : public Event {
- public:
-  MediaKeyNeededEvent(const std::string& key_system,
-                      const std::string& session_id,
-                      const script::Handle<script::Uint8Array>& init_data);
-
-  const std::string& key_system() const { return key_system_; }
-  const std::string& session_id() const { return session_id_; }
-  script::Handle<script::Uint8Array> init_data() const {
-    return script::Handle<script::Uint8Array>(init_data_reference_);
-  }
-
-  DEFINE_WRAPPABLE_TYPE(MediaKeyNeededEvent);
-
- private:
-  std::string key_system_;
-  std::string session_id_;
-  script::ScriptValue<script::Uint8Array>::Reference init_data_reference_;
-};
-
-}  // namespace dom
-}  // namespace cobalt
-
-#endif  // COBALT_DOM_MEDIA_KEY_NEEDED_EVENT_H_
diff --git a/src/cobalt/dom/media_key_needed_event.idl b/src/cobalt/dom/media_key_needed_event.idl
deleted file mode 100644
index 7a2af97..0000000
--- a/src/cobalt/dom/media_key_needed_event.idl
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// https://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#dom-mediakeyneededevent
-
-interface MediaKeyNeededEvent : Event {
-  readonly attribute DOMString keySystem;
-  readonly attribute DOMString sessionId;
-  readonly attribute Uint8Array initData;
-};
diff --git a/src/cobalt/dom/media_source.cc b/src/cobalt/dom/media_source.cc
index 57817f4..a970978 100644
--- a/src/cobalt/dom/media_source.cc
+++ b/src/cobalt/dom/media_source.cc
@@ -45,6 +45,7 @@
 #include "cobalt/dom/media_source.h"
 
 #include <algorithm>
+#include <cmath>
 #include <limits>
 #include <vector>
 
@@ -56,7 +57,6 @@
 #include "cobalt/dom/dom_settings.h"
 #include "cobalt/dom/event.h"
 #include "cobalt/media/base/pipeline_status.h"
-#include "starboard/double.h"
 #include "starboard/media.h"
 
 namespace cobalt {
@@ -99,7 +99,7 @@
 
 void MediaSource::set_duration(double duration,
                                script::ExceptionState* exception_state) {
-  if (duration < 0.0 || SbDoubleIsNan(duration)) {
+  if (duration < 0.0 || std::isnan(duration)) {
     DOMException::Raise(DOMException::kIndexSizeErr, exception_state);
     return;
   }
diff --git a/src/cobalt/dom/mutation_observer_test.cc b/src/cobalt/dom/mutation_observer_test.cc
index 23991d4..9b10a55 100644
--- a/src/cobalt/dom/mutation_observer_test.cc
+++ b/src/cobalt/dom/mutation_observer_test.cc
@@ -272,7 +272,7 @@
   records = observer->TakeRecords();
   EXPECT_TRUE(records.empty());
 
-  // Queue another mutation record on the same ovserver.
+  // Queue another mutation record on the same observer.
   record = MutationRecord::CreateAttributeMutationRecord(
       target, "attribute_name", std::string("old_attribute_data"));
   EXPECT_CALL(*debugger_hooks(), AsyncTaskScheduled(_, "attributes", kOneshot))
@@ -363,7 +363,7 @@
   reporter.ReportAttributesMutation("apple", std::string("wormy"));
   reporter.ReportAttributesMutation("potato", std::string("mashed"));
 
-  // Check that mutation records for the filtered attrbiutes have been queued.
+  // Check that mutation records for the filtered attributes have been queued.
   EXPECT_CALL(*debugger_hooks(), AsyncTaskCanceled(async_task_1));
   EXPECT_CALL(*debugger_hooks(), AsyncTaskCanceled(async_task_2));
   MutationObserver::MutationRecordSequence records = observer->TakeRecords();
diff --git a/src/cobalt/dom/mutation_record.h b/src/cobalt/dom/mutation_record.h
index f1dd75c..27d09d9 100644
--- a/src/cobalt/dom/mutation_record.h
+++ b/src/cobalt/dom/mutation_record.h
@@ -28,7 +28,7 @@
 class NodeList;
 
 // MutationRecords are used with the MutationObserver interface to describe a
-// mutation on the documnet.
+// mutation on the document.
 // https://www.w3.org/TR/dom/#mutationrecord
 class MutationRecord : public script::Wrappable {
  public:
diff --git a/src/cobalt/dom/node.cc b/src/cobalt/dom/node.cc
index 0982fae..7df763a 100644
--- a/src/cobalt/dom/node.cc
+++ b/src/cobalt/dom/node.cc
@@ -39,13 +39,13 @@
 #include "cobalt/dom/rule_matching.h"
 #include "cobalt/dom/text.h"
 #include "cobalt/dom/window.h"
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/configuration.h"
 #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
 #define HANDLE_CORE_DUMP
 #include STARBOARD_CORE_DUMP_HANDLER_INCLUDE
 #endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
 
 namespace cobalt {
 namespace dom {
diff --git a/src/cobalt/dom/node.h b/src/cobalt/dom/node.h
index e48ce39..92c5a23 100644
--- a/src/cobalt/dom/node.h
+++ b/src/cobalt/dom/node.h
@@ -226,7 +226,7 @@
   virtual scoped_refptr<Node> Duplicate() const = 0;
 
   // Purges all cached resource reference from the current node and all
-  // descendents.
+  // descendants.
   void PurgeCachedResourceReferencesRecursively();
 
   bool RegisterMutationObserver(const scoped_refptr<MutationObserver>& observer,
@@ -305,8 +305,8 @@
   scoped_refptr<Node> PreRemove(const scoped_refptr<Node>& child);
   void Remove(const scoped_refptr<Node>& node, bool suppress_observers);
 
-  // Called everytime mutation happens, i.e. when a child is inserted or removed
-  // from this node.
+  // Called every time mutation happens, i.e. when a child is inserted or
+  // removed from this node.
   virtual void OnMutation() {}
 
   // Weak reference to the node document.
diff --git a/src/cobalt/dom/parser.h b/src/cobalt/dom/parser.h
index eaf17ae..8af8f80 100644
--- a/src/cobalt/dom/parser.h
+++ b/src/cobalt/dom/parser.h
@@ -35,8 +35,8 @@
 // be able to parse a piece of HTML or XML input. If the input is a full
 // document then a corresponding Document or XMLDocument should be created, and
 // new nodes are inserted under the document. Otherwise the new nodes are
-// inserted in the given document under parent_node, before referece_node, using
-// the Web API insertBefore().
+// inserted in the given document under parent_node, before reference_node,
+// using the Web API insertBefore().
 //
 // This class is not a part of any specification.
 class Parser {
diff --git a/src/cobalt/dom/performance.h b/src/cobalt/dom/performance.h
index 31da829..b717a94 100644
--- a/src/cobalt/dom/performance.h
+++ b/src/cobalt/dom/performance.h
@@ -29,6 +29,12 @@
 //   https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/NavigationTiming/Overview.html#sec-window.performance-attribute
 class Performance : public script::Wrappable {
  public:
+  // Ensure that the timer resolution is at the lowest 20 microseconds in
+  // order to mitigate potential Spectre-related attacks.  This is following
+  // Mozilla's lead as described here:
+  //   https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/
+  static constexpr int64_t kPerformanceTimerMinResolutionInMicroseconds = 20;
+
   explicit Performance(const scoped_refptr<base::BasicClock>& clock);
 
   // Web API: Performance
diff --git a/src/cobalt/dom/performance_entry.cc b/src/cobalt/dom/performance_entry.cc
new file mode 100644
index 0000000..d34b2fd
--- /dev/null
+++ b/src/cobalt/dom/performance_entry.cc
@@ -0,0 +1,59 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "performance_entry.h"
+
+#include "base/atomic_sequence_num.h"
+
+namespace cobalt {
+namespace dom {
+
+namespace {
+static base::AtomicSequenceNumber index_seq;
+}
+
+PerformanceEntry::PerformanceEntry(const std::string& name,
+                                   DOMHighResTimeStamp start_time,
+                                   DOMHighResTimeStamp finish_time)
+    : duration_(finish_time - start_time),
+    name_(name),
+    start_time_(start_time),
+    index_(index_seq.GetNext()) {}
+
+DOMHighResTimeStamp PerformanceEntry::start_time() const {
+  return start_time_;
+}
+
+DOMHighResTimeStamp PerformanceEntry::duration() const {
+  return duration_;
+}
+
+PerformanceEntry::EntryType PerformanceEntry::ToEntryTypeEnum(
+    const std::string& entry_type) {
+  if (entry_type == "resource")
+    return kResource;
+  if (entry_type == "navigation")
+    return kNavigation;
+  return kInvalid;
+}
+
+bool PerformanceEntry::StartTimeCompareLessThan(
+    PerformanceEntry* a, PerformanceEntry* b) {
+  if (a->start_time() == b->start_time())
+    return a->index_ < b->index_;
+  return a->start_time() < b->start_time();
+}
+
+}  // namespace dom
+}  // namespace cobalt
diff --git a/src/cobalt/dom/performance_entry.h b/src/cobalt/dom/performance_entry.h
new file mode 100644
index 0000000..850fe5d
--- /dev/null
+++ b/src/cobalt/dom/performance_entry.h
@@ -0,0 +1,75 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_PERFORMANCE_ENTRY_H_
+#define COBALT_DOM_PERFORMANCE_ENTRY_H_
+
+#include <string>
+
+#include "cobalt/dom/performance_high_resolution_time.h"
+#include "cobalt/script/wrappable.h"
+
+namespace cobalt {
+namespace dom {
+
+typedef unsigned PerformanceEntryType;
+
+// Implements the PerformanceEntry IDL interface, as described here:
+//   https://w3c.github.io/performance-timeline/#the-performanceentry-interface
+class PerformanceEntry : public script::Wrappable {
+ public:
+  PerformanceEntry(const std::string& name,
+                   DOMHighResTimeStamp start_time,
+                   DOMHighResTimeStamp finish_time);
+
+  enum EntryType : PerformanceEntryType {
+    kInvalid = 0,
+    kResource = 1 << 0,
+    kNavigation = 1 << 1,
+  };
+
+  std::string name() const { return name_; }
+  DOMHighResTimeStamp start_time() const;
+  virtual std::string entry_type() const = 0;
+  virtual PerformanceEntryType EntryTypeEnum() const = 0;
+  // PerformanceNavigationTiming will override this function,
+  // other classes must NOT override this.
+  virtual DOMHighResTimeStamp duration() const;
+
+  static PerformanceEntry::EntryType ToEntryTypeEnum(
+      const std::string& entry_type);
+
+  static bool StartTimeCompareLessThan(PerformanceEntry* a,
+                                       PerformanceEntry* b);
+
+  DEFINE_WRAPPABLE_TYPE(PerformanceEntry);
+
+  ~PerformanceEntry() {}
+
+ protected:
+  // PerformanceEventTiming needs to modify it.
+  DOMHighResTimeStamp duration_;
+
+ private:
+  const std::string name_;
+  const DOMHighResTimeStamp start_time_;
+  const int index_;
+
+  DISALLOW_COPY_AND_ASSIGN(PerformanceEntry);
+};
+
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_PERFORMANCE_ENTRY_H_
diff --git a/src/cobalt/dom/performance_entry.idl b/src/cobalt/dom/performance_entry.idl
new file mode 100644
index 0000000..e7de81f
--- /dev/null
+++ b/src/cobalt/dom/performance_entry.idl
@@ -0,0 +1,23 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://w3c.github.io/performance-timeline/#the-performanceentry-interface
+
+[Exposed=Window]
+interface PerformanceEntry {
+  readonly attribute DOMString name;
+  readonly attribute DOMString entryType;
+  readonly attribute DOMHighResTimeStamp startTime;
+  readonly attribute DOMHighResTimeStamp duration;
+};
diff --git a/src/cobalt/dom/performance_entry_list.idl b/src/cobalt/dom/performance_entry_list.idl
new file mode 100644
index 0000000..f8e6671
--- /dev/null
+++ b/src/cobalt/dom/performance_entry_list.idl
@@ -0,0 +1,22 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://w3c.github.io/performance-timeline/#extensions-to-the-performance-interface
+
+partial interface Performance {
+  PerformanceEntryList getEntries();
+  PerformanceEntryList getEntriesByType(DOMString type);
+  PerformanceEntryList getEntriesByName(DOMString name, optional DOMString type);
+}
+typedef sequence<PerformanceEntry> PerformanceEntryList;
diff --git a/src/cobalt/dom/performance_high_resolution_time.h b/src/cobalt/dom/performance_high_resolution_time.h
new file mode 100644
index 0000000..3246964
--- /dev/null
+++ b/src/cobalt/dom/performance_high_resolution_time.h
@@ -0,0 +1,63 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_DOM_PERFORMANCE_HIGH_RESOLUTION_TIME_H_
+#define COBALT_DOM_PERFORMANCE_HIGH_RESOLUTION_TIME_H_
+
+#include "base/time/time.h"
+
+namespace cobalt {
+namespace dom {
+
+// The definition of DOMHighResTimeStamp.
+//   https://w3c.github.io/hr-time/#dom-domhighrestimestamp
+typedef double DOMHighResTimeStamp;
+
+// Time converstion helper functions.
+inline DOMHighResTimeStamp ConvertSecondsToDOMHighResTimeStamp(double seconds) {
+  return static_cast<DOMHighResTimeStamp>(seconds * 1000.0);
+}
+
+inline double ConvertDOMHighResTimeStampToSeconds(
+    DOMHighResTimeStamp milliseconds) {
+  return milliseconds / 1000.0;
+}
+
+inline DOMHighResTimeStamp ConvertTimeTicksToDOMHighResTimeStamp(
+    base::TimeTicks time) {
+  return (time - base::TimeTicks()).InMillisecondsF();
+}
+
+// Clamp customized minimum clock resolution.
+//   https://w3c.github.io/hr-time/#clock-resolution
+inline base::TimeDelta ClampTimeStampMinimumResolution(base::TimeDelta delta,
+    int64_t min_resolution_in_microseconds) {
+    int64_t microseconds = delta.InMicroseconds();
+    return base::TimeDelta::FromMicroseconds(microseconds -
+        (microseconds % min_resolution_in_microseconds));
+}
+
+// Clamp customized minimum clock resolution and convet TimeDelta
+// to DOMHighResTimeStamp.
+inline DOMHighResTimeStamp ConvertTimeDeltaToDOMHighResTimeStamp(
+    base::TimeDelta delta, int64_t min_resolution_in_microseconds) {
+  base::TimeDelta clamp_delta =
+      ClampTimeStampMinimumResolution(delta, min_resolution_in_microseconds);
+  return clamp_delta.InMillisecondsF();
+}
+
+}  // namespace dom
+}  // namespace cobalt
+
+#endif  // COBALT_DOM_PERFORMANCE_HIGH_RESOLUTION_TIME_H_
diff --git a/src/cobalt/dom/performance__high_resolution_time.idl b/src/cobalt/dom/performance_high_resolution_time.idl
similarity index 100%
rename from src/cobalt/dom/performance__high_resolution_time.idl
rename to src/cobalt/dom/performance_high_resolution_time.idl
diff --git a/src/cobalt/dom/performance_observer.idl b/src/cobalt/dom/performance_observer.idl
new file mode 100644
index 0000000..e77af66
--- /dev/null
+++ b/src/cobalt/dom/performance_observer.idl
@@ -0,0 +1,28 @@
+// Copyright 2015 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://www.w3.org/TR/performance-timeline/#the-performanceobserver-interface
+
+callback PerformanceObserverCallback = void (PerformanceObserverEntryList entries,
+                                             PerformanceObserver observer);
+[Exposed=Window]
+interface PerformanceObserver {
+  constructor(PerformanceObserverCallback callback);
+  void observe (optional PerformanceObserverInit options = {});
+  void disconnect ();
+  PerformanceEntryList takeRecords();
+  // TODO: make this be FrozenArray<DOMString> when available
+  [SameObject] static readonly attribute sequence<DOMString> supportedEntryTypes;
+};
+
diff --git a/src/cobalt/dom/performance_observer_init.idl b/src/cobalt/dom/performance_observer_init.idl
new file mode 100644
index 0000000..db03cc9
--- /dev/null
+++ b/src/cobalt/dom/performance_observer_init.idl
@@ -0,0 +1,20 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// https://www.w3.org/TR/performance-timeline/#performanceobserverinit-dictionary
+
+dictionary PerformanceObserverInit {
+  sequence<DOMString> entryTypes;
+  DOMString type;
+};
diff --git a/src/cobalt/dom/serializer.cc b/src/cobalt/dom/serializer.cc
index 518cec8..2388382 100644
--- a/src/cobalt/dom/serializer.cc
+++ b/src/cobalt/dom/serializer.cc
@@ -33,8 +33,8 @@
 
 const char kStyleAttributeName[] = "style";
 
-void WriteAtttributes(const scoped_refptr<const Element>& element,
-                      std::ostream* out_stream) {
+void WriteAttributes(const scoped_refptr<const Element>& element,
+                     std::ostream* out_stream) {
   const Element::AttributeMap& attributes = element->attribute_map();
   typedef std::map<std::string, std::string> SortedAttributeMap;
   SortedAttributeMap sorted_attribute_map;
@@ -112,8 +112,7 @@
   }
 }
 
-void Serializer::Visit(const Document* document) {
-}
+void Serializer::Visit(const Document* document) {}
 
 void Serializer::Visit(const DocumentType* document_type) {
   if (entering_node_) {
@@ -124,7 +123,7 @@
 void Serializer::Visit(const Element* element) {
   if (entering_node_) {
     *out_stream_ << "<" << element->local_name();
-    WriteAtttributes(element, out_stream_);
+    WriteAttributes(element, out_stream_);
     *out_stream_ << ">";
   } else {
     *out_stream_ << "</" << element->local_name() << ">";
diff --git a/src/cobalt/dom/testing/mock_layout_boxes.h b/src/cobalt/dom/testing/mock_layout_boxes.h
index 2451961..7065808 100644
--- a/src/cobalt/dom/testing/mock_layout_boxes.h
+++ b/src/cobalt/dom/testing/mock_layout_boxes.h
@@ -57,6 +57,8 @@
   MOCK_METHOD0(InvalidateSizes, void());
   MOCK_METHOD0(InvalidateCrossReferences, void());
   MOCK_METHOD0(InvalidateRenderTreeNodes, void());
+  MOCK_METHOD1(SetUiNavItem,
+               void(const scoped_refptr<ui_navigation::NavItem>& item));
 };
 }  // namespace testing
 }  // namespace dom
diff --git a/src/cobalt/dom/window.cc b/src/cobalt/dom/window.cc
index 2ee9432..c349bf0 100644
--- a/src/cobalt/dom/window.cc
+++ b/src/cobalt/dom/window.cc
@@ -82,14 +82,6 @@
   DISALLOW_COPY_AND_ASSIGN(RelayLoadEvent);
 };
 
-namespace {
-// Ensure that the timer resolution is at the lowest 20 microseconds in
-// order to mitigate potential Spectre-related attacks.  This is following
-// Mozilla's lead as described here:
-//   https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/
-const int64_t kPerformanceTimerMinResolutionInMicroseconds = 20;
-}  // namespace
-
 Window::Window(
     script::EnvironmentSettings* settings, const ViewportSize& view_size,
     base::ApplicationState initial_application_state,
@@ -246,7 +238,7 @@
       return new base::MinimumResolutionClock(
           new base::SystemMonotonicClock(),
           base::TimeDelta::FromMicroseconds(
-              kPerformanceTimerMinResolutionInMicroseconds));
+              Performance::kPerformanceTimerMinResolutionInMicroseconds));
     } break;
   }
   NOTREACHED();
diff --git a/src/cobalt/dom/window_timers.h b/src/cobalt/dom/window_timers.h
index 73bec1f..5d4442b 100644
--- a/src/cobalt/dom/window_timers.h
+++ b/src/cobalt/dom/window_timers.h
@@ -75,7 +75,7 @@
   };
   typedef base::hash_map<int, scoped_refptr<TimerInfo> > Timers;
 
-  // Returns a positive interger timer handle that hasn't been assigned, or 0
+  // Returns a positive integer timer handle that hasn't been assigned, or 0
   // if none can be found.
   int GetFreeTimerHandle();
 
diff --git a/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
index 7010199..e512c71 100644
--- a/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_html_parser_wrapper.cc
@@ -132,7 +132,7 @@
     // element and before the head element, will be dropped when the document is
     // parsed. ASCII whitespace after the html element will be parsed as if it
     // were at the end of the body element. Set option XML_PARSE_NOBLANKS to
-    // omit those non signaficant whitespaces.
+    // omit those non significant whitespaces.
     htmlCtxtUseOptions(html_parser_context_, XML_PARSE_NOBLANKS);
 
     if (!html_parser_context_) {
diff --git a/src/cobalt/dom_parser/libxml_parser_wrapper.cc b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
index d33f8ca..d1a6ec1 100644
--- a/src/cobalt/dom_parser/libxml_parser_wrapper.cc
+++ b/src/cobalt/dom_parser/libxml_parser_wrapper.cc
@@ -28,14 +28,14 @@
 #include "cobalt/dom/comment.h"
 #include "cobalt/dom/element.h"
 #include "cobalt/dom/text.h"
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/configuration.h"
 #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
 #define HANDLE_CORE_DUMP
 #include "base/lazy_instance.h"
 #include STARBOARD_CORE_DUMP_HANDLER_INCLUDE
 #endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
 #include "third_party/libxml/src/include/libxml/xmlerror.h"
 
 namespace cobalt {
diff --git a/src/cobalt/extension/crash_handler.h b/src/cobalt/extension/crash_handler.h
new file mode 100644
index 0000000..8cf4732
--- /dev/null
+++ b/src/cobalt/extension/crash_handler.h
@@ -0,0 +1,47 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_EXTENSION_CRASH_HANDLER_H_
+#define COBALT_EXTENSION_CRASH_HANDLER_H_
+
+#include <stdint.h>
+
+#include "starboard/configuration.h"
+#include "third_party/crashpad/wrapper/annotations.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionCrashHandlerName "dev.cobalt.extension.CrashHandler"
+
+typedef struct CobaltExtensionCrashHandlerApi {
+  // Name should be the string |kCobaltExtensionCrashHandlerName|.
+  // This helps to validate that the extension API is correct.
+  const char* name;
+
+  // This specifies the version of the API that is implemented.
+  uint32_t version;
+
+  // The fields below this point were added in version 1 or later.
+
+  bool (*OverrideCrashpadAnnotations)(
+      CrashpadAnnotations* crashpad_annotations);
+} CobaltExtensionCrashHandlerApi;
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // COBALT_EXTENSION_CRASH_HANDLER_H_
diff --git a/src/cobalt/extension/cwrappers.h b/src/cobalt/extension/cwrappers.h
new file mode 100644
index 0000000..604110c
--- /dev/null
+++ b/src/cobalt/extension/cwrappers.h
@@ -0,0 +1,45 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_EXTENSION_CWRAPPERS_H_
+#define COBALT_EXTENSION_CWRAPPERS_H_
+
+#include <stdint.h>
+
+#include "starboard/configuration.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define kCobaltExtensionCWrappersName "dev.cobalt.extension.CWrappers"
+
+typedef struct CobaltExtensionCWrappersApi {
+  // Name should be the string kCobaltExtensionCWrapperName.
+  // This helps to validate that the extension API is correct.
+  const char* name;
+
+  // This specifies the version of the API that is implemented.
+  uint32_t version;
+
+  // The fields below this point were added in version 1 or later.
+
+  double (*PowWrapper)(double base, double exponent);
+} CobaltExtensionCWrappersApi;
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // COBALT_EXTENSION_CWRAPPERS_H_
diff --git a/src/cobalt/extension/extension_test.cc b/src/cobalt/extension/extension_test.cc
index d92acd1..3d1c30e 100644
--- a/src/cobalt/extension/extension_test.cc
+++ b/src/cobalt/extension/extension_test.cc
@@ -15,6 +15,8 @@
 #include <cmath>
 
 #include "cobalt/extension/configuration.h"
+#include "cobalt/extension/crash_handler.h"
+#include "cobalt/extension/cwrappers.h"
 #include "cobalt/extension/graphics.h"
 #include "cobalt/extension/installation_manager.h"
 #include "cobalt/extension/media_session.h"
@@ -193,6 +195,46 @@
   EXPECT_EQ(second_extension_api, extension_api)
       << "Extension struct should be a singleton";
 }
+
+TEST(ExtensionTest, CrashHandler) {
+  typedef CobaltExtensionCrashHandlerApi ExtensionApi;
+  const char* kExtensionName = kCobaltExtensionCrashHandlerName;
+
+  const ExtensionApi* extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  if (!extension_api) {
+    return;
+  }
+
+  EXPECT_STREQ(extension_api->name, kExtensionName);
+  EXPECT_EQ(extension_api->version, 1u);
+  EXPECT_NE(extension_api->OverrideCrashpadAnnotations, nullptr);
+
+  const ExtensionApi* second_extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  EXPECT_EQ(second_extension_api, extension_api)
+      << "Extension struct should be a singleton";
+}
+
+TEST(ExtensionTest, CWrappers) {
+  typedef CobaltExtensionCWrappersApi ExtensionApi;
+  const char* kExtensionName = kCobaltExtensionCWrappersName;
+
+  const ExtensionApi* extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  if (!extension_api) {
+    return;
+  }
+
+  EXPECT_STREQ(extension_api->name, kExtensionName);
+  EXPECT_EQ(extension_api->version, 1u);
+  EXPECT_NE(extension_api->PowWrapper, nullptr);
+
+  const ExtensionApi* second_extension_api =
+      static_cast<const ExtensionApi*>(SbSystemGetExtension(kExtensionName));
+  EXPECT_EQ(second_extension_api, extension_api)
+      << "Extension struct should be a singleton";
+}
 }  // namespace extension
 }  // namespace cobalt
 #endif  // SB_API_VERSION >= 11
diff --git a/src/cobalt/extension/media_session.h b/src/cobalt/extension/media_session.h
index 91ab5b2..38d3322 100644
--- a/src/cobalt/extension/media_session.h
+++ b/src/cobalt/extension/media_session.h
@@ -15,7 +15,6 @@
 #ifndef COBALT_EXTENSION_MEDIA_SESSION_H_
 #define COBALT_EXTENSION_MEDIA_SESSION_H_
 
-
 #include "starboard/configuration.h"
 #include "starboard/time.h"
 
@@ -113,9 +112,13 @@
       CobaltExtensionMediaSessionUpdatePlatformPlaybackStateCallback
           update_platform_playback_state_callback);
 
-  // Destory platform's MediaSessionClient after the Cobalt's
+  // Destroy platform's MediaSessionClient after the Cobalt's
   // MediaSessionClient has been destroyed.
   void (*DestroyMediaSessionClientCallback)();
+
+  // Starboard method for updating playback state.
+  void (*UpdateActiveSessionPlatformPlaybackState)(
+      CobaltExtensionMediaSessionPlaybackState state);
 } CobaltExtensionMediaSessionApi;
 
 inline void CobaltExtensionMediaSessionActionDetailsInit(
diff --git a/src/cobalt/h5vcc/dial/dial_server.cc b/src/cobalt/h5vcc/dial/dial_server.cc
index d90f5dd..5764b88 100644
--- a/src/cobalt/h5vcc/dial/dial_server.cc
+++ b/src/cobalt/h5vcc/dial/dial_server.cc
@@ -48,7 +48,7 @@
 class DialServer::ServiceHandler : public net::DialServiceHandler {
  public:
   ServiceHandler(const base::WeakPtr<DialServer>& dial_server,
-                 const std::string& sevice_name);
+                 const std::string& service_name);
 
   // net::DialServiceHandler implementation.
   const std::string& service_name() const override { return service_name_; }
diff --git a/src/cobalt/input/camera_3d.h b/src/cobalt/input/camera_3d.h
index 1d213f7..d282e4d 100644
--- a/src/cobalt/input/camera_3d.h
+++ b/src/cobalt/input/camera_3d.h
@@ -27,7 +27,7 @@
 
 // Obtains camera parameters from hardware input to render a 3D scene.
 // Interface to the Web module and Renderer module. Some settings may not apply
-// depending on the specfic hardware implementation, so their setter methods
+// depending on the specific hardware implementation, so their setter methods
 // have empty default implementations.
 class Camera3D : public base::RefCountedThreadSafe<Camera3D> {
  public:
@@ -44,10 +44,8 @@
 
   // Functions to map input keys to camera controls.
   virtual void CreateKeyMapping(int keycode, uint32 camera_axis,
-                                float degrees_per_second) {
-  }
-  virtual void ClearKeyMapping(int keycode) {
-  }
+                                float degrees_per_second) {}
+  virtual void ClearKeyMapping(int keycode) {}
   virtual void ClearAllKeyMappings() {}
 
   // Return the camera's current view direction.
@@ -61,8 +59,7 @@
 
   // Updates the camera's perspective parameters.
   virtual void UpdatePerspective(float width_to_height_aspect_ratio,
-                                 float vertical_fov) {
-  }
+                                 float vertical_fov) {}
 
   // Returns the camera's view and projection matrices, setup according to the
   // latest available orientation and perspective information. This queries the
diff --git a/src/cobalt/input/key_event_handler.h b/src/cobalt/input/key_event_handler.h
index 39f303b..c873762 100644
--- a/src/cobalt/input/key_event_handler.h
+++ b/src/cobalt/input/key_event_handler.h
@@ -26,7 +26,7 @@
     KeyboardEventCallback;
 
 // Base class for objects that can process keyboard events.
-// This includes input device manangers and key event filters.
+// This includes input device managers and key event filters.
 // Objects of this class can either handle the key event directly using the
 // callback provided at construction, or pass the event on to a filter.
 // This allows filters to be chained together to implement the combined
diff --git a/src/cobalt/layout/block_formatting_block_container_box.cc b/src/cobalt/layout/block_formatting_block_container_box.cc
index 676c3b4..cf45f33 100644
--- a/src/cobalt/layout/block_formatting_block_container_box.cc
+++ b/src/cobalt/layout/block_formatting_block_container_box.cc
@@ -66,27 +66,27 @@
   // Only collapse in-flow, block-level boxes. Do not collapse root element and
   // the initial containing block. Do not collapse boxes with overflow not equal
   // to 'visible', because these create new formatting contexts.
-  bool is_collapsable =
+  bool is_collapsible =
       !IsAbsolutelyPositioned() && GetLevel() == Box::kBlockLevel && parent() &&
       parent()->parent() && !IsOverflowCropped(computed_style());
 
   // Margins should only collapse if no padding or border separate them.
   //   https://www.w3.org/TR/CSS22/box.html#collapsing-margins
-  bool top_margin_is_collapsable = is_collapsable &&
+  bool top_margin_is_collapsible = is_collapsible &&
                                    padding_top() == LayoutUnit() &&
                                    border_top_width() == LayoutUnit();
   // Lay out child boxes in the normal flow.
   //   https://www.w3.org/TR/CSS21/visuren.html#normal-flow
   std::unique_ptr<BlockFormattingContext> block_formatting_context(
       new BlockFormattingContext(child_layout_params,
-                                 top_margin_is_collapsable));
+                                 top_margin_is_collapsible));
   for (Boxes::const_iterator child_box_iterator = child_boxes().begin();
        child_box_iterator != child_boxes().end(); ++child_box_iterator) {
     Box* child_box = *child_box_iterator;
     block_formatting_context->UpdateRect(child_box);
   }
 
-  if (is_collapsable) {
+  if (is_collapsible) {
     block_formatting_context->CollapseContainingMargins(this);
   }
 
diff --git a/src/cobalt/layout/block_formatting_context.cc b/src/cobalt/layout/block_formatting_context.cc
index 33b8510..7508de5 100644
--- a/src/cobalt/layout/block_formatting_context.cc
+++ b/src/cobalt/layout/block_formatting_context.cc
@@ -23,9 +23,9 @@
 namespace layout {
 
 BlockFormattingContext::BlockFormattingContext(
-    const LayoutParams& layout_params, const bool is_margin_collapsable)
+    const LayoutParams& layout_params, const bool is_margin_collapsible)
     : layout_params_(layout_params),
-      margin_collapsing_params_(MarginCollapsingParams(is_margin_collapsable)) {
+      margin_collapsing_params_(MarginCollapsingParams(is_margin_collapsible)) {
 }
 
 BlockFormattingContext::~BlockFormattingContext() {}
diff --git a/src/cobalt/layout/block_formatting_context.h b/src/cobalt/layout/block_formatting_context.h
index 2096453..704c874 100644
--- a/src/cobalt/layout/block_formatting_context.h
+++ b/src/cobalt/layout/block_formatting_context.h
@@ -25,11 +25,11 @@
 namespace layout {
 
 struct MarginCollapsingParams {
-  MarginCollapsingParams(const bool is_margin_collapsable)
+  MarginCollapsingParams(const bool is_margin_collapsible)
       : collapsing_margin(0),
         should_collapse_own_margins_together(true),
         should_collapse_margin_bottom(true),
-        should_collapse_margin_top(is_margin_collapsable) {}
+        should_collapse_margin_top(is_margin_collapsible) {}
 
   LayoutUnit collapsing_margin;
   base::Optional<LayoutUnit> context_margin_top;
@@ -50,7 +50,7 @@
 class BlockFormattingContext : public FormattingContext {
  public:
   explicit BlockFormattingContext(const LayoutParams& layout_params,
-                                  const bool is_margin_collapsable);
+                                  const bool is_margin_collapsible);
   ~BlockFormattingContext() override;
 
   // Updates the top and bottom margins of the containing box after children
diff --git a/src/cobalt/layout/box.cc b/src/cobalt/layout/box.cc
index 9d68134..f09e19b 100644
--- a/src/cobalt/layout/box.cc
+++ b/src/cobalt/layout/box.cc
@@ -223,29 +223,15 @@
              : InsetsLayoutUnit();
 }
 
-RectLayoutUnit Box::GetTransformedBoxFromRoot(
-    const RectLayoutUnit& box_from_margin_box) const {
-  return GetTransformedBoxFromContainingBlock(nullptr, box_from_margin_box);
-}
-
-RectLayoutUnit Box::GetTransformedBoxFromContainingBlock(
-    const ContainerBox* containing_block,
-    const RectLayoutUnit& box_from_margin_box) const {
-  // Get the transform for the margin box from the containing block and
-  // add the box offset from the margin box to the beginning of the transform.
-  math::Matrix3F transform =
-      GetMarginBoxTransformFromContainingBlock(containing_block) *
-      math::TranslateMatrix(box_from_margin_box.x().toFloat(),
-                            box_from_margin_box.y().toFloat());
-
-  // Transform the box.
+namespace {
+RectLayoutUnit GetTransformedBox(const math::Matrix3F& transform,
+                                 const RectLayoutUnit& box) {
   const int kNumPoints = 4;
   math::PointF box_corners[kNumPoints] = {
-      {0.0f, 0.0f},
-      {box_from_margin_box.width().toFloat(), 0.0f},
-      {0.0f, box_from_margin_box.height().toFloat()},
-      {box_from_margin_box.width().toFloat(),
-       box_from_margin_box.height().toFloat()},
+      {box.x().toFloat(), box.y().toFloat()},
+      {box.right().toFloat(), box.y().toFloat()},
+      {box.x().toFloat(), box.bottom().toFloat()},
+      {box.right().toFloat(), box.bottom().toFloat()},
   };
 
   for (int i = 0; i < kNumPoints; ++i) {
@@ -264,6 +250,29 @@
                         LayoutUnit(max_corner.x() - min_corner.x()),
                         LayoutUnit(max_corner.y() - min_corner.y()));
 }
+}  // namespace
+
+RectLayoutUnit Box::GetTransformedBoxFromRoot(
+    const RectLayoutUnit& box_from_margin_box) const {
+  return GetTransformedBoxFromContainingBlock(nullptr, box_from_margin_box);
+}
+
+RectLayoutUnit Box::GetTransformedBoxFromRootWithScroll(
+    const RectLayoutUnit& box_from_margin_box) const {
+  // Get the transformed box from root while factoring in scrollLeft and
+  // scrollTop of intermediate containers.
+  return GetTransformedBox(
+      GetMarginBoxTransformFromContainingBlockWithScroll(nullptr),
+      box_from_margin_box);
+}
+
+RectLayoutUnit Box::GetTransformedBoxFromContainingBlock(
+    const ContainerBox* containing_block,
+    const RectLayoutUnit& box_from_margin_box) const {
+  return GetTransformedBox(
+      GetMarginBoxTransformFromContainingBlock(containing_block),
+      box_from_margin_box);
+}
 
 RectLayoutUnit Box::GetTransformedBoxFromContainingBlockContentBox(
     const ContainerBox* containing_block,
@@ -373,8 +382,8 @@
   return margin_top() + GetBorderBoxHeight() + margin_bottom();
 }
 
-math::Matrix3F Box::GetMarginBoxTransformFromContainingBlock(
-    const ContainerBox* containing_block) const {
+math::Matrix3F Box::GetMarginBoxTransformFromContainingBlockInternal(
+    const ContainerBox* containing_block, bool include_scroll) const {
   math::Matrix3F transform = math::Matrix3F::Identity();
   if (this == containing_block) {
     return transform;
@@ -421,12 +430,32 @@
                                       containing_block_offset.y().toFloat()) *
                 transform;
 
+    // Factor in the container's scrollLeft / scrollTop as needed.
+    if (include_scroll && container->ui_nav_item_ &&
+        container->ui_nav_item_->IsContainer()) {
+      float left, top;
+      container->ui_nav_item_->GetContentOffset(&left, &top);
+      transform = math::TranslateMatrix(-left, -top) * transform;
+    }
+
     box = container;
   }
 
   return transform;
 }
 
+math::Matrix3F Box::GetMarginBoxTransformFromContainingBlock(
+    const ContainerBox* containing_block) const {
+  return GetMarginBoxTransformFromContainingBlockInternal(
+      containing_block, false /* include_scroll */);
+}
+
+math::Matrix3F Box::GetMarginBoxTransformFromContainingBlockWithScroll(
+    const ContainerBox* containing_block) const {
+  return GetMarginBoxTransformFromContainingBlockInternal(
+      containing_block, true /* include_scroll */);
+}
+
 Vector2dLayoutUnit Box::GetMarginBoxOffsetFromRoot(
     bool transform_forms_root) const {
   Vector2dLayoutUnit containing_block_offset_from_root =
@@ -1994,8 +2023,10 @@
   // containing blocks.
   scoped_refptr<ui_navigation::NavItem> ui_nav_container;
   const ContainerBox* containing_block;
+  const Box* prev_containing_block = this;
   for (containing_block = GetContainingBlock(); containing_block != nullptr;
-       containing_block = containing_block->GetContainingBlock()) {
+       prev_containing_block = containing_block,
+      containing_block = containing_block->GetContainingBlock()) {
     if (containing_block->ui_nav_item_ &&
         containing_block->ui_nav_item_->IsContainer()) {
       ui_nav_container = containing_block->ui_nav_item_;
@@ -2013,11 +2044,26 @@
   ui_nav_item_->SetSize(border_box_size.width().toFloat(),
                         border_box_size.height().toFloat());
 
+  // GetMarginBoxTransformFromContainingBlock() doesn't properly handle the
+  // descendant of the containing block if it uses 'position: relative' -- it
+  // just assumes the padding box is used instead of the content box in this
+  // case. Workaround the issue here.
+  //   https://www.w3.org/TR/CSS21/visudet.html#containing-block-details
+  Vector2dLayoutUnit containing_block_offset;
+  if (containing_block) {
+    containing_block_offset =
+        prev_containing_block->GetContainingBlockOffsetFromItsContentBox(
+            containing_block) +
+        containing_block->GetContentBoxOffsetFromMarginBox();
+  }
+
   // Get the border box's transform relative to its containing item. This
   // dictates the center of the border box relative to its container.
   Vector2dLayoutUnit border_box_offset = GetBorderBoxOffsetFromMarginBox();
   math::Matrix3F transform =
       GetMarginBoxTransformFromContainingBlock(containing_block) *
+      math::TranslateMatrix(containing_block_offset.x().toFloat(),
+                            containing_block_offset.y().toFloat()) *
       math::TranslateMatrix(border_box_offset.x().toFloat() +
                                 0.5f * border_box_size.width().toFloat(),
                             border_box_offset.y().toFloat() +
diff --git a/src/cobalt/layout/box.h b/src/cobalt/layout/box.h
index 43768e3..06a2790 100644
--- a/src/cobalt/layout/box.h
+++ b/src/cobalt/layout/box.h
@@ -222,7 +222,7 @@
     return css_computed_style_declaration_->data();
   }
 
-  // The animation set specifies all currently active animations appyling
+  // The animation set specifies all currently active animations applying
   // to this box's computed_style() CSS Style Declaration.
   //   https://w3c.github.io/web-animations
   const web_animations::AnimationSet* animations() const {
@@ -280,6 +280,8 @@
   // account transforms.
   RectLayoutUnit GetTransformedBoxFromRoot(
       const RectLayoutUnit& box_from_margin_box) const;
+  RectLayoutUnit GetTransformedBoxFromRootWithScroll(
+      const RectLayoutUnit& box_from_margin_box) const;
   RectLayoutUnit GetTransformedBoxFromContainingBlock(
       const ContainerBox* containing_block,
       const RectLayoutUnit& box_from_margin_box) const;
@@ -369,6 +371,8 @@
 
   math::Matrix3F GetMarginBoxTransformFromContainingBlock(
       const ContainerBox* containing_block) const;
+  math::Matrix3F GetMarginBoxTransformFromContainingBlockWithScroll(
+      const ContainerBox* containing_block) const;
 
   Vector2dLayoutUnit GetMarginBoxOffsetFromRoot(
       bool transform_forms_root) const;
@@ -839,6 +843,11 @@
   // and background-image would populate.
   math::RectF GetBackgroundRect();
 
+  // Get the transform for this box from the specified containing block (which
+  // may be null to indicate root).
+  math::Matrix3F GetMarginBoxTransformFromContainingBlockInternal(
+      const ContainerBox* containing_block, bool include_scroll) const;
+
   // Some custom CSS transform functions require a UI navigation focus item as
   // input. This computes the appropriate UI navigation item for this box's
   // transform. This should only be called if the box IsTransformed().
diff --git a/src/cobalt/layout/container_box.cc b/src/cobalt/layout/container_box.cc
index 3951702..9bef557 100644
--- a/src/cobalt/layout/container_box.cc
+++ b/src/cobalt/layout/container_box.cc
@@ -279,8 +279,7 @@
 
 namespace {
 
-InsetsLayoutUnit
-GetOffsetFromContainingBlockToParentOfAbsolutelyPositionedBox(
+InsetsLayoutUnit GetOffsetFromContainingBlockToParentOfAbsolutelyPositionedBox(
     const ContainerBox* containing_block, Box* child_box) {
   // NOTE: Bottom inset is not computed and should not be queried.
   DCHECK(child_box->IsAbsolutelyPositioned());
@@ -307,8 +306,7 @@
   // as the containing block for 'fixed' position elements.
   offset += InsetsLayoutUnit(containing_block->padding_left(),
                              containing_block->padding_top(),
-                             containing_block->padding_right(),
-                             LayoutUnit());
+                             containing_block->padding_right(), LayoutUnit());
 
   return offset;
 }
@@ -831,7 +829,7 @@
   // Update the stacking context if this is found to be a stacking context.
   ContainerBox* this_as_stacking_context = const_cast<ContainerBox*>(this);
 
-  // Reset the draw order for this box. Even if it isn't explictly a stacking
+  // Reset the draw order for this box. Even if it isn't explicitly a stacking
   // context, it'll be used as one for in-flow, non-positioned child boxes.
   this_as_stacking_context->next_draw_order_position_ = 0;
 
diff --git a/src/cobalt/layout/flex_container_box.cc b/src/cobalt/layout/flex_container_box.cc
index 2fcd325..958fc85 100644
--- a/src/cobalt/layout/flex_container_box.cc
+++ b/src/cobalt/layout/flex_container_box.cc
@@ -15,6 +15,7 @@
 #include "cobalt/layout/flex_container_box.h"
 
 #include <algorithm>
+#include <utility>
 #include <vector>
 
 #include "cobalt/cssom/computed_style.h"
@@ -230,6 +231,11 @@
   base::Optional<LayoutUnit> maybe_margin_bottom = GetUsedMarginBottomIfNotAuto(
       computed_style(), layout_params.containing_block_size);
 
+  set_margin_left(maybe_margin_left.value_or(LayoutUnit()));
+  set_margin_right(maybe_margin_right.value_or(LayoutUnit()));
+  set_margin_top(maybe_margin_top.value_or(LayoutUnit()));
+  set_margin_bottom(maybe_margin_bottom.value_or(LayoutUnit()));
+
   if (IsAbsolutelyPositioned()) {
     UpdateWidthAssumingAbsolutelyPositionedBox(
         layout_params.containing_block_direction,
@@ -250,15 +256,15 @@
   LayoutUnit main_size = LayoutUnit();
   // 4. Determine the main size of the flex container using the rules of the
   // formatting context in which it participates.
+  if (!layout_params.freeze_width) {
+    UpdateContentWidthAndMargins(layout_params.containing_block_direction,
+                                 layout_params.containing_block_size.width(),
+                                 layout_params.shrink_to_fit_width_forced,
+                                 width_depends_on_containing_block, maybe_left,
+                                 maybe_right, maybe_margin_left,
+                                 maybe_margin_right, main_space_, cross_space_);
+  }
   if (main_direction_is_horizontal) {
-    if (!layout_params.freeze_width) {
-      UpdateContentWidthAndMargins(
-          layout_params.containing_block_direction,
-          layout_params.containing_block_size.width(),
-          layout_params.shrink_to_fit_width_forced,
-          width_depends_on_containing_block, maybe_left, maybe_right,
-          maybe_margin_left, maybe_margin_right, main_space_, cross_space_);
-    }
     main_size = width();
   } else {
     if (!layout_params.freeze_height) {
@@ -309,11 +315,6 @@
     set_width(flex_formatting_context.cross_size());
   }
 
-  set_margin_left(maybe_margin_left.value_or(LayoutUnit()));
-  set_margin_right(maybe_margin_right.value_or(LayoutUnit()));
-  set_margin_top(maybe_margin_top.value_or(LayoutUnit()));
-  set_margin_bottom(maybe_margin_bottom.value_or(LayoutUnit()));
-
   UpdateRectOfPositionedChildBoxes(child_layout_params, layout_params);
 
   if (items.empty()) {
diff --git a/src/cobalt/layout/inline_formatting_context.cc b/src/cobalt/layout/inline_formatting_context.cc
index 0a9c5bc..6f9805a 100644
--- a/src/cobalt/layout/inline_formatting_context.cc
+++ b/src/cobalt/layout/inline_formatting_context.cc
@@ -77,7 +77,7 @@
   // calculate the "preferred width". It is possible to save one layout pass
   // taking into account that:
   //   - an exact value of "preferred width" does not matter if "available
-  //     width" cannot acommodate it;
+  //     width" cannot accommodate it;
   //   - the inline formatting context has more than one line if and only if
   //     the "preferred width" is greater than the "available width";
   //   - "preferred minimum" and "preferred" widths are equal when an inline
diff --git a/src/cobalt/layout/layout.gyp b/src/cobalt/layout/layout.gyp
index e608390..201c0c2 100644
--- a/src/cobalt/layout/layout.gyp
+++ b/src/cobalt/layout/layout.gyp
@@ -94,7 +94,7 @@
         'text_box.cc',
         'text_box.h',
         'topmost_event_target.cc',
-        'topmost_event_targer.h',
+        'topmost_event_target.h',
         'used_style.cc',
         'used_style.h',
         'vector2d_layout_unit.cc',
diff --git a/src/cobalt/layout/layout_boxes.cc b/src/cobalt/layout/layout_boxes.cc
index e387472..f617840 100644
--- a/src/cobalt/layout/layout_boxes.cc
+++ b/src/cobalt/layout/layout_boxes.cc
@@ -57,7 +57,7 @@
        box_iterator != client_rect_boxes.end(); ++box_iterator) {
     RectLayoutUnit transformed_border_box(
         (*box_iterator)
-            ->GetTransformedBoxFromRoot(
+            ->GetTransformedBoxFromRootWithScroll(
                 (*box_iterator)->GetBorderBoxFromMarginBox()));
     dom_rect_list->AppendDOMRect(
         new dom::DOMRect(transformed_border_box.x().toFloat(),
@@ -146,8 +146,7 @@
   }
 
   // Return the cached results if applicable.
-  if (scroll_area_cache_ &&
-      scroll_area_cache_->first == dir) {
+  if (scroll_area_cache_ && scroll_area_cache_->first == dir) {
     return scroll_area_cache_->second;
   }
 
@@ -159,8 +158,7 @@
   for (scoped_refptr<Box> layout_box : boxes_) {
     // Include the box's own content and padding areas.
     SizeLayoutUnit padding_size = layout_box->GetClampedPaddingBoxSize();
-    padding_area.Union(math::RectF(0, 0,
-                                   padding_size.width().toFloat(),
+    padding_area.Union(math::RectF(0, 0, padding_size.width().toFloat(),
                                    padding_size.height().toFloat()));
     const ContainerBox* container_box = layout_box->AsContainerBox();
     if (!container_box) {
@@ -185,10 +183,9 @@
             RectLayoutUnit border_box =
                 box->GetTransformedBoxFromContainingBlock(
                     container_box, box->GetBorderBoxFromMarginBox());
-            scroll_area.Union(math::RectF(border_box.x().toFloat(),
-                                          border_box.y().toFloat(),
-                                          border_box.width().toFloat(),
-                                          border_box.height().toFloat()));
+            scroll_area.Union(math::RectF(
+                border_box.x().toFloat(), border_box.y().toFloat(),
+                border_box.width().toFloat(), border_box.height().toFloat()));
 
             // Include the scrollable overflow regions of the contents provided
             // they are visible (i.e. container has overflow: visible).
@@ -221,8 +218,7 @@
 
   // Cache the results to speed up future queries.
   scroll_area_cache_.emplace(
-      dir,
-      math::RectF(left, top, right - left, bottom - top));
+      dir, math::RectF(left, top, right - left, bottom - top));
   return scroll_area_cache_->second;
 }
 
@@ -261,6 +257,15 @@
   }
 }
 
+void LayoutBoxes::SetUiNavItem(
+    const scoped_refptr<ui_navigation::NavItem>& item) {
+  for (Boxes::const_iterator box_iterator = boxes_.begin();
+       box_iterator != boxes_.end(); ++box_iterator) {
+    Box* box = *box_iterator;
+    box->SetUiNavItem(item);
+  }
+}
+
 math::RectF LayoutBoxes::GetBoundingBorderRectangle() const {
   // In the CSSOM View extensions to the HTMLElement interface, at
   // https://www.w3.org/TR/2013/WD-cssom-view-20131217/#extensions-to-the-htmlelement-interface,
diff --git a/src/cobalt/layout/layout_boxes.h b/src/cobalt/layout/layout_boxes.h
index 0e838c0..42ee844 100644
--- a/src/cobalt/layout/layout_boxes.h
+++ b/src/cobalt/layout/layout_boxes.h
@@ -61,6 +61,7 @@
   void InvalidateSizes() override;
   void InvalidateCrossReferences() override;
   void InvalidateRenderTreeNodes() override;
+  void SetUiNavItem(const scoped_refptr<ui_navigation::NavItem>& item) override;
 
   // Other
   //
diff --git a/src/cobalt/layout/layout_manager.cc b/src/cobalt/layout/layout_manager.cc
index 1da3d31..2f82d74 100644
--- a/src/cobalt/layout/layout_manager.cc
+++ b/src/cobalt/layout/layout_manager.cc
@@ -89,7 +89,7 @@
   // Setting these flags triggers an update of the layout box tree and the
   // generation of a new render tree at a regular interval (e.g. 60Hz). Events
   // such as DOM mutations cause them to be set to true. While the render tree
-  // is excusively produced at the regular interval, the box tree can also be
+  // is exclusively produced at the regular interval, the box tree can also be
   // updated via a call to DoSynchronousLayout().
   bool are_computed_styles_and_box_tree_dirty_;
   base::CVal<bool> is_render_tree_pending_;
diff --git a/src/cobalt/layout/topmost_event_target.cc b/src/cobalt/layout/topmost_event_target.cc
index 8801fef..23cbdb9 100644
--- a/src/cobalt/layout/topmost_event_target.cc
+++ b/src/cobalt/layout/topmost_event_target.cc
@@ -95,7 +95,7 @@
     }
 
     scoped_refptr<dom::HTMLElement> html_element = element->AsHTMLElement();
-    if (html_element && html_element->CanbeDesignatedByPointerIfDisplayed()) {
+    if (html_element && html_element->CanBeDesignatedByPointerIfDisplayed()) {
       ConsiderBoxes(html_element, layout_boxes, element_coordinate);
     }
   }
@@ -449,7 +449,7 @@
     // This is an 'up' event for the last pressed button indicating that no
     // more buttons are pressed.
     if (target_element && !is_touchpad_event) {
-      // Send the click event if needed, which is not prevented by canceling
+      // Send the click event if needed, which is not prevented by cancelling
       // the pointerdown event.
       //   https://www.w3.org/TR/uievents/#event-type-click
       //   https://www.w3.org/TR/pointerevents/#compatibility-mapping-with-mouse-events
diff --git a/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins-expected.png b/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins-expected.png
new file mode 100644
index 0000000..499cf73
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins.html b/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins.html
new file mode 100644
index 0000000..deb1b9f
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/css3-flexbox/flex-container-auto-margins.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<!--
+ | Combined tests for container auto margins of CSS Flexible Box Layout Module.
+ |   https://www.w3.org/TR/css-flexbox-1
+ -->
+<html>
+<head>
+  <style>
+  body {
+    margin: 65px;
+    font-family: Roboto;
+    background-color: #808080;
+    font-size: 12px;
+  }
+
+  .main {
+    width: 500px;
+    height: 300px;
+    background-color: #fff;
+  }
+
+  .absolute {
+    position: absolute;
+    left: 400px;
+  }
+
+  .outer {
+    width: 100px;
+    height: 50px;
+    background-color: #00f;
+  }
+
+  .inner {
+    width: 20px;
+    height: 20px;
+
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background-color: #0f0;
+  }
+
+  .auto {
+    margin: 0 auto;
+  }
+  .margin {
+    margin: 0 20px;
+  }
+
+  .column {
+    flex-flow: column wrap;
+  }
+  .row {
+    flex-flow: row wrap;
+  }
+  </style>
+</head>
+
+<body>
+  <div class="main">
+    <div class="outer">
+      <div class="inner auto column"></div>
+    </div>
+    <span class="outer">
+      <div class="inner auto column"></div>
+    </span>
+    <div class="outer">
+      <div class="inner auto row"></div>
+    </div>
+    <span class="outer">
+      <div class="inner auto row"></div>
+    </span>
+
+    <div class="outer">
+      <div class="inner margin column"></div>
+    </div>
+    <span class="outer">
+      <div class="inner margin column"></div>
+    </span>
+    <div class="outer">
+      <div class="inner margin row"></div>
+    </div>
+    <span class="outer">
+      <div class="inner margin row"></div>
+    </span>
+
+    <div class="outer absolute" style="top: 10px;">
+      <div class="inner auto column"></div>
+    </div>
+    <div class="outer absolute" style="top: 80px;">
+      <div class="inner auto row"></div>
+    </div>
+
+    <div class="outer absolute" style="top: 150px;">
+      <div class="inner margin column"></div>
+    </div>
+    <div class="outer absolute" style="top: 220px;">
+      <div class="inner margin row"></div>
+    </div>
+
+  </div>
+</body>
+</html>
diff --git a/src/cobalt/layout_tests/testdata/css3-flexbox/layout_tests.txt b/src/cobalt/layout_tests/testdata/css3-flexbox/layout_tests.txt
index 26b3994..e023eb1 100644
--- a/src/cobalt/layout_tests/testdata/css3-flexbox/layout_tests.txt
+++ b/src/cobalt/layout_tests/testdata/css3-flexbox/layout_tests.txt
@@ -135,5 +135,6 @@
 csswg_flex-shrink-007
 csswg_flex-shrink-008
 empty_container_baseline
+flex-container-auto-margins
 flex-items-flexibility
 positioned-containers
diff --git a/src/cobalt/layout_tests/testdata/css3-fonts/5-2-use-system-fallback-if-no-matching-family-is-found-expected.png b/src/cobalt/layout_tests/testdata/css3-fonts/5-2-use-system-fallback-if-no-matching-family-is-found-expected.png
index 5d53a71..8560d78 100644
--- a/src/cobalt/layout_tests/testdata/css3-fonts/5-2-use-system-fallback-if-no-matching-family-is-found-expected.png
+++ b/src/cobalt/layout_tests/testdata/css3-fonts/5-2-use-system-fallback-if-no-matching-family-is-found-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll-expected.png b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll-expected.png
new file mode 100644
index 0000000..62c4879
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll.html b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll.html
new file mode 100644
index 0000000..cb7492e
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<html>
+<!--
+ | Test CSSOM View extensions to the Element Interface, verifying that
+ | getBoundingClientRect() works properly with scrollLeft and scrollTop.
+ -->
+<head>
+  <style>
+    body {
+      font-family: Roboto;
+      font-size: 16px;
+      background-color: #FF0000;
+      margin: 0px;
+    }
+
+    .overflow-scroll {
+      outline: none;
+      width: 150px;
+      height: 100px;
+      overflow: scroll;
+      position: relative;
+      background-color: #000000;
+    }
+
+    .content {
+      width: 50px;
+      height: 50px;
+      position: absolute;
+    }
+  </style>
+  <script>
+    if (window.testRunner) {
+      window.testRunner.waitUntilDone();
+    }
+
+    function verifyGetBoundingClientRectAttributesAreCorrect(id, x, y, w, h) {
+      var error = "";
+      var element = document.getElementById(id);
+      if (!element) {
+        error += "\nElement " + id + " not found";
+        return error;
+      }
+
+      var rect = element.getBoundingClientRect();
+      if (rect["left"] != x) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".left mismatch";
+        error += "\n  Actual: " + rect["left"];
+        error += "\nExpected: " + x;
+      }
+      if (rect["top"] != y) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".top mismatch";
+        error += "\n  Actual: " + rect["top"];
+        error += "\nExpected: " + y;
+      }
+      if (rect["width"] != w) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".width mismatch";
+        error += "\n  Actual: " + rect["width"];
+        error += "\nExpected: " + w;
+      }
+      if (rect["height"] != h) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".height mismatch";
+        error += "\n  Actual: " + rect["height"];
+        error += "\nExpected: " + h;
+      }
+      return error;
+    }
+
+    window.onload = function() {
+      document.getElementById("outer-scroll").scrollTop = 25;
+      document.getElementById("outer-scroll").scrollLeft = 25;
+      document.getElementById("inner-scroll").scrollTop = 10;
+      document.getElementById("inner-scroll").scrollLeft = 50;
+      var error1 = verifyGetBoundingClientRectAttributesAreCorrect(
+          "target1", 0, -25, 50, 50);
+      var error2 = verifyGetBoundingClientRectAttributesAreCorrect(
+          "target2", 100, 75, 50, 50);
+      if (error1 || error2) {
+        console.log("FAIL" + error1 + error2);
+      } else {
+        document.body.style.backgroundColor = "rgba(0,0,0,0)";
+      }
+      if (window.testRunner) {
+        window.testRunner.notifyDone();
+      }
+    }
+  </script>
+</head>
+<body>
+  <div id="outer-scroll" class="overflow-scroll">
+    <div class="overflow-scroll">
+      <div id="target1" class="content"
+           style="background-color: #FF0000; transform: translateX(0px)"></div>
+      <div class="content"
+           style="background-color: #00FF00; transform: translateX(75px)"></div>
+      <div class="content"
+           style="background-color: #0000FF; transform: translateX(150px)"></div>
+    </div>
+    <div id="inner-scroll" class="overflow-scroll">
+      <div class="content"
+           style="background-color: #FF0000; transform: translateX(0px)"></div>
+      <div class="content"
+           style="background-color: #00FF00; transform: translateX(75px)"></div>
+      <div id="target2" class="content"
+           style="background-color: #0000FF; transform: translateX(150px)"></div>
+    </div>
+  </div>
+</body>
+</html>
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl-expected.png b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl-expected.png
new file mode 100644
index 0000000..1f279b8
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl-expected.png
Binary files differ
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl.html b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl.html
new file mode 100644
index 0000000..0e7c689
--- /dev/null
+++ b/src/cobalt/layout_tests/testdata/cssom-view/extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<!--
+ | Test CSSOM View extensions to the Element Interface, verifying that
+ | getBoundingClientRect() works properly with RTL and scrollLeft and scrollTop.
+ -->
+<head>
+  <style>
+    body {
+      font-family: Roboto;
+      font-size: 16px;
+      background-color: #FF0000;
+      margin: 0px;
+      position: absolute;
+      left: 0px;
+      width: 200px;
+      height: 200px;
+    }
+
+    .overflow-scroll {
+      outline: none;
+      width: 150px;
+      height: 100px;
+      overflow: scroll;
+      position: relative;
+      background-color: #000000;
+    }
+
+    .content {
+      width: 50px;
+      height: 50px;
+      position: absolute;
+    }
+  </style>
+  <script>
+    if (window.testRunner) {
+      window.testRunner.waitUntilDone();
+    }
+
+    function verifyGetBoundingClientRectAttributesAreCorrect(id, x, y, w, h) {
+      var error = "";
+      var element = document.getElementById(id);
+      if (!element) {
+        error += "\nElement " + id + " not found";
+        return error;
+      }
+
+      var rect = element.getBoundingClientRect();
+      if (rect["left"] != x) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".left mismatch";
+        error += "\n  Actual: " + rect["left"];
+        error += "\nExpected: " + x;
+      }
+      if (rect["top"] != y) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".top mismatch";
+        error += "\n  Actual: " + rect["top"];
+        error += "\nExpected: " + y;
+      }
+      if (rect["width"] != w) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".width mismatch";
+        error += "\n  Actual: " + rect["width"];
+        error += "\nExpected: " + w;
+      }
+      if (rect["height"] != h) {
+        error += "\ngetElementById('" + id + "').getBoundingClientRect()" +
+                 ".height mismatch";
+        error += "\n  Actual: " + rect["height"];
+        error += "\nExpected: " + h;
+      }
+      return error;
+    }
+
+    window.onload = function() {
+      document.getElementById("outer-scroll").scrollTop = 25;
+      document.getElementById("outer-scroll").scrollLeft = -25;
+      document.getElementById("inner-scroll").scrollTop = 10;
+      document.getElementById("inner-scroll").scrollLeft = -50;
+      var error1 = verifyGetBoundingClientRectAttributesAreCorrect(
+          "target1", 150, -25, 50, 50);
+      var error2 = verifyGetBoundingClientRectAttributesAreCorrect(
+          "target2", 50, 75, 50, 50);
+      if (error1 || error2) {
+        console.log("FAIL" + error1 + error2);
+      } else {
+        document.body.style.backgroundColor = "rgba(0,0,0,0)";
+      }
+      if (window.testRunner) {
+        window.testRunner.notifyDone();
+      }
+    }
+  </script>
+</head>
+<body dir="rtl">
+  <div id="outer-scroll" class="overflow-scroll">
+    <div class="overflow-scroll">
+      <div id="target1" class="content"
+           style="background-color: #FF0000; transform: translateX(0px)"></div>
+      <div class="content"
+           style="background-color: #00FF00; transform: translateX(-75px)"></div>
+      <div class="content"
+           style="background-color: #0000FF; transform: translateX(-150px)"></div>
+    </div>
+    <div id="inner-scroll" class="overflow-scroll">
+      <div class="content"
+           style="background-color: #FF0000; transform: translateX(0px)"></div>
+      <div class="content"
+           style="background-color: #00FF00; transform: translateX(-75px)"></div>
+      <div id="target2" class="content"
+           style="background-color: #0000FF; transform: translateX(-150px)"></div>
+    </div>
+  </div>
+</body>
+</html>
diff --git a/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt b/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
index 39f0e9c..c4afbbf 100644
--- a/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
+++ b/src/cobalt/layout_tests/testdata/cssom-view/layout_tests.txt
@@ -11,6 +11,8 @@
 extensions_to_the_element_interface_get_bounding_client_rect_with_box_splitting
 extensions_to_the_element_interface_get_bounding_client_rect_with_nested_transforms
 extensions_to_the_element_interface_get_bounding_client_rect_with_scale_transform
+extensions_to_the_element_interface_get_bounding_client_rect_with_scroll
+extensions_to_the_element_interface_get_bounding_client_rect_with_scroll_rtl
 extensions_to_the_element_interface_get_bounding_client_rect_with_translate_transform
 extensions_to_the_html_element_interface_offset_top_left_width_height
 extensions_to_the_html_element_interface_offset_width_height_with_box_splitting
diff --git a/src/cobalt/loader/blob_fetcher.h b/src/cobalt/loader/blob_fetcher.h
index eb6856e..8628ed8 100644
--- a/src/cobalt/loader/blob_fetcher.h
+++ b/src/cobalt/loader/blob_fetcher.h
@@ -26,7 +26,7 @@
  public:
   // This callback avoids a dependency from the fetcher to the actual blob
   // implementation.
-  // If the blob is succesfully fetched:
+  // If the blob is successfully fetched:
   //   1. Writes the size of its buffer to |size|.
   //   2. If |size| > 0, then it also writes the address of the non-empty buffer
   //      to |data|, otherwise writes NULL to |data|.
diff --git a/src/cobalt/loader/cors_preflight.cc b/src/cobalt/loader/cors_preflight.cc
index 6af4f72..eb3b70a 100644
--- a/src/cobalt/loader/cors_preflight.cc
+++ b/src/cobalt/loader/cors_preflight.cc
@@ -199,7 +199,7 @@
     const std::vector<std::string>& CORS_exposed_header_name_list,
     bool credentials_mode_is_include) {
   // Every check in this function is case-insensitive comparison.
-  // Header is safe if it's CORS-safelisted repsonse-header name.
+  // Header is safe if it's CORS-safelisted response-header name.
   if (IsInArray(name.c_str(), kCORSSafelistedResponseHeaders,
                 arraysize(kCORSSafelistedResponseHeaders))) {
     return true;
@@ -211,7 +211,7 @@
   }
   // The following two steps checks if given header name is in CORS-exposed
   // header-name list. If Access-Control-Expose-Headers header is '*', all
-  // header names in reponse should be in CORS-exposed header-name list.
+  // header names in response should be in CORS-exposed header-name list.
   if (CORS_exposed_header_name_list.size() == 1 &&
       CORS_exposed_header_name_list.at(0) == "*" &&
       !credentials_mode_is_include) {
@@ -389,8 +389,7 @@
     int max_age = 0;
     if (response_headers->GetNormalizedHeader(kAccessControlMaxAge,
                                               &max_age_str)) {
-      max_age = std::min(SbStringAToI(max_age_str.c_str()),
-                         kPreflightCacheMaxAgeLimit);
+      max_age = std::min(atoi(max_age_str.c_str()), kPreflightCacheMaxAgeLimit);
     }
     preflight_cache_->AppendEntry(source->GetURL().spec(), origin_, max_age,
                                   credentials_mode_is_include_, methods_vec,
diff --git a/src/cobalt/loader/cors_preflight_cache.cc b/src/cobalt/loader/cors_preflight_cache.cc
index 4ba0ba7..c56da2f 100644
--- a/src/cobalt/loader/cors_preflight_cache.cc
+++ b/src/cobalt/loader/cors_preflight_cache.cc
@@ -159,7 +159,7 @@
     if (entry_iter == url_iter->second.end()) {
       continue;
     }
-    // The entry could have been updated and should only delete obselete ones.
+    // The entry could have been updated and should only delete obsolete ones.
     if (entry_iter->second->expiration_time < base::Time::Now()) {
       url_iter->second.erase(entry_iter);
     }
diff --git a/src/cobalt/loader/cors_preflight_cache.h b/src/cobalt/loader/cors_preflight_cache.h
index 518726b..6e063d5 100644
--- a/src/cobalt/loader/cors_preflight_cache.h
+++ b/src/cobalt/loader/cors_preflight_cache.h
@@ -59,8 +59,8 @@
   };
 
   // The spec wants a cache entry for every method and for every header which is
-  // a little unnesessarily expensive. We create an entry for each request and
-  // If there is an old entry in the new entry's pleace we simply push the old
+  // a little unnecessarily expensive. We create an entry for each request and
+  // If there is an old entry in the new entry's place we simply push the old
   // one out which potentially increases cache misses slightly but reduces
   // memory cost. Chromium also takes this approach.
   // The map's first key is entry's request url and second is entry's origin.
diff --git a/src/cobalt/loader/file_fetcher.cc b/src/cobalt/loader/file_fetcher.cc
index e44c349..11e62bf 100644
--- a/src/cobalt/loader/file_fetcher.cc
+++ b/src/cobalt/loader/file_fetcher.cc
@@ -122,7 +122,7 @@
   // Build the vector of paths to search for files.
   // Paths will be tried in the order they are listed.
   // Add the user-specified extra directory first, if specified,
-  // so it has precendence.
+  // so it has precedence.
   if (!extra_search_dir.empty()) {
     search_path_.push_back(extra_search_dir);
   }
diff --git a/src/cobalt/loader/file_fetcher.h b/src/cobalt/loader/file_fetcher.h
index 840ab24..097faa1 100644
--- a/src/cobalt/loader/file_fetcher.h
+++ b/src/cobalt/loader/file_fetcher.h
@@ -73,7 +73,7 @@
   // Builds the search path list, including an optional extra directory.
   void BuildSearchPath(const base::FilePath& extra_search_dir);
 
-  // Tries opening a file using the current entry in the seach path.
+  // Tries opening a file using the current entry in the search path.
   void TryFileOpen();
 
   void ReadNextChunk();
diff --git a/src/cobalt/loader/file_fetcher_test.cc b/src/cobalt/loader/file_fetcher_test.cc
index e9defc9..5dcbafa 100644
--- a/src/cobalt/loader/file_fetcher_test.cc
+++ b/src/cobalt/loader/file_fetcher_test.cc
@@ -53,7 +53,7 @@
   CHECK(base::PathService::Get(base::DIR_TEST_DATA, &dir_test_data_));
 }
 
-TEST_F(FileFetcherTest, NonExisitingPath) {
+TEST_F(FileFetcherTest, NonExistingPath) {
   base::RunLoop run_loop;
 
   StrictMock<MockFetcherHandler> fetcher_handler_mock(&run_loop);
diff --git a/src/cobalt/loader/image/failure_image_decoder.h b/src/cobalt/loader/image/failure_image_decoder.h
new file mode 100644
index 0000000..06045f8
--- /dev/null
+++ b/src/cobalt/loader/image/failure_image_decoder.h
@@ -0,0 +1,57 @@
+// Copyright 2021 The Cobalt Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef COBALT_LOADER_IMAGE_FAILURE_IMAGE_DECODER_H_
+#define COBALT_LOADER_IMAGE_FAILURE_IMAGE_DECODER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/compiler_specific.h"
+#include "cobalt/loader/image/image.h"
+#include "cobalt/loader/image/image_data_decoder.h"
+
+namespace cobalt {
+namespace loader {
+namespace image {
+
+// This class always signals a decoding error rather than decoding.  It can
+// be used for imitating the normal image decoders without doing any
+// decoding works.
+class FailureImageDecoder : public ImageDataDecoder {
+ public:
+  explicit FailureImageDecoder(render_tree::ResourceProvider* resource_provider,
+                               const base::DebuggerHooks& debugger_hooks)
+      : ImageDataDecoder(resource_provider, debugger_hooks) {}
+
+  // From ImageDataDecoder
+  std::string GetTypeString() const override { return "FailureImageDecoder"; }
+
+ private:
+  // From ImageDataDecoder
+  size_t DecodeChunkInternal(const uint8* data, size_t input_byte) override {
+    set_state(kError);
+    return input_byte;
+  }
+  scoped_refptr<Image> FinishInternal() override {
+    // Indicate the failure of decoding works.
+    return nullptr;
+  }
+};
+
+}  // namespace image
+}  // namespace loader
+}  // namespace cobalt
+
+#endif  // COBALT_LOADER_IMAGE_FAILURE_IMAGE_DECODER_H_
diff --git a/src/cobalt/loader/image/image_decoder.cc b/src/cobalt/loader/image/image_decoder.cc
index f9bf6c8..a499c63 100644
--- a/src/cobalt/loader/image/image_decoder.cc
+++ b/src/cobalt/loader/image/image_decoder.cc
@@ -21,6 +21,7 @@
 #include "base/trace_event/trace_event.h"
 #include "cobalt/configuration/configuration.h"
 #include "cobalt/loader/image/dummy_gif_image_decoder.h"
+#include "cobalt/loader/image/failure_image_decoder.h"
 #include "cobalt/loader/image/image_decoder_starboard.h"
 #include "cobalt/loader/image/jpeg_image_decoder.h"
 #include "cobalt/loader/image/lottie_animation_decoder.h"
@@ -28,6 +29,7 @@
 #include "cobalt/loader/image/stub_image_decoder.h"
 #include "cobalt/loader/image/webp_image_decoder.h"
 #include "cobalt/loader/switches.h"
+#include "cobalt/render_tree/resource_provider_stub.h"
 #include "net/base/mime_util.h"
 #include "net/http/http_status_code.h"
 #include "starboard/configuration.h"
@@ -71,6 +73,12 @@
   }
 }
 
+// Returns true if the ResourceProvider is ResourceProviderStub.
+bool IsResourceProviderStub(render_tree::ResourceProvider* resource_provider) {
+  return resource_provider->GetTypeId() ==
+         base::GetTypeId<render_tree::ResourceProviderStub>();
+}
+
 }  // namespace
 
 ImageDecoder::ImageDecoder(
@@ -219,7 +227,11 @@
   DCHECK_EQ(state_, kSuspended);
   DCHECK(!resource_provider_);
   DCHECK(resource_provider);
-
+  if (IsResourceProviderStub(resource_provider)) {
+    use_failure_image_decoder_ = true;
+  } else {
+    use_failure_image_decoder_ = false;
+  }
   state_ = kWaitingForHeader;
   resource_provider_ = resource_provider;
 }
@@ -328,11 +340,14 @@
 std::unique_ptr<ImageDataDecoder> CreateImageDecoderFromImageType(
     ImageDecoder::ImageType image_type,
     render_tree::ResourceProvider* resource_provider,
-    const base::DebuggerHooks& debugger_hooks) {
+    const base::DebuggerHooks& debugger_hooks, bool use_failure_image_decoder) {
   // Call different types of decoders by matching the image signature.
   if (s_use_stub_image_decoder) {
     return std::unique_ptr<ImageDataDecoder>(
         new StubImageDecoder(resource_provider, debugger_hooks));
+  } else if (use_failure_image_decoder) {
+    return std::unique_ptr<ImageDataDecoder>(
+        new FailureImageDecoder(resource_provider, debugger_hooks));
   } else if (image_type == ImageDecoder::kImageTypeJPEG) {
     return std::unique_ptr<ImageDataDecoder>(
         new JPEGImageDecoder(resource_provider, debugger_hooks,
@@ -379,7 +394,8 @@
 
   if (!decoder_) {
     decoder_ = CreateImageDecoderFromImageType(image_type_, resource_provider_,
-                                               debugger_hooks_);
+                                               debugger_hooks_,
+                                               use_failure_image_decoder_);
   }
 
   if (!decoder_) {
@@ -412,7 +428,7 @@
                       ->CobaltRasterizerType()) == "direct-gles";
 #elif SB_HAS(GLES2) && defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
   bool allow_image_decoding_to_multi_plane = true;
-#else  // SB_HAS(GLES2) && defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
+#else   // SB_HAS(GLES2) && defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
   bool allow_image_decoding_to_multi_plane = false;
 #endif  // SB_HAS(GLES2) && defined(COBALT_FORCE_DIRECT_GLES_RASTERIZER)
 
diff --git a/src/cobalt/loader/image/image_decoder.h b/src/cobalt/loader/image/image_decoder.h
index 2f82867..cb80ce6 100644
--- a/src/cobalt/loader/image/image_decoder.h
+++ b/src/cobalt/loader/image/image_decoder.h
@@ -71,7 +71,7 @@
   void Resume(render_tree::ResourceProvider* resource_provider) override;
 
   // Called when this ImageDecoder's deletion has been posted to a message loop.
-  // This prevents any additional decoding from occuring prior to the decoder
+  // This prevents any additional decoding from occurring prior to the decoder
   // being deleted.
   void SetDeletionPending();
 
@@ -117,6 +117,9 @@
   // Whether or not there is a pending task deleting this decoder on a message
   // loop.
   base::subtle::Atomic32 is_deletion_pending_;
+
+  // Whether or not we use failure image decoder.
+  bool use_failure_image_decoder_ = false;
 };
 
 }  // namespace image
diff --git a/src/cobalt/loader/image/png_image_decoder.cc b/src/cobalt/loader/image/png_image_decoder.cc
index 5fd726a..fa27801 100644
--- a/src/cobalt/loader/image/png_image_decoder.cc
+++ b/src/cobalt/loader/image/png_image_decoder.cc
@@ -34,7 +34,7 @@
 const uint32 kMaxPNGSize = 1000000UL;
 
 // Use fix point multiplier instead of integer division or floating point math.
-// This multipler produces exactly the same result for all values in range 0 -
+// This multiplier produces exactly the same result for all values in range 0 -
 // 255.
 const uint32 kFixPointOffset = 24;
 const uint32 kFixPointShifted = 1U << kFixPointOffset;
@@ -97,7 +97,7 @@
   // from setjmp indicates whether control reached that point normally or from a
   // call to longjmp. If the return is from a direct invocation, setjmp returns
   // 0. If the return is from a call to longjmp, setjmp returns a nonzero value.
-MSVC_PUSH_DISABLE_WARNING(4611);
+  MSVC_PUSH_DISABLE_WARNING(4611);
   // warning C4611: interaction between '_setjmp' and C++ object destruction is
   // non-portable.
   if (setjmp(png_->jmpbuf)) {
@@ -106,7 +106,7 @@
     set_state(kError);
     return 0;
   }
-MSVC_POP_WARNING();
+  MSVC_POP_WARNING();
 
   png_process_data(png_, info_, const_cast<png_bytep>(data), size);
 
diff --git a/src/cobalt/loader/image/sandbox/image_decoder_sandbox.cc b/src/cobalt/loader/image/sandbox/image_decoder_sandbox.cc
index 6367305..9095241 100644
--- a/src/cobalt/loader/image/sandbox/image_decoder_sandbox.cc
+++ b/src/cobalt/loader/image/sandbox/image_decoder_sandbox.cc
@@ -53,7 +53,7 @@
   scoped_refptr<loader::image::Image> image;
 };
 
-std::vector<base::FilePath> GetImagePaths(const char* extention) {
+std::vector<base::FilePath> GetImagePaths(const char* extension) {
   base::FilePath image_path;
   CHECK(base::PathService::Get(base::DIR_TEST_DATA, &image_path));
   image_path = image_path.Append(FILE_PATH_LITERAL("cobalt"))
@@ -65,7 +65,7 @@
                                  FileEnumerator::FILES);
   for (base::FilePath next = file_enumerator.Next(); !next.empty();
        next = file_enumerator.Next()) {
-    if (next.Extension() == extention) {
+    if (next.Extension() == extension) {
       result.push_back(next);
     }
   }
diff --git a/src/cobalt/loader/image/threaded_image_decoder_proxy.cc b/src/cobalt/loader/image/threaded_image_decoder_proxy.cc
index 43cc094..7f1b8aa 100644
--- a/src/cobalt/loader/image/threaded_image_decoder_proxy.cc
+++ b/src/cobalt/loader/image/threaded_image_decoder_proxy.cc
@@ -126,7 +126,7 @@
 
 void ThreadedImageDecoderProxy::Resume(
     render_tree::ResourceProvider* resource_provider) {
-  load_message_loop_->task_runner()->PostTask(
+  load_message_loop_->task_runner()->PostBlockingTask(
       FROM_HERE,
       base::Bind(&ImageDecoder::Resume, base::Unretained(image_decoder_.get()),
                  resource_provider));
diff --git a/src/cobalt/loader/loader.cc b/src/cobalt/loader/loader.cc
index 53c3854..1532a74 100644
--- a/src/cobalt/loader/loader.cc
+++ b/src/cobalt/loader/loader.cc
@@ -87,7 +87,7 @@
 
   std::unique_ptr<Decoder> decoder = decoder_creator_.Run(
       base::Bind(&Loader::LoadComplete, base::Unretained(this)));
-  // We are doing this bizzare check because decoder_ used to be a scoped_ptr
+  // We are doing this bizarre check because decoder_ used to be a scoped_ptr
   // and scoped_ptr checks equality of held raw pointer and only delete rhs if
   // not equal.
   if (decoder.get() == decoder_.get()) {
diff --git a/src/cobalt/loader/loader.gyp b/src/cobalt/loader/loader.gyp
index 2b61cf7..3a213f3 100644
--- a/src/cobalt/loader/loader.gyp
+++ b/src/cobalt/loader/loader.gyp
@@ -52,6 +52,7 @@
         'image/animated_webp_image.h',
         'image/dummy_gif_image_decoder.cc',
         'image/dummy_gif_image_decoder.h',
+        'image/failure_image_decoder.h',
         'image/image_cache.h',
         'image/image_data_decoder.cc',
         'image/image_data_decoder.h',
diff --git a/src/cobalt/loader/mesh/projection_codec/projection_decoder.h b/src/cobalt/loader/mesh/projection_codec/projection_decoder.h
index 53842f4..7c604de 100644
--- a/src/cobalt/loader/mesh/projection_codec/projection_decoder.h
+++ b/src/cobalt/loader/mesh/projection_codec/projection_decoder.h
@@ -41,7 +41,7 @@
   static const uint32_t kMaxMeshCount = 32;
   static const uint32_t kMaxTriangleIndexCount = 128 * 1000;
 
-  // This is a callback handler interface for a ProjecionDecoder.
+  // This is a callback handler interface for a ProjectionDecoder.
   class Sink {
    public:
     virtual ~Sink();
@@ -104,7 +104,7 @@
     BitReader(const uint8_t* data, size_t data_size);
 
     // Reads the requested number of big-endian bits. Sets ok() to false if an
-    // error ocurred.
+    // error occurred.
     uint32_t GetBits(int32_t num_bits);
 
     // Aligns the reader to an 8-bit boundary, potentially discarding up to 7
diff --git a/src/cobalt/loader/net_fetcher.cc b/src/cobalt/loader/net_fetcher.cc
index 8dd8c35..c74394f 100644
--- a/src/cobalt/loader/net_fetcher.cc
+++ b/src/cobalt/loader/net_fetcher.cc
@@ -23,14 +23,14 @@
 #include "cobalt/loader/url_fetcher_string_writer.h"
 #include "cobalt/network/network_module.h"
 #include "net/url_request/url_fetcher.h"
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 #include "starboard/configuration.h"
 #if SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
 #define HANDLE_CORE_DUMP
 #include "base/lazy_instance.h"
 #include STARBOARD_CORE_DUMP_HANDLER_INCLUDE
 #endif  // SB_HAS(CORE_DUMP_HANDLER_SUPPORT)
-#endif  // OS_STARBOARD
+#endif  // defined(STARBOARD)
 
 namespace cobalt {
 namespace loader {
diff --git a/src/cobalt/loader/resource_cache.cc b/src/cobalt/loader/resource_cache.cc
index e14e7bb..23346db 100644
--- a/src/cobalt/loader/resource_cache.cc
+++ b/src/cobalt/loader/resource_cache.cc
@@ -114,7 +114,7 @@
   on_retry_loading_.Run();
 
   // The delay starts at 1 second and doubles every subsequent retry until the
-  // maxiumum delay of 1024 seconds (~17 minutes) is reached. After this, all
+  // maximum delay of 1024 seconds (~17 minutes) is reached. After this, all
   // additional attempts also wait 1024 seconds.
   const int64 kBaseRetryDelayInMilliseconds = 1000;
   const int kMaxRetryCountShift = 10;
diff --git a/src/cobalt/loader/resource_cache.h b/src/cobalt/loader/resource_cache.h
index 7833762..bd2890a 100644
--- a/src/cobalt/loader/resource_cache.h
+++ b/src/cobalt/loader/resource_cache.h
@@ -563,7 +563,7 @@
   // |cached_resource_map_| and add it to |weak_referenced_cached_resource_map_|
   // or |unreferenced_cached_resource_map_|, depending on whether the resource
   // is still weakly referenced.
-  // It will then start purgeing and may immediately free the resource from
+  // It will then start purging and may immediately free the resource from
   // memory ifthe cache is over its memory limit.
   void NotifyResourceDestroyed(CachedResourceType* cached_resource);
 
diff --git a/src/cobalt/loader/sync_loader.cc b/src/cobalt/loader/sync_loader.cc
index 9b1b4cf..d64c379 100644
--- a/src/cobalt/loader/sync_loader.cc
+++ b/src/cobalt/loader/sync_loader.cc
@@ -44,7 +44,7 @@
         end_waitable_event_(base::WaitableEvent::ResetPolicy::MANUAL,
                             base::WaitableEvent::InitialState::NOT_SIGNALED) {}
 
-  // Start() and End() should be called on the same thread, the sychronous load
+  // Start() and End() should be called on the same thread, the synchronous load
   // thread, so the member objects are created, execute, and are destroyed,
   // on that same thread.
   void Start(base::Callback<std::unique_ptr<Fetcher>(Fetcher::Handler*)>
diff --git a/src/cobalt/math/cubic_bezier.h b/src/cobalt/math/cubic_bezier.h
index 88c8020..98e6869 100644
--- a/src/cobalt/math/cubic_bezier.h
+++ b/src/cobalt/math/cubic_bezier.h
@@ -33,7 +33,7 @@
   // Returns an approximation of dy/dx at the given x.
   double Slope(double x) const;
 
-  // Sets |min| and |max| to the bezier's minimum and maximium y values in the
+  // Sets |min| and |max| to the bezier's minimum and maximum y values in the
   // interval [0, 1].
   void Range(double* min, double* max) const;
 
diff --git a/src/cobalt/math/matrix3_f.h b/src/cobalt/math/matrix3_f.h
index de31149..8694472 100644
--- a/src/cobalt/math/matrix3_f.h
+++ b/src/cobalt/math/matrix3_f.h
@@ -88,7 +88,7 @@
   }
 
   // Compute eigenvalues and (optionally) normalized eigenvectors of
-  // a positive defnite matrix *this. Eigenvectors are computed only if
+  // a positive definite matrix *this. Eigenvectors are computed only if
   // non-null |eigenvectors| matrix is passed. If it is NULL, the routine
   // will not attempt to compute eigenvectors but will still return eigenvalues
   // if they can be computed.
diff --git a/src/cobalt/math/matrix_interpolation.cc b/src/cobalt/math/matrix_interpolation.cc
index 676e3ec..d2b48b9 100644
--- a/src/cobalt/math/matrix_interpolation.cc
+++ b/src/cobalt/math/matrix_interpolation.cc
@@ -53,7 +53,7 @@
     col0x *= 1 / decomposition.scale[0];
     col0y *= 1 / decomposition.scale[0];
   }
-  if ((0.0f !=  decomposition.scale[1])) {
+  if ((0.0f != decomposition.scale[1])) {
     col1x *= 1 / decomposition.scale[1];
     col1y *= 1 / decomposition.scale[1];
   }
@@ -87,17 +87,16 @@
   return decomposition;
 }
 
-float Lerp(float a, float b, float progress) {
-  return a + (b - a) * progress;
-}
+float Lerp(float a, float b, float progress) { return a + (b - a) * progress; }
 
 namespace {
 
 // Prepare certain attributes of the decomposed matrices for interpolation.
-void SanitizeInputsForInterpolation(
-    const DecomposedMatrix& a, const DecomposedMatrix& b,
-    float* a_scale_sanitized, float* a_angle_sanitized,
-    float* b_angle_sanitized) {
+void SanitizeInputsForInterpolation(const DecomposedMatrix& a,
+                                    const DecomposedMatrix& b,
+                                    float* a_scale_sanitized,
+                                    float* a_angle_sanitized,
+                                    float* b_angle_sanitized) {
   static const float kPi = static_cast<float>(M_PI);
 
   // If x-axis of one is flipped, and y-axis of the other,
@@ -172,7 +171,7 @@
 
   // Translate matrix.  Note that we deviate from the specification here
   // because the specification's "recompose" algorithm is inconsistent with
-  // its "decompose" algorithm.  The modification acheives this consistency.
+  // its "decompose" algorithm.  The modification achieves this consistency.
   matrix(0, 2) = decomposition.translation[0];
   matrix(1, 2) = decomposition.translation[1];
 
diff --git a/src/cobalt/math/quad_f.cc b/src/cobalt/math/quad_f.cc
index d001d21..0c93e30 100644
--- a/src/cobalt/math/quad_f.cc
+++ b/src/cobalt/math/quad_f.cc
@@ -39,8 +39,8 @@
   // This math computes the signed area of the quad. Positive area
   // indicates the quad is clockwise; negative area indicates the quad is
   // counter-clockwise. Note carefully: this is backwards from conventional
-  // math because our geometric space uses screen coordiantes with y-axis
-  // pointing downards.
+  // math because our geometric space uses screen coordinates with y-axis
+  // pointing downwards.
   // Reference: http://mathworld.wolfram.com/PolygonArea.html.
   // The equation can be written:
   // Signed area = determinant1 + determinant2 + determinant3 + determinant4
@@ -66,7 +66,7 @@
   // Then checking if the origin is contained in the translated triangle.
   // The origin O lies inside ABC if and only if the triangles OAB, OBC,
   // and OCA are all either clockwise or counterclockwise.
-  // This algorithm is from Real-Time Collision Detection (Chaper 5.4.2).
+  // This algorithm is from Real-Time Collision Detection (Chapter 5.4.2).
 
   Vector2dF a = r1 - point;
   Vector2dF b = r2 - point;
diff --git a/src/cobalt/math/rect_conversions.h b/src/cobalt/math/rect_conversions.h
index 687a43b..ee81aac 100644
--- a/src/cobalt/math/rect_conversions.h
+++ b/src/cobalt/math/rect_conversions.h
@@ -24,7 +24,7 @@
 Rect ToNearestRect(const RectF& rect);
 
 // Returns true if the Rect produced after snapping the corners of the RectF
-// to an integer grid is withing |distance|.
+// to an integer grid is within |distance|.
 bool IsNearestRectWithinDistance(const RectF& rect, float distance);
 
 // Returns a Rect obtained by flooring the values of the given RectF.
diff --git a/src/cobalt/media/base/audio_discard_helper_unittest.cc b/src/cobalt/media/base/audio_discard_helper_unittest.cc
index 22edc3b..bd7f744 100644
--- a/src/cobalt/media/base/audio_discard_helper_unittest.cc
+++ b/src/cobalt/media/base/audio_discard_helper_unittest.cc
@@ -322,8 +322,8 @@
   encoded_buffer->set_discard_padding(
       std::make_pair(kDuration / 2, base::TimeDelta()));
 
-  // All of the first buffer should be discarded, half from the inital delay and
-  // another half from the front discard padding.
+  // All of the first buffer should be discarded, half from the initial delay
+  // and another half from the front discard padding.
   //
   //    Encoded                   Discard Delay
   //   |--------|     |---------|     |----|
diff --git a/src/cobalt/media/base/audio_parameters.h b/src/cobalt/media/base/audio_parameters.h
index 542fb0a..2e20da8 100644
--- a/src/cobalt/media/base/audio_parameters.h
+++ b/src/cobalt/media/base/audio_parameters.h
@@ -142,7 +142,7 @@
   ChannelLayout channel_layout() const { return channel_layout_; }
 
   // The number of channels is usually computed from channel_layout_. Setting
-  // this explictly is only required with CHANNEL_LAYOUT_DISCRETE.
+  // this explicitly is only required with CHANNEL_LAYOUT_DISCRETE.
   void set_channels_for_discrete(int channels) {
     DCHECK(channel_layout_ == CHANNEL_LAYOUT_DISCRETE ||
            channels == ChannelLayoutToChannelCount(channel_layout_));
diff --git a/src/cobalt/media/base/bit_reader_core.h b/src/cobalt/media/base/bit_reader_core.h
index 5c63fc6..9e7fda1 100644
--- a/src/cobalt/media/base/bit_reader_core.h
+++ b/src/cobalt/media/base/bit_reader_core.h
@@ -97,7 +97,7 @@
   bool ReadBitsInternal(int num_bits, uint64_t* out);
 
   // Refill bit registers to have at least |min_nbits| bits available.
-  // Return true if the mininimum bit count condition is met after the refill.
+  // Return true if the minimum bit count condition is met after the refill.
   bool Refill(int min_nbits);
 
   // Refill the current bit register from the next bit register.
diff --git a/src/cobalt/media/base/color_space.h b/src/cobalt/media/base/color_space.h
index bedff31..281e7eb 100644
--- a/src/cobalt/media/base/color_space.h
+++ b/src/cobalt/media/base/color_space.h
@@ -23,7 +23,7 @@
 // refactors.
 namespace gfx {
 
-// Used to represet a color space for the purpose of color conversion.
+// Used to represent a color space for the purpose of color conversion.
 // This is designed to be safe and compact enough to send over IPC
 // between any processes.
 class ColorSpace {
@@ -129,7 +129,7 @@
     // Limited Rec. 709 color range with RGB values ranging from 16 to 235.
     kRangeIdLimited = 1,
 
-    // Full RGB color range with RGB valees from 0 to 255.
+    // Full RGB color range with RGB values from 0 to 255.
     kRangeIdFull = 2,
 
     // Range is defined by TransferID/MatrixID.
diff --git a/src/cobalt/media/base/container_names.cc b/src/cobalt/media/base/container_names.cc
index c55a41b..4134db4 100644
--- a/src/cobalt/media/base/container_names.cc
+++ b/src/cobalt/media/base/container_names.cc
@@ -11,7 +11,6 @@
 #include "base/logging.h"
 #include "base/numerics/safe_conversions.h"
 #include "cobalt/media/base/bit_reader.h"
-#include "starboard/character.h"
 #include "starboard/common/string.h"
 #include "starboard/memory.h"
 #include "starboard/types.h"
@@ -1101,14 +1100,14 @@
   RCHECK(*offset < buffer_size);
 
   // Skip over any leading space.
-  while (SbCharacterIsSpace(buffer[*offset])) {
+  while (isspace(buffer[*offset])) {
     ++(*offset);
     RCHECK(*offset < buffer_size);
   }
 
   // Need to process up to max_digits digits.
   int numSeen = 0;
-  while (--max_digits >= 0 && SbCharacterIsDigit(buffer[*offset])) {
+  while (--max_digits >= 0 && isdigit(buffer[*offset])) {
     ++numSeen;
     ++(*offset);
     if (*offset >= buffer_size) return true;  // Out of space but seen a digit.
diff --git a/src/cobalt/media/base/decrypt_config.h b/src/cobalt/media/base/decrypt_config.h
index 4c43834..b8e3b44 100644
--- a/src/cobalt/media/base/decrypt_config.h
+++ b/src/cobalt/media/base/decrypt_config.h
@@ -47,18 +47,15 @@
   //   does not specify patterns for cbcs encryption mode. The pattern is
   //   assumed to be 1:9 for video and 1:0 for audio.
   static std::unique_ptr<DecryptConfig> CreateCencConfig(
-      const std::string& key_id,
-      const std::string& iv,
+      const std::string& key_id, const std::string& iv,
       const std::vector<SubsampleEntry>& subsamples);
   static std::unique_ptr<DecryptConfig> CreateCbcsConfig(
-      const std::string& key_id,
-      const std::string& iv,
+      const std::string& key_id, const std::string& iv,
       const std::vector<SubsampleEntry>& subsamples,
       base::Optional<EncryptionPattern> encryption_pattern);
 
   DecryptConfig(const EncryptionMode& encryption_mode,
-                const std::string& key_id,
-                const std::string& iv,
+                const std::string& key_id, const std::string& iv,
                 const std::vector<SubsampleEntry>& subsamples,
                 base::Optional<EncryptionPattern> encryption_pattern);
   ~DecryptConfig();
@@ -75,7 +72,7 @@
   bool HasPattern() const;
 
   // Returns true if the corresponding decoder buffer requires decryption and
-  // false if that buffer is clear despite the presense of DecryptConfig.
+  // false if that buffer is clear despite the presence of DecryptConfig.
   bool is_encrypted() const { return !key_id_.empty() && !iv_.empty(); }
 
   // Returns true if all fields in |config| match this config.
diff --git a/src/cobalt/media/base/demuxer_stream_provider.h b/src/cobalt/media/base/demuxer_stream_provider.h
index ce5c42d..26b922a 100644
--- a/src/cobalt/media/base/demuxer_stream_provider.h
+++ b/src/cobalt/media/base/demuxer_stream_provider.h
@@ -16,7 +16,7 @@
 // Abstract class that defines how to retrieve "media sources" in DemuxerStream
 // form (for most cases) or URL form (for the MediaPlayerRenderer case).
 //
-// The sub-classes do not stricly provide demuxer streams, but because all
+// The sub-classes do not strictly provide demuxer streams, but because all
 // sub-classes are for the moment Demuxers, this class has not been renamed to
 // "MediaProvider". This class would be a good candidate for renaming, if
 // ever Pipeline were to support this class directly, instead of the Demuxer
diff --git a/src/cobalt/media/base/fake_demuxer_stream.h b/src/cobalt/media/base/fake_demuxer_stream.h
index d50e7f6..3827a94 100644
--- a/src/cobalt/media/base/fake_demuxer_stream.h
+++ b/src/cobalt/media/base/fake_demuxer_stream.h
@@ -69,7 +69,7 @@
   // Sets further read requests to return EOS buffers.
   void SeekToEndOfStream();
 
-  // Sets the splice timestamp for all furture buffers returned via Read().
+  // Sets the splice timestamp for all future buffers returned via Read().
   void set_splice_timestamp(base::TimeDelta splice_timestamp) {
     splice_timestamp_ = splice_timestamp;
   }
diff --git a/src/cobalt/media/base/key_systems.cc b/src/cobalt/media/base/key_systems.cc
index a211ede..4f6e697 100644
--- a/src/cobalt/media/base/key_systems.cc
+++ b/src/cobalt/media/base/key_systems.cc
@@ -362,7 +362,7 @@
       continue;
     }
 
-    // Supporting persistent state is a prerequsite for supporting persistent
+    // Supporting persistent state is a prerequisite for supporting persistent
     // sessions.
     if (properties->GetPersistentStateSupport() ==
         EmeFeatureSupport::NOT_SUPPORTED) {
diff --git a/src/cobalt/media/base/media_permission.h b/src/cobalt/media/base/media_permission.h
index 19179f4..299164a 100644
--- a/src/cobalt/media/base/media_permission.h
+++ b/src/cobalt/media/base/media_permission.h
@@ -28,14 +28,14 @@
   MediaPermission();
   virtual ~MediaPermission();
 
-  // Checks whether |type| is permitted for |security_origion| without
+  // Checks whether |type| is permitted for |security_origin| without
   // triggering user interaction (e.g. permission prompt). The status will be
   // |false| if the permission has never been set.
   virtual void HasPermission(
       Type type, const GURL& security_origin,
       const PermissionStatusCB& permission_status_cb) = 0;
 
-  // Requests |type| permission for |security_origion|. This may trigger user
+  // Requests |type| permission for |security_origin|. This may trigger user
   // interaction (e.g. permission prompt) if the permission has never been set.
   virtual void RequestPermission(
       Type type, const GURL& security_origin,
diff --git a/src/cobalt/media/base/pipeline.h b/src/cobalt/media/base/pipeline.h
index c2bbcfc..13ae02f 100644
--- a/src/cobalt/media/base/pipeline.h
+++ b/src/cobalt/media/base/pipeline.h
@@ -51,7 +51,8 @@
 // playing.
 class MEDIA_EXPORT Pipeline : public base::RefCountedThreadSafe<Pipeline> {
  public:
-  typedef base::Callback<void(PipelineStatus status, bool is_initial_preroll)>
+  typedef base::Callback<void(PipelineStatus status, bool is_initial_preroll,
+                              const std::string& error_message)>
       SeekCB;
 
   // Return true if the punch through box should be rendered.  Return false if
@@ -179,7 +180,7 @@
 
   // Attempt to set the volume of the audio renderer.  Valid values for volume
   // range from 0.0f (muted) to 1.0f (full volume).  This value affects all
-  // channels proportionately for multi-channel audio streams.
+  // channels proportionally for multi-channel audio streams.
   virtual void SetVolume(float volume) = 0;
 
   // Returns the current media playback time, which progresses from 0 until
diff --git a/src/cobalt/media/base/playback_statistics.cc b/src/cobalt/media/base/playback_statistics.cc
index 9559724..c35a451 100644
--- a/src/cobalt/media/base/playback_statistics.cc
+++ b/src/cobalt/media/base/playback_statistics.cc
@@ -73,41 +73,42 @@
   }
 }
 
-}  // namespace
-
-PlaybackStatistics::Record::Record(const VideoDecoderConfig& video_config) {
-  SbAtomicNoBarrier_Increment(&s_active_instances, 1);
-
-  UpdateMaxValue(s_active_instances, &s_max_active_instances);
-
-  if (video_config.codec() == kCodecAV1) {
-    SbAtomicBarrier_Increment(&s_av1_played, 1);
-  } else if (video_config.codec() == kCodecH264) {
-    SbAtomicBarrier_Increment(&s_h264_played, 1);
-  } else if (video_config.codec() == kCodecHEVC) {
-    SbAtomicBarrier_Increment(&s_hevc_played, 1);
-  } else if (video_config.codec() == kCodecVP9) {
-    SbAtomicBarrier_Increment(&s_vp9_played, 1);
-  } else {
-    SB_NOTREACHED();
-  }
-
-  OnConfigChange(video_config);
+std::string ToString(const base::Optional<base::TimeDelta>& t) {
+  return (t) ? starboard::FormatString("%" PRId64, t->InMicroseconds()) : "n/a";
 }
 
-PlaybackStatistics::Record::~Record() {
+}  // namespace
+
+PlaybackStatistics::~PlaybackStatistics() {
   SbAtomicNoBarrier_Increment(&s_active_instances, -1);
 }
 
-void PlaybackStatistics::Record::OnPresenting(
+void PlaybackStatistics::UpdateVideoConfig(
     const VideoDecoderConfig& video_config) {
-  SbAtomicNoBarrier_Store(&s_last_working_codec, video_config.codec());
-}
+  if (is_initial_config_) {
+    is_initial_config_ = false;
 
-void PlaybackStatistics::Record::OnConfigChange(
-    const VideoDecoderConfig& video_config) {
-  auto width = static_cast<SbAtomic32>(video_config.natural_size().width());
-  auto height = static_cast<SbAtomic32>(video_config.natural_size().height());
+    SbAtomicNoBarrier_Increment(&s_active_instances, 1);
+
+    UpdateMaxValue(s_active_instances, &s_max_active_instances);
+
+    if (video_config.codec() == kCodecAV1) {
+      SbAtomicBarrier_Increment(&s_av1_played, 1);
+    } else if (video_config.codec() == kCodecH264) {
+      SbAtomicBarrier_Increment(&s_h264_played, 1);
+    } else if (video_config.codec() == kCodecHEVC) {
+      SbAtomicBarrier_Increment(&s_hevc_played, 1);
+    } else if (video_config.codec() == kCodecVP9) {
+      SbAtomicBarrier_Increment(&s_vp9_played, 1);
+    } else {
+      SB_NOTREACHED();
+    }
+  }
+
+  const auto width =
+      static_cast<SbAtomic32>(video_config.natural_size().width());
+  const auto height =
+      static_cast<SbAtomic32>(video_config.natural_size().height());
 
   UpdateMinValue(width, &s_min_video_width);
   UpdateMaxValue(width, &s_max_video_width);
@@ -115,17 +116,48 @@
   UpdateMaxValue(height, &s_max_video_height);
 
   LOG(INFO) << "Playback statistics on config change: "
-            << PlaybackStatistics::GetStatistics(video_config);
+            << GetStatistics(video_config);
 }
 
-// static
+
+void PlaybackStatistics::OnPresenting(const VideoDecoderConfig& video_config) {
+  SbAtomicNoBarrier_Store(&s_last_working_codec, video_config.codec());
+}
+
+void PlaybackStatistics::OnSeek(const base::TimeDelta& seek_time) {
+  seek_time_ = seek_time;
+  first_written_audio_timestamp_.reset();
+  first_written_video_timestamp_.reset();
+}
+
+void PlaybackStatistics::OnAudioAU(const base::TimeDelta& timestamp) {
+  last_written_audio_timestamp_ = timestamp;
+  if (!first_written_audio_timestamp_) {
+    first_written_audio_timestamp_.emplace(timestamp);
+  }
+}
+
+void PlaybackStatistics::OnVideoAU(const base::TimeDelta& timestamp) {
+  last_written_video_timestamp_ = timestamp;
+  if (!first_written_video_timestamp_) {
+    first_written_video_timestamp_.emplace(timestamp);
+  }
+}
+
 std::string PlaybackStatistics::GetStatistics(
-    const VideoDecoderConfig& current_video_config) {
+    const VideoDecoderConfig& current_video_config) const {
   return starboard::FormatString(
       "current_codec: %s, drm: %s, width: %d, height: %d,"
       " active_players (max): %d (%d), av1: ~%d, h264: ~%d, hevc: ~%d,"
       " vp9: ~%d, min_width: %d, min_height: %d, max_width: %d, max_height: %d,"
-      " last_working_codec: %s",
+      " last_working_codec: %s,"
+      " seek_time: %" PRId64
+      ","
+      " first_audio_time: %s,"
+      " first_video_time: %s,"
+      " last_audio_time: %" PRId64
+      ","
+      " last_video_time: %" PRId64,
       GetCodecName(current_video_config.codec()).c_str(),
       (current_video_config.is_encrypted() ? "Y" : "N"),
       static_cast<int>(current_video_config.natural_size().width()),
@@ -142,7 +174,12 @@
       SbAtomicNoBarrier_Load(&s_max_video_height),
       GetCodecName(static_cast<VideoCodec>(
                        SbAtomicNoBarrier_Load(&s_last_working_codec)))
-          .c_str());
+          .c_str(),
+      seek_time_.InMicroseconds(),
+      ToString(first_written_audio_timestamp_).c_str(),
+      ToString(first_written_audio_timestamp_).c_str(),
+      last_written_audio_timestamp_.InMicroseconds(),
+      last_written_video_timestamp_.InMicroseconds());
 }
 
 }  // namespace media
diff --git a/src/cobalt/media/base/playback_statistics.h b/src/cobalt/media/base/playback_statistics.h
index cb3109a..9cbb562 100644
--- a/src/cobalt/media/base/playback_statistics.h
+++ b/src/cobalt/media/base/playback_statistics.h
@@ -17,6 +17,8 @@
 
 #include <string>
 
+#include "base/optional.h"
+#include "base/time/time.h"
 #include "cobalt/media/base/video_decoder_config.h"
 
 namespace cobalt {
@@ -24,18 +26,24 @@
 
 class PlaybackStatistics {
  public:
-  class Record {
-   public:
-    // TODO: Implement record for audio streams.
-    explicit Record(const VideoDecoderConfig& video_config);
-    ~Record();
+  ~PlaybackStatistics();
 
-    void OnPresenting(const VideoDecoderConfig& video_config);
-    void OnConfigChange(const VideoDecoderConfig& video_config);
-  };
+  void UpdateVideoConfig(const VideoDecoderConfig& video_config);
+  void OnPresenting(const VideoDecoderConfig& video_config);
+  void OnSeek(const base::TimeDelta& seek_time);
+  void OnAudioAU(const base::TimeDelta& timestamp);
+  void OnVideoAU(const base::TimeDelta& timestamp);
 
-  static std::string GetStatistics(
-      const VideoDecoderConfig& current_video_config);
+  std::string GetStatistics(
+      const VideoDecoderConfig& current_video_config) const;
+
+ private:
+  base::TimeDelta seek_time_;
+  base::Optional<base::TimeDelta> first_written_audio_timestamp_;
+  base::Optional<base::TimeDelta> first_written_video_timestamp_;
+  base::TimeDelta last_written_audio_timestamp_;
+  base::TimeDelta last_written_video_timestamp_;
+  bool is_initial_config_ = true;
 };
 
 }  // namespace media
diff --git a/src/cobalt/media/base/ranges_unittest.cc b/src/cobalt/media/base/ranges_unittest.cc
index 34e4ea3..02d0af8 100644
--- a/src/cobalt/media/base/ranges_unittest.cc
+++ b/src/cobalt/media/base/ranges_unittest.cc
@@ -115,7 +115,7 @@
   ASSERT_RANGES(a.IntersectionWith(b), "{ }");
   ASSERT_RANGES(b.IntersectionWith(a), "{ }");
 
-  // Test intersections with a completely overlaping range.
+  // Test intersections with a completely overlapping range.
   ASSERT_EQ(b.Add(-1, 13), 1u) << b;
   ASSERT_RANGES(a, "{ [0,1) [4,7) [10,12) }");
   ASSERT_RANGES(b, "{ [-1,13) }");
diff --git a/src/cobalt/media/base/sbplayer_pipeline.cc b/src/cobalt/media/base/sbplayer_pipeline.cc
index e6a9803..5ca7e82 100644
--- a/src/cobalt/media/base/sbplayer_pipeline.cc
+++ b/src/cobalt/media/base/sbplayer_pipeline.cc
@@ -42,6 +42,7 @@
 #include "cobalt/media/base/sbplayer_set_bounds_helper.h"
 #include "cobalt/media/base/starboard_player.h"
 #include "cobalt/media/base/video_decoder_config.h"
+#include "starboard/common/string.h"
 #include "starboard/configuration_constants.h"
 
 namespace cobalt {
@@ -143,7 +144,7 @@
   void SetPlaybackRateTask(float volume);
   void SetDurationTask(TimeDelta duration);
 
-  // DemuxerHost implementaion.
+  // DemuxerHost implementation.
   void OnBufferedTimeRangesChanged(
       const Ranges<base::TimeDelta>& ranges) override;
   void SetDuration(TimeDelta duration) override;
@@ -175,7 +176,8 @@
   void DelayedNeedData();
 
   void UpdateDecoderConfig(DemuxerStream* stream);
-  void CallSeekCB(PipelineStatus status);
+  void CallSeekCB(PipelineStatus status, const std::string& error_message);
+  void CallErrorCB(PipelineStatus status, const std::string& error_message);
 
   void SuspendTask(base::WaitableEvent* done_event);
   void ResumeTask(PipelineWindow window, base::WaitableEvent* done_event);
@@ -184,6 +186,9 @@
   // estimate and avoid calling SbPlayerGetInfo too frequently.
   void StoreMediaTime(TimeDelta media_time);
 
+  // Retrieve the statistics as a string and append to message.
+  std::string AppendStatisticsString(const std::string& message) const;
+
   // Message loop used to execute pipeline tasks.  It is thread-safe.
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
@@ -191,7 +196,7 @@
   const bool allow_resume_after_suspend_;
 
   // The window this player associates with.  It should only be assigned in the
-  // dtor and accesed once by SbPlayerCreate().
+  // dtor and accessed once by SbPlayerCreate().
   PipelineWindow window_;
 
   // Call to get the SbDecodeTargetGraphicsContextProvider for SbPlayerCreate().
@@ -300,7 +305,7 @@
   // The maximum video playback capabilities required for the playback.
   std::string max_video_capabilities_;
 
-  base::Optional<PlaybackStatistics::Record> statistics_record_;
+  PlaybackStatistics playback_statistics_;
 
   DISALLOW_COPY_AND_ASSIGN(SbPlayerPipeline);
 };
@@ -507,8 +512,12 @@
     return;
   }
 
+  playback_statistics_.OnSeek(time);
+
   if (!player_) {
-    seek_cb.Run(PIPELINE_ERROR_INVALID_STATE, false);
+    seek_cb.Run(PIPELINE_ERROR_INVALID_STATE, false,
+                AppendStatisticsString("SbPlayerPipeline::Seek failed: "
+                                       "player_ is nullptr."));
     return;
   }
 
@@ -814,7 +823,7 @@
   }
 
   if (error != PIPELINE_OK) {
-    ResetAndRunIfNotNull(&error_cb_, error, "Demuxer error.");
+    CallErrorCB(error, "Demuxer error.");
   }
 }
 
@@ -871,7 +880,9 @@
   }
 
   player_.reset();
-  CallSeekCB(DECODER_ERROR_NOT_SUPPORTED);
+  CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
+             "SbPlayerPipeline::CreateUrlPlayer failed: "
+             "player_->IsValid() is false.");
 }
 
 void SbPlayerPipeline::SetDrmSystem(SbDrmSystem drm_system) {
@@ -924,11 +935,17 @@
                     : invalid_video_config;
 
   if (video_stream_) {
-    statistics_record_.emplace(video_stream_->video_decoder_config());
+    playback_statistics_.UpdateVideoConfig(
+        video_stream_->video_decoder_config());
   }
 
   {
     base::AutoLock auto_lock(lock_);
+    SB_DCHECK(!player_);
+    // In the extreme case that CreatePlayer() is called when a |player_| is
+    // available, reset the existing player first to reduce the number of active
+    // players.
+    player_.reset();
     player_.reset(new StarboardPlayer(
         task_runner_, get_decode_target_graphics_context_provider_func_,
         audio_config, video_config, window_, drm_system, this,
@@ -958,7 +975,9 @@
   }
 
   player_.reset();
-  CallSeekCB(DECODER_ERROR_NOT_SUPPORTED);
+  CallSeekCB(DECODER_ERROR_NOT_SUPPORTED,
+             "SbPlayerPipeline::CreatePlayer failed: "
+             "player_->IsValid() is false.");
 }
 
 void SbPlayerPipeline::OnDemuxerInitialized(PipelineStatus status) {
@@ -974,7 +993,7 @@
   }
 
   if (status != PIPELINE_OK) {
-    ResetAndRunIfNotNull(&error_cb_, status, "Demuxer initialization error.");
+    CallErrorCB(status, "Demuxer initialization error.");
     return;
   }
 
@@ -991,9 +1010,8 @@
 
   if (audio_stream == NULL && video_stream == NULL) {
     LOG(INFO) << "The video has to contain an audio track or a video track.";
-    ResetAndRunIfNotNull(
-        &error_cb_, DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
-        "The video has to contain an audio track or a video track.");
+    CallErrorCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS,
+                "The video has to contain an audio track or a video track.");
     return;
   }
 
@@ -1082,7 +1100,7 @@
       video_read_in_progress_ = false;
     }
     if (!seek_cb_.is_null()) {
-      CallSeekCB(PIPELINE_OK);
+      CallSeekCB(PIPELINE_OK, "");
     }
     return;
   }
@@ -1097,10 +1115,14 @@
   if (type == DemuxerStream::AUDIO) {
     audio_read_in_progress_ = false;
     if (!buffer->end_of_stream()) {
+      playback_statistics_.OnAudioAU(buffer->timestamp());
       timestamp_of_last_written_audio_ = buffer->timestamp().ToSbTime();
     }
   } else {
     video_read_in_progress_ = false;
+    if (!buffer->end_of_stream()) {
+      playback_statistics_.OnVideoAU(buffer->timestamp());
+    }
   }
 
   player_->WriteBuffer(type, buffer);
@@ -1208,11 +1230,11 @@
 #endif  // SB_HAS(PLAYER_WITH_URL)
       buffering_state_cb_.Run(kPrerollCompleted);
       if (!seek_cb_.is_null()) {
-        CallSeekCB(PIPELINE_OK);
+        CallSeekCB(PIPELINE_OK, "");
       }
-      if (statistics_record_) {
-        SB_DCHECK(video_stream_);
-        statistics_record_->OnPresenting(video_stream_->video_decoder_config());
+      if (video_stream_) {
+        playback_statistics_.OnPresenting(
+            video_stream_->video_decoder_config());
       }
       break;
     }
@@ -1239,27 +1261,22 @@
     DCHECK(is_url_based_);
     switch (static_cast<SbUrlPlayerError>(error)) {
       case kSbUrlPlayerErrorNetwork:
-        ResetAndRunIfNotNull(&error_cb_, PIPELINE_ERROR_NETWORK, message);
+        CallErrorCB(PIPELINE_ERROR_NETWORK, message);
         break;
       case kSbUrlPlayerErrorSrcNotSupported:
-        ResetAndRunIfNotNull(&error_cb_, DEMUXER_ERROR_COULD_NOT_OPEN, message);
+        CallErrorCB(DEMUXER_ERROR_COULD_NOT_OPEN, message);
+
         break;
     }
     return;
   }
 #endif  // SB_HAS(PLAYER_WITH_URL)
-
-  auto statistics = video_stream_ ? PlaybackStatistics::GetStatistics(
-                                        video_stream_->video_decoder_config())
-                                  : "n/a";
   switch (error) {
     case kSbPlayerErrorDecode:
-      ResetAndRunIfNotNull(&error_cb_, PIPELINE_ERROR_DECODE,
-                           message + ", statistics: " + statistics);
+      CallErrorCB(PIPELINE_ERROR_DECODE, message);
       break;
     case kSbPlayerErrorCapabilityChanged:
-      ResetAndRunIfNotNull(&error_cb_, PLAYBACK_CAPABILITY_CHANGED,
-                           message + ", statistics: " + statistics);
+      CallErrorCB(PLAYBACK_CAPABILITY_CHANGED, message);
       break;
 #if SB_API_VERSION >= 11
     case kSbPlayerErrorMax:
@@ -1295,12 +1312,16 @@
       content_size_change_cb_.Run();
     }
 
-    DCHECK(statistics_record_);
-    statistics_record_->OnConfigChange(stream->video_decoder_config());
+    playback_statistics_.UpdateVideoConfig(stream->video_decoder_config());
   }
 }
 
-void SbPlayerPipeline::CallSeekCB(PipelineStatus status) {
+void SbPlayerPipeline::CallSeekCB(PipelineStatus status,
+                                  const std::string& error_message) {
+  if (status == PIPELINE_OK) {
+    DCHECK(error_message.empty());
+  }
+
   SeekCB seek_cb;
   bool is_initial_preroll;
   {
@@ -1310,7 +1331,15 @@
     is_initial_preroll = is_initial_preroll_;
     is_initial_preroll_ = false;
   }
-  seek_cb.Run(status, is_initial_preroll);
+  seek_cb.Run(status, is_initial_preroll,
+              AppendStatisticsString(error_message));
+}
+
+void SbPlayerPipeline::CallErrorCB(PipelineStatus status,
+                                   const std::string& error_message) {
+  DCHECK_NE(status, PIPELINE_OK);
+  ResetAndRunIfNotNull(&error_cb_, status,
+                       AppendStatisticsString(error_message));
 }
 
 void SbPlayerPipeline::SuspendTask(base::WaitableEvent* done_event) {
@@ -1357,6 +1386,18 @@
   done_event->Signal();
 }
 
+std::string SbPlayerPipeline::AppendStatisticsString(
+    const std::string& message) const {
+  if (nullptr == video_stream_) {
+    return message + ", playback statistics: n/a.";
+  } else {
+    return message + ", playback statistics: " +
+           playback_statistics_.GetStatistics(
+               video_stream_->video_decoder_config()) +
+           '.';
+  }
+}
+
 }  // namespace
 
 // static
diff --git a/src/cobalt/media/base/starboard_player.cc b/src/cobalt/media/base/starboard_player.cc
index d7eeb2e..010d294 100644
--- a/src/cobalt/media/base/starboard_player.cc
+++ b/src/cobalt/media/base/starboard_player.cc
@@ -23,6 +23,7 @@
 #include "base/logging.h"
 #include "base/trace_event/trace_event.h"
 #include "cobalt/media/base/starboard_utils.h"
+#include "starboard/common/media.h"
 #include "starboard/configuration.h"
 #include "starboard/memory.h"
 
@@ -189,10 +190,12 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(audio_config.IsValidConfig());
 
-  LOG(INFO) << "New audio config -- " << audio_config.AsHumanReadableString();
+  LOG(INFO) << "Updated AudioDecoderConfig -- "
+            << audio_config.AsHumanReadableString();
 
   audio_config_ = audio_config;
   audio_sample_info_ = MediaAudioConfigToSbMediaAudioSampleInfo(audio_config_);
+  LOG(INFO) << "Converted to SbMediaAudioSampleInfo -- " << audio_sample_info_;
 }
 
 void StarboardPlayer::UpdateVideoConfig(
@@ -200,7 +203,8 @@
   DCHECK(task_runner_->BelongsToCurrentThread());
   DCHECK(video_config.IsValidConfig());
 
-  LOG(INFO) << "New video config -- " << video_config.AsHumanReadableString();
+  LOG(INFO) << "Updated VideoDecoderConfig -- "
+            << video_config.AsHumanReadableString();
 
   video_config_ = video_config;
   video_sample_info_.frame_width =
@@ -221,6 +225,7 @@
   video_sample_info_.mime = video_config_.mime().c_str();
   video_sample_info_.max_video_capabilities = max_video_capabilities_.c_str();
 #endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
+  LOG(INFO) << "Converted to SbMediaVideoSampleInfo -- " << video_sample_info_;
 }
 
 void StarboardPlayer::WriteBuffer(DemuxerStream::Type type,
@@ -542,7 +547,7 @@
   TRACE_EVENT0("cobalt::media", "StarboardPlayer::CreatePlayer");
   DCHECK(task_runner_->BelongsToCurrentThread());
 
-bool is_visible = SbWindowIsValid(window_);
+  bool is_visible = SbWindowIsValid(window_);
 #if SB_API_VERSION >= 11
   SbMediaAudioCodec audio_codec = audio_sample_info_.codec;
   SbMediaVideoCodec video_codec = kSbMediaVideoCodecNone;
@@ -592,17 +597,15 @@
     DCHECK(audio_codec != kSbMediaAudioCodecNone);
   }
   player_ = SbPlayerCreate(
-      window_, video_codec, audio_codec,
-      drm_system_, has_audio ? &audio_sample_info_ : NULL,
+      window_, video_codec, audio_codec, drm_system_,
+      has_audio ? &audio_sample_info_ : NULL,
 #if SB_API_VERSION >= 11
       max_video_capabilities_.length() > 0 ? max_video_capabilities_.c_str()
                                            : NULL,
 #endif  // SB_API_VERSION >= 11
       &StarboardPlayer::DeallocateSampleCB, &StarboardPlayer::DecoderStatusCB,
-      &StarboardPlayer::PlayerStatusCB,
-      &StarboardPlayer::PlayerErrorCB,
-      this, output_mode_,
-      get_decode_target_graphics_context_provider_func_.Run());
+      &StarboardPlayer::PlayerStatusCB, &StarboardPlayer::PlayerErrorCB, this,
+      output_mode_, get_decode_target_graphics_context_provider_func_.Run());
 
 #endif  // SB_HAS(PLAYER_CREATION_AND_OUTPUT_MODE_QUERY_IMPROVEMENT)
 
@@ -699,7 +702,7 @@
     sample_info.drm_info = NULL;
   }
   SbPlayerWriteSample2(player_, sample_type, &sample_info, 1);
-#else  // SB_API_VERSION >= 11
+#else   // SB_API_VERSION >= 11
   video_sample_info_.is_key_frame = buffer->is_key_frame();
   DCHECK_GT(SbPlayerGetMaximumNumberOfSamplesPerWrite(player_, sample_type), 0);
   SbPlayerSampleInfo sample_info = {
diff --git a/src/cobalt/media/base/starboard_player.h b/src/cobalt/media/base/starboard_player.h
index b4c1581..b78a90f 100644
--- a/src/cobalt/media/base/starboard_player.h
+++ b/src/cobalt/media/base/starboard_player.h
@@ -207,7 +207,7 @@
   SbPlayerOutputMode ComputeSbPlayerOutputMode(
       bool prefer_decode_to_texture) const;
 
-  // The following variables are initialized in the ctor and never changed.
+// The following variables are initialized in the ctor and never changed.
 #if SB_HAS(PLAYER_WITH_URL)
   std::string url_;
 #endif  // SB_HAS(PLAYER_WITH_URL)
@@ -256,7 +256,7 @@
 
   VideoFrameProvider* const video_frame_provider_;
 
-  // A string of video maxmium capabilities.
+  // A string of video maximum capabilities.
   std::string max_video_capabilities_;
 
 #if SB_HAS(PLAYER_WITH_URL)
diff --git a/src/cobalt/media/base/vector_math_unittest.cc b/src/cobalt/media/base/vector_math_unittest.cc
index 840689e..abe87d5 100644
--- a/src/cobalt/media/base/vector_math_unittest.cc
+++ b/src/cobalt/media/base/vector_math_unittest.cc
@@ -285,7 +285,7 @@
         EWMATestScenario(0.0f, kOnes, 32, 0.0f).HasExpectedResult(0.0f, 1.0f),
         EWMATestScenario(1.0f, kZeros, 32, 0.0f).HasExpectedResult(1.0f, 0.0f),
 
-        // Smothing factor of one: Result = last sample squared.
+        // Smoothing factor of one: Result = last sample squared.
         EWMATestScenario(0.0f, kCheckerboard, 32, 1.0f)
             .ScaledBy(2.0f)
             .HasExpectedResult(4.0f, 4.0f),
@@ -356,7 +356,7 @@
         EWMATestScenario(0.0f, kInverseCheckerboard, 15, 0.25f)
             .HasExpectedResult(0.56570137f, 1.0f),
 
-        // Smoothing factor of 1/4, impluse signal.
+        // Smoothing factor of 1/4, impulse signal.
         EWMATestScenario(0.0f, kZeros, 3, 0.25f)
             .WithImpulse(2.0f, 0)
             .HasExpectedResult(0.562500f, 4.0f),
diff --git a/src/cobalt/media/base/video_frame.cc b/src/cobalt/media/base/video_frame.cc
index af86dda..5d739ab 100644
--- a/src/cobalt/media/base/video_frame.cc
+++ b/src/cobalt/media/base/video_frame.cc
@@ -67,7 +67,7 @@
   return "INVALID";
 }
 
-// Returns true if |frame| is accesible mapped in the VideoFrame memory space.
+// Returns true if |frame| is accessible mapped in the VideoFrame memory space.
 // static
 static bool IsStorageTypeMappable(VideoFrame::StorageType storage_type) {
   return
diff --git a/src/cobalt/media/base/video_util.h b/src/cobalt/media/base/video_util.h
index 9a75ff7..dc2ad9f 100644
--- a/src/cobalt/media/base/video_util.h
+++ b/src/cobalt/media/base/video_util.h
@@ -90,9 +90,9 @@
     const scoped_refptr<VideoFrame>& frame);
 
 // Copy I420 video frame to match the required coded size and pad the region
-// outside the visible rect repeatly with the last column / row up to the coded
-// size of |dst_frame|. Return false when |dst_frame| is empty or visible rect
-// is empty.
+// outside the visible rect repeatedly with the last column / row up to the
+// coded size of |dst_frame|. Return false when |dst_frame| is empty or visible
+// rect is empty.
 // One application is content mirroring using HW encoder. As the required coded
 // size for encoder is unknown before capturing, memory copy is needed when the
 // coded size does not match the requirement. Padding can improve the encoding
diff --git a/src/cobalt/media/base/video_util_unittest.cc b/src/cobalt/media/base/video_util_unittest.cc
index e485aad..44cd554 100644
--- a/src/cobalt/media/base/video_util_unittest.cc
+++ b/src/cobalt/media/base/video_util_unittest.cc
@@ -29,7 +29,7 @@
 // Create a VideoFrame and initialize the visible rect using
 // |FillPlaneWithPattern()|. For testing purpose, the VideoFrame should be
 // filled with varying values, which is different from
-// |VideoFrame::CreateColorFrame()| where the entrire VideoFrame is filled
+// |VideoFrame::CreateColorFrame()| where the entire VideoFrame is filled
 // with a given color.
 scoped_refptr<media::VideoFrame> CreateFrameWithPatternFilled(
     media::VideoPixelFormat format, const math::Size& coded_size,
diff --git a/src/cobalt/media/base/yuv_convert.h b/src/cobalt/media/base/yuv_convert.h
index 28a39ae..9e94632 100644
--- a/src/cobalt/media/base/yuv_convert.h
+++ b/src/cobalt/media/base/yuv_convert.h
@@ -85,7 +85,7 @@
                                   int uvstride, int rgbstride, YUVType yuv_type,
                                   Rotate view_rotate, ScaleFilter filter);
 
-// Biliner Scale a frame of YV12 to 32 bits ARGB on a specified rectangle.
+// Bilinear Scale a frame of YV12 to 32 bits ARGB on a specified rectangle.
 // |yplane|, etc and |rgbframe| should point to the top-left pixels of the
 // source and destination buffers.
 MEDIA_EXPORT void ScaleYUVToRGB32WithRect(
diff --git a/src/cobalt/media/decoder_buffer_allocator.cc b/src/cobalt/media/decoder_buffer_allocator.cc
index 8a70a3b..7c83911 100644
--- a/src/cobalt/media/decoder_buffer_allocator.cc
+++ b/src/cobalt/media/decoder_buffer_allocator.cc
@@ -213,7 +213,7 @@
   *allocate_from_front = context == 1;
   if (*allocate_from_front) {
     for (FreeBlockSet::iterator it = begin; it != end; ++it) {
-      if (it->CanFullfill(1, alignment)) {
+      if (it->CanFulfill(1, alignment)) {
         return it;
       }
     }
@@ -224,7 +224,7 @@
   FreeBlockSet::reverse_iterator rbegin(end);
   FreeBlockSet::reverse_iterator rend(begin);
   for (FreeBlockSet::reverse_iterator it = rbegin; it != rend; ++it) {
-    if (it->CanFullfill(1, alignment)) {
+    if (it->CanFulfill(1, alignment)) {
       return --it.base();
     }
   }
diff --git a/src/cobalt/media/fetcher_buffered_data_source.h b/src/cobalt/media/fetcher_buffered_data_source.h
index 7fcc3e0..fb589a1 100644
--- a/src/cobalt/media/fetcher_buffered_data_source.h
+++ b/src/cobalt/media/fetcher_buffered_data_source.h
@@ -65,7 +65,7 @@
   FetcherBufferedDataSource(
       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
       const GURL& url, const csp::SecurityCallback& security_callback,
-      network::NetworkModule* network_module, loader::RequestMode requset_mode,
+      network::NetworkModule* network_module, loader::RequestMode request_mode,
       loader::Origin origin);
   ~FetcherBufferedDataSource() override;
 
diff --git a/src/cobalt/media/filters/chunk_demuxer.cc b/src/cobalt/media/filters/chunk_demuxer.cc
index e88c81d..cf5a4bd 100644
--- a/src/cobalt/media/filters/chunk_demuxer.cc
+++ b/src/cobalt/media/filters/chunk_demuxer.cc
@@ -179,7 +179,7 @@
   if (type_ == TEXT) {
     // Since text tracks are discontinuous and the lack of cues should not block
     // playback, report the buffered range for text tracks as [0, |duration|) so
-    // that intesections with audio & video tracks are computed correctly when
+    // that intersections with audio & video tracks are computed correctly when
     // no cues are present.
     Ranges<TimeDelta> text_range;
     text_range.Add(TimeDelta(), duration);
diff --git a/src/cobalt/media/filters/ivf_parser.h b/src/cobalt/media/filters/ivf_parser.h
index 069d9ea..50054c7 100644
--- a/src/cobalt/media/filters/ivf_parser.h
+++ b/src/cobalt/media/filters/ivf_parser.h
@@ -16,7 +16,7 @@
 
 #pragma pack(push, 1)
 struct MEDIA_EXPORT IvfFileHeader {
-  // Byte swap interger fields between native and (on disk) little endian.
+  // Byte swap integer fields between native and (on disk) little endian.
   void ByteSwap();
 
   char signature[4];        // signature: 'DKIF'
@@ -38,7 +38,7 @@
     "sizeof(IvfFileHeader) must be fixed since it will be used with file IO");
 
 struct MEDIA_EXPORT IvfFrameHeader {
-  // Byte swap interger fields between native and (on disk) little endian.
+  // Byte swap integer fields between native and (on disk) little endian.
   void ByteSwap();
 
   uint32_t frame_size;  // Size of frame in bytes (not including the header)
diff --git a/src/cobalt/media/filters/source_buffer_range.h b/src/cobalt/media/filters/source_buffer_range.h
index 6374159..cd23779 100644
--- a/src/cobalt/media/filters/source_buffer_range.h
+++ b/src/cobalt/media/filters/source_buffer_range.h
@@ -82,7 +82,7 @@
   // The first buffer in |range| must come directly after the last buffer
   // in this range.
   // If |transfer_current_position| is true, |range|'s |next_buffer_index_|
-  // is transfered to this SourceBufferRange.
+  // is transferred to this SourceBufferRange.
   // Note: Use these only to merge existing ranges. |range|'s first buffer
   // timestamp must be adjacent to this range. No group start timestamp
   // adjacency is involved in these methods.
diff --git a/src/cobalt/media/filters/source_buffer_stream.h b/src/cobalt/media/filters/source_buffer_stream.h
index 57f194b..85ea203 100644
--- a/src/cobalt/media/filters/source_buffer_stream.h
+++ b/src/cobalt/media/filters/source_buffer_stream.h
@@ -375,7 +375,7 @@
 
   // Sets |selected_range_| and seeks to the nearest keyframe after
   // |timestamp| if necessary and possible. This method only attempts to
-  // set |selected_range_| if |seleted_range_| is null and |track_buffer_|
+  // set |selected_range_| if |selected_range_| is null and |track_buffer_|
   // is empty.
   void SetSelectedRangeIfNeeded(const DecodeTimestamp timestamp);
 
diff --git a/src/cobalt/media/filters/source_buffer_stream_unittest.cc b/src/cobalt/media/filters/source_buffer_stream_unittest.cc
index e6e286b..631dac1 100644
--- a/src/cobalt/media/filters/source_buffer_stream_unittest.cc
+++ b/src/cobalt/media/filters/source_buffer_stream_unittest.cc
@@ -1099,7 +1099,7 @@
   // Now replace the last 5 buffers with new data.
   NewCodedFrameGroupAppend(10, 5, &kDataB);
 
-  // The next 4 buffers should be the origial data, held in the track buffer.
+  // The next 4 buffers should be the original data, held in the track buffer.
   CheckExpectedBuffers(11, 14, &kDataA);
 
   // The next buffer is at position 15, so we should fail to fulfill the
@@ -2195,7 +2195,7 @@
   // Next buffer is at position 10, so should not be able to fulfill request.
   CheckNoNextBuffer();
 
-  // Append 6 buffers at positons 5 through 10. This is to test that doing a
+  // Append 6 buffers at positions 5 through 10. This is to test that doing a
   // start-overlap successfully fulfills the read at position 10, even though
   // position 10 was unbuffered.
   NewCodedFrameGroupAppend(5, 6, &kDataB);
diff --git a/src/cobalt/media/filters/vp8_bool_decoder.h b/src/cobalt/media/filters/vp8_bool_decoder.h
index 6d7536b..c13bce8 100644
--- a/src/cobalt/media/filters/vp8_bool_decoder.h
+++ b/src/cobalt/media/filters/vp8_bool_decoder.h
@@ -81,7 +81,7 @@
   bool ReadLiteral(size_t num_bits, int* out);
 
   // Reads a literal with sign from the coded stream. This is similar to
-  // the ReadListeral(), it first read a "num_bits"-wide unsigned value, and
+  // the ReadLiteral(), it first read a "num_bits"-wide unsigned value, and
   // then read an extra bit as the sign of the literal. Returns false if it has
   // reached the end of |data| and failed to read the literal or the sign.
   // This is different from the "read_signed_literal(d, n)" defined in RFC 6386.
diff --git a/src/cobalt/media/filters/wsola_internals.h b/src/cobalt/media/filters/wsola_internals.h
index 4d96b39..58ad8dc 100644
--- a/src/cobalt/media/filters/wsola_internals.h
+++ b/src/cobalt/media/filters/wsola_internals.h
@@ -57,7 +57,7 @@
 // is most similar to |target_block|. |energy_target_block| is the energy of the
 // |target_block|. |energy_candidate_blocks| is the energy of all blocks within
 // |search_block|.
-MEDIA_EXPORT int FullSearch(int low_limit, int hight_limimit,
+MEDIA_EXPORT int FullSearch(int low_limit, int high_limit,
                             Interval exclude_interval,
                             const AudioBus* target_block,
                             const AudioBus* search_block,
diff --git a/src/cobalt/media/formats/common/offset_byte_queue_unittest.cc b/src/cobalt/media/formats/common/offset_byte_queue_unittest.cc
index 7c537f1..5200ce6 100644
--- a/src/cobalt/media/formats/common/offset_byte_queue_unittest.cc
+++ b/src/cobalt/media/formats/common/offset_byte_queue_unittest.cc
@@ -77,7 +77,7 @@
   EXPECT_EQ(400 - 256, buf[0]);
 
   // Trimming to the exact end of the buffer should return 'true'. This
-  // accomodates EOS cases.
+  // accommodates EOS cases.
   EXPECT_TRUE(queue_->Trim(512));
   EXPECT_EQ(512, queue_->head());
   queue_->Peek(&buf, &size);
diff --git a/src/cobalt/media/formats/mp2t/es_adapter_video.cc b/src/cobalt/media/formats/mp2t/es_adapter_video.cc
index ecf08d4..7b3e64b 100644
--- a/src/cobalt/media/formats/mp2t/es_adapter_video.cc
+++ b/src/cobalt/media/formats/mp2t/es_adapter_video.cc
@@ -196,7 +196,7 @@
   // PTS/DTS are interpolated between the min PTS/DTS of discarded frames
   // and the PTS/DTS of the first valid buffer.
   // Note: |pts_delta| and |dts_delta| are calculated using integer division.
-  // Interpolation thus accumulutes small errors. However, since timestamps
+  // Interpolation thus accumulates small errors. However, since timestamps
   // are given in microseconds, only a high number of discarded frames
   // (in the order of 10000s) could have an impact and create a gap (from MSE
   // point of view) between the last interpolated frame and
diff --git a/src/cobalt/media/formats/mp4/aac_unittest.cc b/src/cobalt/media/formats/mp4/aac_unittest.cc
index d4362d7..86b5a56 100644
--- a/src/cobalt/media/formats/mp4/aac_unittest.cc
+++ b/src/cobalt/media/formats/mp4/aac_unittest.cc
@@ -119,7 +119,7 @@
       AudioExtensionSamplingFrequencyLog("0"), AudioChannelLayoutLog("2")));
   EXPECT_TRUE(Parse(data));
 
-  // Test w/o implict SBR.
+  // Test w/o implicit SBR.
   EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 24000);
   EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_MONO);
 
@@ -140,7 +140,7 @@
       AudioExtensionSamplingFrequencyLog("0"), AudioChannelLayoutLog("3")));
   EXPECT_TRUE(Parse(data));
 
-  // Test w/o implict SBR.
+  // Test w/o implicit SBR.
   EXPECT_EQ(aac_.GetOutputSamplesPerSecond(false), 24000);
   EXPECT_EQ(aac_.GetChannelLayout(false), CHANNEL_LAYOUT_STEREO);
 
diff --git a/src/cobalt/media/formats/mp4/box_definitions.cc b/src/cobalt/media/formats/mp4/box_definitions.cc
index 5d30892..b070a72 100644
--- a/src/cobalt/media/formats/mp4/box_definitions.cc
+++ b/src/cobalt/media/formats/mp4/box_definitions.cc
@@ -244,8 +244,7 @@
       default_iv_size(0),
       default_crypt_byte_block(0),
       default_skip_byte_block(0),
-      default_constant_iv_size(0)
-{}
+      default_constant_iv_size(0) {}
 TrackEncryption::~TrackEncryption() {}
 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }
 
@@ -259,19 +258,19 @@
          reader->ReadVec(&default_kid, kKeyIdSize));
   is_encrypted = (flag != 0);
   if (is_encrypted) {
-     if (reader->version() > 0) {
-       default_crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
-       default_skip_byte_block = possible_pattern_info & 0x0f;
-     }
-     if (default_iv_size == 0) {
-       RCHECK(reader->Read1(&default_constant_iv_size));
-       RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
-       SbMemorySet(default_constant_iv, 0, sizeof(default_constant_iv));
-       for (uint8_t i = 0; i < default_constant_iv_size; i++)
-         RCHECK(reader->Read1(default_constant_iv + i));
-     } else {
-       RCHECK(default_iv_size == 8 || default_iv_size == 16);
-     }
+    if (reader->version() > 0) {
+      default_crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
+      default_skip_byte_block = possible_pattern_info & 0x0f;
+    }
+    if (default_iv_size == 0) {
+      RCHECK(reader->Read1(&default_constant_iv_size));
+      RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
+      SbMemorySet(default_constant_iv, 0, sizeof(default_constant_iv));
+      for (uint8_t i = 0; i < default_constant_iv_size; i++)
+        RCHECK(reader->Read1(default_constant_iv + i));
+    } else {
+      RCHECK(default_iv_size == 8 || default_iv_size == 16);
+    }
   } else {
     RCHECK(default_iv_size == 0);
   }
@@ -303,10 +302,8 @@
 
 bool ProtectionSchemeInfo::HasSupportedScheme() const {
   FourCC four_cc = type.type;
-  if (four_cc == FOURCC_CENC)
-    return true;
-  if (four_cc == FOURCC_CBCS)
-    return true;
+  if (four_cc == FOURCC_CENC) return true;
+  if (four_cc == FOURCC_CBCS) return true;
   return false;
 }
 
@@ -971,7 +968,7 @@
 
   if (lang_chars[0] < 'a' || lang_chars[0] > 'z' || lang_chars[1] < 'a' ||
       lang_chars[1] > 'z' || lang_chars[2] < 'a' || lang_chars[2] > 'z') {
-    // Got unexpected characteds in ISO 639-2/T language code. Something must be
+    // Got unexpected characters in ISO 639-2/T language code. Something must be
     // wrong with the input file, report 'und' language to be safe.
     DVLOG(2) << "Ignoring MDHD language_code (non ISO 639-2 compliant): "
              << lang_chars;
@@ -1230,8 +1227,7 @@
       iv_size(0),
       crypt_byte_block(0),
       skip_byte_block(0),
-      constant_iv_size(0)
-{}
+      constant_iv_size(0) {}
 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
 
 bool CencSampleEncryptionInfoEntry::Parse(BoxReader* reader) {
diff --git a/src/cobalt/media/formats/mp4/box_definitions.h b/src/cobalt/media/formats/mp4/box_definitions.h
index 0dd974f..c885df2 100644
--- a/src/cobalt/media/formats/mp4/box_definitions.h
+++ b/src/cobalt/media/formats/mp4/box_definitions.h
@@ -82,7 +82,7 @@
 
   // Parse SampleEncryptionEntry from |reader|.
   // |iv_size| specifies the size of initialization vector. |has_subsamples|
-  // indicates whether this sample encryption entry constains subsamples.
+  // indicates whether this sample encryption entry contains subsamples.
   // Returns false if parsing fails.
   bool Parse(BufferReader* reader, uint8_t iv_size, bool has_subsamples);
 
diff --git a/src/cobalt/media/formats/mp4/box_reader.h b/src/cobalt/media/formats/mp4/box_reader.h
index 7cc5269..0be7186 100644
--- a/src/cobalt/media/formats/mp4/box_reader.h
+++ b/src/cobalt/media/formats/mp4/box_reader.h
@@ -49,7 +49,7 @@
             size_ - pos_ >= count);
   }
 
-  // Read a value from the stream, perfoming endian correction, and advance the
+  // Read a value from the stream, performing endian correction, and advance the
   // stream pointer.
   bool Read1(uint8_t* v) WARN_UNUSED_RESULT;
   bool Read2(uint16_t* v) WARN_UNUSED_RESULT;
diff --git a/src/cobalt/media/formats/mp4/mp4_stream_parser.cc b/src/cobalt/media/formats/mp4/mp4_stream_parser.cc
index 8ec8d9a..71b9b4f 100644
--- a/src/cobalt/media/formats/mp4/mp4_stream_parser.cc
+++ b/src/cobalt/media/formats/mp4/mp4_stream_parser.cc
@@ -48,8 +48,7 @@
 // Caller should be prepared to handle return of Unencrypted() in case of
 // unsupported scheme.
 EncryptionScheme GetEncryptionScheme(const ProtectionSchemeInfo& sinf) {
-  if (!sinf.HasSupportedScheme())
-    return Unencrypted();
+  if (!sinf.HasSupportedScheme()) return Unencrypted();
   FourCC fourcc = sinf.type.type;
   EncryptionScheme::CipherMode mode = EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
   EncryptionPattern pattern;
@@ -331,7 +330,7 @@
       int sample_per_second = 0;
       std::vector<uint8_t> extra_data;
       // Check if it is MPEG4 AAC defined in ISO 14496 Part 3 or
-      // supported MPEG2 AAC varients.
+      // supported MPEG2 AAC variants.
       if (ESDescriptor::IsAAC(audio_type)) {
         codec = kCodecAAC;
         channel_layout = aac.GetChannelLayout(has_sbr_);
@@ -378,8 +377,7 @@
       EncryptionScheme scheme = Unencrypted();
       if (is_track_encrypted) {
         scheme = GetEncryptionScheme(entry.sinf);
-        if (!scheme.is_encrypted())
-          return false;
+        if (!scheme.is_encrypted()) return false;
       }
       audio_config.Initialize(codec, sample_format, channel_layout,
                               sample_per_second, extra_data, scheme,
@@ -442,8 +440,7 @@
       EncryptionScheme scheme = Unencrypted();
       if (is_track_encrypted) {
         scheme = GetEncryptionScheme(entry.sinf);
-        if (!scheme.is_encrypted())
-          return false;
+        if (!scheme.is_encrypted()) return false;
       }
       video_config.Initialize(entry.video_codec, entry.video_codec_profile,
                               PIXEL_FORMAT_YV12, COLOR_SPACE_HD_REC709,
diff --git a/src/cobalt/media/formats/mp4/track_run_iterator_unittest.cc b/src/cobalt/media/formats/mp4/track_run_iterator_unittest.cc
index 2858a7f..09b3908 100644
--- a/src/cobalt/media/formats/mp4/track_run_iterator_unittest.cc
+++ b/src/cobalt/media/formats/mp4/track_run_iterator_unittest.cc
@@ -979,7 +979,7 @@
   // no dependents, but we occasionally encounter media where all samples are
   // marked "sync" and we must rely on combining the two flags to pick out the
   // true key frames. See http://crbug.com/310712 and http://crbug.com/507916.
-  // Realiably knowing the keyframes for video is also critical to SPS PPS
+  // Reliably knowing the keyframes for video is also critical to SPS PPS
   // insertion.
   EXPECT_EQ("2 K P P P K P", KeyframeAndRAPInfo(iter_.get()));
 }
diff --git a/src/cobalt/media/formats/webm/tracks_builder.cc b/src/cobalt/media/formats/webm/tracks_builder.cc
index 285ced1..1e91fbc 100644
--- a/src/cobalt/media/formats/webm/tracks_builder.cc
+++ b/src/cobalt/media/formats/webm/tracks_builder.cc
@@ -23,7 +23,7 @@
   return 8;
 }
 
-// Returns the minimium size required to serialize an integer value.
+// Returns the minimum size required to serialize an integer value.
 static int GetUIntSize(uint64_t value) {
   if (value < 0x0100ULL) return 1;
   if (value < 0x010000ULL) return 2;
diff --git a/src/cobalt/media/player/web_media_player_impl.cc b/src/cobalt/media/player/web_media_player_impl.cc
index 7638848..a6d9b41 100644
--- a/src/cobalt/media/player/web_media_player_impl.cc
+++ b/src/cobalt/media/player/web_media_player_impl.cc
@@ -3,11 +3,11 @@
 // found in the LICENSE file.
 #include "cobalt/media/player/web_media_player_impl.h"
 
-#include <math.h>
-
+#include <cmath>
 #include <limits>
 #include <memory>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -26,7 +26,6 @@
 #include "cobalt/media/filters/chunk_demuxer.h"
 #include "cobalt/media/player/web_media_player_proxy.h"
 #include "cobalt/media/progressive/progressive_demuxer.h"
-#include "starboard/double.h"
 #include "starboard/types.h"
 
 namespace cobalt {
@@ -71,7 +70,7 @@
 
 bool IsNearTheEndOfStream(const WebMediaPlayerImpl* wmpi, double position) {
   float duration = wmpi->GetDuration();
-  if (SbDoubleIsFinite(duration)) {
+  if (std::isfinite(duration)) {
     // If video is very short, we always treat a position as near the end.
     if (duration <= kEndOfStreamEpsilonInSeconds) return true;
     if (position >= duration - kEndOfStreamEpsilonInSeconds) return true;
@@ -608,7 +607,8 @@
 }
 
 void WebMediaPlayerImpl::OnPipelineSeek(PipelineStatus status,
-                                        bool is_initial_preroll) {
+                                        bool is_initial_preroll,
+                                        const std::string& error_message) {
   DCHECK_EQ(main_loop_, base::MessageLoop::current());
   state_.starting = false;
   state_.seeking = false;
@@ -619,7 +619,8 @@
   }
 
   if (status != PIPELINE_OK) {
-    OnPipelineError(status, "Failed pipeline seek.");
+    OnPipelineError(status,
+                    "Failed pipeline seek with error: " + error_message + ".");
     return;
   }
 
@@ -695,7 +696,7 @@
     case PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED:
       SetNetworkError(
           WebMediaPlayer::kNetworkStateFormatError,
-          message.empty() ? "Pipeline extenrnal renderer failed." : message);
+          message.empty() ? "Pipeline external renderer failed." : message);
       break;
     case DEMUXER_ERROR_COULD_NOT_OPEN:
       SetNetworkError(WebMediaPlayer::kNetworkStateFormatError,
diff --git a/src/cobalt/media/player/web_media_player_impl.h b/src/cobalt/media/player/web_media_player_impl.h
index c77d8b3..6b0843f 100644
--- a/src/cobalt/media/player/web_media_player_impl.h
+++ b/src/cobalt/media/player/web_media_player_impl.h
@@ -69,12 +69,12 @@
 #include "cobalt/media/player/web_media_player_delegate.h"
 #include "url/gurl.h"
 
-#if defined(OS_STARBOARD)
+#if defined(STARBOARD)
 
 #define COBALT_USE_PUNCHOUT
 #define COBALT_SKIP_SEEK_REQUEST_NEAR_END
 
-#endif  // defined(OS_STARBOARD)
+#endif  // defined(STARBOARD)
 
 namespace cobalt {
 namespace media {
@@ -194,7 +194,8 @@
   void SetDrmSystem(const scoped_refptr<media::DrmSystem>& drm_system) override;
   void SetDrmSystemReadyCB(const DrmSystemReadyCB& drm_system_ready_cb);
 
-  void OnPipelineSeek(PipelineStatus status, bool is_initial_preroll);
+  void OnPipelineSeek(PipelineStatus status, bool is_initial_preroll,
+                      const std::string& error_message);
   void OnPipelineEnded(PipelineStatus status);
   void OnPipelineError(PipelineStatus error, const std::string& message);
   void OnPipelineBufferingState(Pipeline::BufferingState buffering_state);
diff --git a/src/cobalt/media/progressive/mp4_map.cc b/src/cobalt/media/progressive/mp4_map.cc
index 3a65467..2824b85 100644
--- a/src/cobalt/media/progressive/mp4_map.cc
+++ b/src/cobalt/media/progressive/mp4_map.cc
@@ -373,7 +373,7 @@
 }
 
 // Set up map state and load first part of table, or entire table if it is small
-// enough, for each of the supporated atoms.
+// enough, for each of the supported atoms.
 bool MP4Map::SetAtom(uint32 four_cc, uint64 offset, uint64 size,
                      uint32 cache_size_entries, const uint8* atom) {
   // All map atoms are variable-length tables starting with 4 bytes of
@@ -652,7 +652,7 @@
   return true;
 }
 
-// To find the chunk number of an abritrary sample we have to sum the
+// To find the chunk number of an arbitrary sample we have to sum the
 // samples-per-chunk value multiplied by the number of chunks with that sample
 // count until the sum exceeds the sample number, then calculate the chunk
 // number from that range of per-sample chunk sizes. Since this map is meant
diff --git a/src/cobalt/media/progressive/mp4_map.h b/src/cobalt/media/progressive/mp4_map.h
index 93bc08f..0678fc4 100644
--- a/src/cobalt/media/progressive/mp4_map.h
+++ b/src/cobalt/media/progressive/mp4_map.h
@@ -110,7 +110,7 @@
   // table is always aligned with the full table in cache_size_entries, so
   // that the position in the cache is trivially calculated from
   // entry_number % cache_size_entries, and the cache index is similarly
-  // caculated from entry_number / cache_size_entries.
+  // calculated from entry_number / cache_size_entries.
   class TableCache : public base::RefCountedThreadSafe<TableCache> {
    public:
     TableCache(uint64 table_offset,  // byte offset of start of table in file
@@ -155,7 +155,7 @@
   uint64 current_chunk_offset_;  // file byte offset of current_chunk_sample_
 
   // Can be set by a stsz entry count but an stsz may provide a default size,
-  // in which case this number may not be known until itegration through
+  // in which case this number may not be known until iteration through
   // the ctts, or stts has completed. In the event that one of those tables
   // ends at a lower number than the others this number will be amended
   // to return the lower number.
diff --git a/src/cobalt/media/progressive/mp4_map_unittest.cc b/src/cobalt/media/progressive/mp4_map_unittest.cc
index 347b7bb..29e2706 100644
--- a/src/cobalt/media/progressive/mp4_map_unittest.cc
+++ b/src/cobalt/media/progressive/mp4_map_unittest.cc
@@ -536,7 +536,7 @@
       if (sample_table_->read_count())
         ASSERT_LE(sample_table_->read_bytes() / sample_table_->read_count(),
                   (i + 1) * kEntrySize_stsz);
-      // call to sample past the table size should still faile
+      // call to sample past the table size should still fail
       uint32 failed_size = 0;
       ASSERT_FALSE(map_->GetSize(sample_table_->sample_count(), &failed_size));
     }
diff --git a/src/cobalt/media/progressive/progressive_demuxer.cc b/src/cobalt/media/progressive/progressive_demuxer.cc
index a396825..27587ca 100644
--- a/src/cobalt/media/progressive/progressive_demuxer.cc
+++ b/src/cobalt/media/progressive/progressive_demuxer.cc
@@ -48,7 +48,7 @@
   base::AutoLock auto_lock(lock_);
 
   // Don't accept any additional reads if we've been told to stop.
-  // The demuxer_ may have been destroyed in the pipleine thread.
+  // The demuxer_ may have been destroyed in the pipeline thread.
   if (stopped_) {
     TRACE_EVENT0("media_stack", "ProgressiveDemuxerStream::Read() EOS sent.");
     read_cb.Run(DemuxerStream::kOk,
@@ -211,7 +211,7 @@
 
 ProgressiveDemuxer::~ProgressiveDemuxer() {
   // Explicitly stop |blocking_thread_| to ensure that it stops before the
-  // destructiing of any other members.
+  // destructing of any other members.
   blocking_thread_.Stop();
 }
 
diff --git a/src/cobalt/media/progressive/progressive_parser.h b/src/cobalt/media/progressive/progressive_parser.h
index a0e6f41..0e903f5 100644
--- a/src/cobalt/media/progressive/progressive_parser.h
+++ b/src/cobalt/media/progressive/progressive_parser.h
@@ -44,7 +44,7 @@
   virtual bool ParseConfig() = 0;
 
   // Returns a populated, valid AU indicating the needed information for
-  // downloding and decoding the next access unit in the stream, or NULL on
+  // downloading and decoding the next access unit in the stream, or NULL on
   // fatal error. On success this advances the respective audio or video cursor
   // to the next AU.
   virtual scoped_refptr<AvcAccessUnit> GetNextAU(DemuxerStream::Type type) = 0;
diff --git a/src/cobalt/media/progressive/rbsp_stream.h b/src/cobalt/media/progressive/rbsp_stream.h
index 0c8d8bc..2604820 100644
--- a/src/cobalt/media/progressive/rbsp_stream.h
+++ b/src/cobalt/media/progressive/rbsp_stream.h
@@ -51,7 +51,7 @@
   // advance by one byte through the NALU buffer, respecting the encoding of
   // 00 00 03 => 00 00. Updates the state of current_nalu_byte_ to the new
   // value.
-  // returns fale if we have moved past the end of the buffer.
+  // returns false if we have moved past the end of the buffer.
   bool ConsumeNALUByte();
   // return single bit in the LSb from the RBSP stream. Bits are read from MSb
   // to LSb in the stream.
diff --git a/src/cobalt/media/progressive/rbsp_stream_unittest.cc b/src/cobalt/media/progressive/rbsp_stream_unittest.cc
index 33669ed..0bcf519 100644
--- a/src/cobalt/media/progressive/rbsp_stream_unittest.cc
+++ b/src/cobalt/media/progressive/rbsp_stream_unittest.cc
@@ -121,7 +121,7 @@
         }
       }
     } else {
-      // we will need to detect any naturally ocurring 00 00 03s
+      // we will need to detect any naturally occurring 00 00 03s
       // and protect them from removal of the 03, by inserting a
       // second 03
       int num_zeros = 0;
diff --git a/src/cobalt/media/sandbox/fuzzer_app.cc b/src/cobalt/media/sandbox/fuzzer_app.cc
index 40a93cf..9b4853f 100644
--- a/src/cobalt/media/sandbox/fuzzer_app.cc
+++ b/src/cobalt/media/sandbox/fuzzer_app.cc
@@ -77,7 +77,7 @@
 
   if (argc == 3) {
     *initial_seed = ZzufFuzzer::kSeedForOriginalContent;
-    number_of_iterations_ = SbStringParseSignedInteger(argv[1], NULL, 10);
+    number_of_iterations_ = strtol(argv[1], NULL, 10);
 
     if (number_of_iterations_ <= 0) {
       LOG(ERROR) << "Invalid 'number of iterations' " << argv[1];
@@ -85,14 +85,14 @@
     }
   } else {
     DCHECK_EQ(argc, 4);
-    *initial_seed = SbStringParseSignedInteger(argv[1], NULL, 10);
+    *initial_seed = strtol(argv[1], NULL, 10);
 
     if (*initial_seed < 0) {
       LOG(ERROR) << "Invalid 'initial seed' " << argv[1];
       return false;
     }
 
-    number_of_iterations_ = SbStringParseSignedInteger(argv[2], NULL, 10);
+    number_of_iterations_ = strtol(argv[2], NULL, 10);
 
     if (number_of_iterations_ <= 0) {
       LOG(ERROR) << "Invalid 'number of iterations' " << argv[2];
diff --git a/src/cobalt/media_session/default_media_session_client.cc b/src/cobalt/media_session/default_media_session_client.cc
deleted file mode 100644
index b1a7c47..0000000
--- a/src/cobalt/media_session/default_media_session_client.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2017 The Cobalt Authors. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef COBALT_MEDIA_SESSION_DEFAULT_MEDIA_SESSION_CLIENT_H_
-#define COBALT_MEDIA_SESSION_DEFAULT_MEDIA_SESSION_CLIENT_H_
-
-#include <memory>
-
-#include "cobalt/media_session/media_session_client.h"
-
-namespace cobalt {
-namespace media_session {
-
-class DefaultMediaSessionClient : public MediaSessionClient {
- public:
-  DefaultMediaSessionClient() {}
-  ~DefaultMediaSessionClient() override {}
-};
-
-// static
-std::unique_ptr<MediaSessionClient> MediaSessionClient::Create() {
-  return std::unique_ptr<MediaSessionClient>(new DefaultMediaSessionClient());
-}
-
-}  // namespace media_session
-}  // namespace cobalt
-
-#endif  // COBALT_MEDIA_SESSION_DEFAULT_MEDIA_SESSION_CLIENT_H_
diff --git a/src/cobalt/media_session/media_session.cc b/src/cobalt/media_session/media_session.cc
index acc4070..2b8dd33 100644
--- a/src/cobalt/media_session/media_session.cc
+++ b/src/cobalt/media_session/media_session.cc
@@ -85,7 +85,7 @@
 
 void MediaSession::EnsureMediaSessionClient() {
   if (media_session_client_ == nullptr) {
-    media_session_client_ = media_session::MediaSessionClient::Create();
+    media_session_client_ = std::make_unique<MediaSessionClient>();
     DCHECK(media_session_client_);
     media_session_client_->set_media_session(this);
   }
diff --git a/src/cobalt/media_session/media_session.gyp b/src/cobalt/media_session/media_session.gyp
index da0d96b..42e4f55 100644
--- a/src/cobalt/media_session/media_session.gyp
+++ b/src/cobalt/media_session/media_session.gyp
@@ -29,13 +29,6 @@
         'media_session_state.cc',
         'media_session_state.h',
       ],
-      'conditions': [
-        ['custom_media_session_client == 0', {
-          'sources': [
-            'default_media_session_client.cc',
-          ]
-        }]
-      ],
       'dependencies': [
         '<(DEPTH)/cobalt/base/base.gyp:base',
         '<(DEPTH)/cobalt/browser/browser_bindings_gen.gyp:generated_types',
diff --git a/src/cobalt/media_session/media_session_client.cc b/src/cobalt/media_session/media_session_client.cc
index d2454d4..9a5f2dc 100644
--- a/src/cobalt/media_session/media_session_client.cc
+++ b/src/cobalt/media_session/media_session_client.cc
@@ -79,7 +79,7 @@
         extension_->version < 1) {
       LOG(WARNING) << "Wrong MediaSession extension supplied";
       extension_ = nullptr;
-    } else {
+    } else if (extension_->RegisterMediaSessionCallbacks != nullptr) {
       extension_->RegisterMediaSessionCallbacks(
           this, &InvokeActionCallback, &UpdatePlatformPlaybackStateCallback);
     }
@@ -175,15 +175,13 @@
   return result;
 }
 
-void MediaSessionClient::UpdatePlatformCobaltExtensionPlaybackState(
+void MediaSessionClient::UpdatePlatformPlaybackState(
     CobaltExtensionMediaSessionPlaybackState state) {
   DCHECK(media_session_->task_runner_);
   if (!media_session_->task_runner_->BelongsToCurrentThread()) {
     media_session_->task_runner_->PostTask(
-        FROM_HERE,
-        base::Bind(
-            &MediaSessionClient::UpdatePlatformCobaltExtensionPlaybackState,
-            base::Unretained(this), state));
+        FROM_HERE, base::Bind(&MediaSessionClient::UpdatePlatformPlaybackState,
+                              base::Unretained(this), state));
     return;
   }
 
@@ -329,7 +327,7 @@
     CobaltExtensionMediaSessionPlaybackState state, void* callback_context) {
   MediaSessionClient* client =
       static_cast<MediaSessionClient*>(callback_context);
-  client->UpdatePlatformCobaltExtensionPlaybackState(state);
+  client->UpdatePlatformPlaybackState(state);
 }
 
 // static
@@ -337,7 +335,7 @@
     CobaltExtensionMediaSessionActionDetails details, void* callback_context) {
   MediaSessionClient* client =
       static_cast<MediaSessionClient*>(callback_context);
-  client->InvokeCobaltExtensionAction(details);
+  client->InvokeAction(details);
 }
 
 CobaltExtensionMediaSessionPlaybackState
diff --git a/src/cobalt/media_session/media_session_client.h b/src/cobalt/media_session/media_session_client.h
index 4961a91..3e37d1f 100644
--- a/src/cobalt/media_session/media_session_client.h
+++ b/src/cobalt/media_session/media_session_client.h
@@ -41,9 +41,6 @@
 
   virtual ~MediaSessionClient();
 
-  // Creates platform-specific instance.
-  static std::unique_ptr<MediaSessionClient> Create();
-
   // Retrieves the singleton MediaSession associated with this client.
   MediaSession* GetMediaSession() { return media_session_; }
 
@@ -57,17 +54,9 @@
   // the "guessed playback state"
   // https://wicg.github.io/mediasession/#guessed-playback-state
   // Can be invoked from any thread.
-  void UpdatePlatformCobaltExtensionPlaybackState(
+  void UpdatePlatformPlaybackState(
       CobaltExtensionMediaSessionPlaybackState state);
 
-  // Deprecated - use the alternative
-  // UpdatePlatformCobaltExtensionPlaybackState.
-  // TODO: Delete once platform migrations to CobaltExtensionMediaSessionApi are
-  // complete.
-  void UpdatePlatformPlaybackState(MediaSessionPlaybackState state) {
-    UpdatePlatformCobaltExtensionPlaybackState(ConvertPlaybackState(state));
-  }
-
   // Invokes a given media session action
   // https://wicg.github.io/mediasession/#actions-model
   // Can be invoked from any thread.
@@ -79,33 +68,12 @@
   }
 
   // Invokes a given media session action that takes additional details.
-  void InvokeCobaltExtensionAction(
-      CobaltExtensionMediaSessionActionDetails details) {
+  void InvokeAction(CobaltExtensionMediaSessionActionDetails details) {
     std::unique_ptr<CobaltExtensionMediaSessionActionDetails> details_ptr(
         new CobaltExtensionMediaSessionActionDetails(details));
     InvokeActionInternal(std::move(details_ptr));
   }
 
-  // Deprecated - use the alternative InvokeCobaltExtensionAction.
-  // TODO: Delete once platform migrations to CobaltExtensionMediaSessionApi are
-  // complete.
-  void InvokeAction(std::unique_ptr<MediaSessionActionDetails> details) {
-    std::unique_ptr<CobaltExtensionMediaSessionActionDetails> ext_details(
-        new CobaltExtensionMediaSessionActionDetails());
-    CobaltExtensionMediaSessionActionDetailsInit(
-        ext_details.get(), ConvertMediaSessionAction(details->action()));
-    if (details->has_seek_offset()) {
-      ext_details->seek_offset = details->seek_offset().value();
-    }
-    if (details->has_seek_time()) {
-      ext_details->seek_time = details->seek_time().value();
-    }
-    if (details->has_fast_seek()) {
-      ext_details->fast_seek = details->fast_seek().value();
-    }
-    InvokeActionInternal(std::move(ext_details));
-  }
-
   // Invoked on the browser thread when any metadata, position state, playback
   // state, or supported session actions change.
   virtual void OnMediaSessionStateChanged(
diff --git a/src/cobalt/media_session/media_session_test.cc b/src/cobalt/media_session/media_session_test.cc
index fcdd413..1a56e80 100644
--- a/src/cobalt/media_session/media_session_test.cc
+++ b/src/cobalt/media_session/media_session_test.cc
@@ -142,7 +142,7 @@
       ->GetMediaSessionState().actual_playback_state());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStatePlaying);
+      kCobaltExtensionMediaSessionPlaying);
 
   session->mock_session_client()->WaitForSessionStateChange();
   EXPECT_EQ(kMediaSessionPlaybackStatePlaying, session->mock_session_client()
@@ -161,7 +161,7 @@
       ->GetMediaSessionState().actual_playback_state());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStatePaused);
+      kCobaltExtensionMediaSessionPaused);
 
   session->mock_session_client()->WaitForSessionStateChange();
   EXPECT_EQ(kMediaSessionPlaybackStatePaused, session->mock_session_client()
@@ -174,7 +174,7 @@
       ->GetMediaSessionState().actual_playback_state());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStateNone);
+      kCobaltExtensionMediaSessionNone);
 
   session->mock_session_client()->WaitForSessionStateChange();
   EXPECT_EQ(kMediaSessionPlaybackStateNone, session->mock_session_client()
@@ -270,7 +270,7 @@
   EXPECT_EQ(1 << kMediaSessionActionPlay, state.available_actions().to_ulong());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStatePlaying);
+      kCobaltExtensionMediaSessionPlaying);
 
   session->mock_session_client()->WaitForSessionStateChange();
   state = session->mock_session_client()->GetMediaSessionState();
@@ -303,7 +303,7 @@
             state.available_actions().to_ulong());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStatePaused);
+      kCobaltExtensionMediaSessionPaused);
 
   session->mock_session_client()->WaitForSessionStateChange();
   state = session->mock_session_client()->GetMediaSessionState();
@@ -327,7 +327,7 @@
             state.available_actions().to_ulong());
 
   session->mock_session_client()->UpdatePlatformPlaybackState(
-      kMediaSessionPlaybackStateNone);
+      kCobaltExtensionMediaSessionNone);
 
   session->mock_session_client()->WaitForSessionStateChange();
   state = session->mock_session_client()->GetMediaSessionState();
@@ -346,15 +346,15 @@
 
   MockCallbackFunction cf;
   FakeScriptValue<MediaSession::MediaSessionActionHandler> holder(&cf);
-  std::unique_ptr<MediaSessionActionDetails> details(
-      new MediaSessionActionDetails());
+  CobaltExtensionMediaSessionActionDetails details;
 
   session->SetActionHandler(kMediaSessionActionSeekto, holder);
   EXPECT_CALL(cf, Run(SeekTime(1.2))).WillOnce(Return(CallbackResult<void>()));
 
-  details->set_action(kMediaSessionActionSeekto);
-  details->set_seek_time(1.2);
-  session->mock_session_client()->InvokeAction(std::move(details));
+  CobaltExtensionMediaSessionActionDetailsInit(
+      &details, kCobaltExtensionMediaSessionActionSeekto);
+  details.seek_time = 1.2;
+  session->mock_session_client()->InvokeAction(details);
 }
 
 TEST(MediaSessionTest, SeekDetails) {
@@ -387,21 +387,21 @@
   CobaltExtensionMediaSessionActionDetailsInit(
       &details, kCobaltExtensionMediaSessionActionSeekto);
   details.seek_time = 1.2;
-  session->mock_session_client()->InvokeCobaltExtensionAction(details);
+  session->mock_session_client()->InvokeAction(details);
 
   EXPECT_CALL(cf, Run(SeekOffset(kMediaSessionActionSeekforward, 3.4)))
       .WillOnce(Return(CallbackResult<void>()));
   CobaltExtensionMediaSessionActionDetailsInit(
       &details, kCobaltExtensionMediaSessionActionSeekforward);
   details.seek_offset = 3.4;
-  session->mock_session_client()->InvokeCobaltExtensionAction(details);
+  session->mock_session_client()->InvokeAction(details);
 
   EXPECT_CALL(cf, Run(SeekOffset(kMediaSessionActionSeekbackward, 5.6)))
       .WillOnce(Return(CallbackResult<void>()));
   CobaltExtensionMediaSessionActionDetailsInit(
       &details, kCobaltExtensionMediaSessionActionSeekbackward);
   details.seek_offset = 5.6;
-  session->mock_session_client()->InvokeCobaltExtensionAction(details);
+  session->mock_session_client()->InvokeAction(details);
 
   session->mock_session_client()->WaitForSessionStateChange();
   EXPECT_GE(session->mock_session_client()->GetMediaSessionChangeCount(), 0);
diff --git a/src/cobalt/network/local_network.cc b/src/cobalt/network/local_network.cc
index ad92464..b39878f 100644
--- a/src/cobalt/network/local_network.cc
+++ b/src/cobalt/network/local_network.cc
@@ -72,7 +72,7 @@
 
 bool IsIPInPrivateRange(const SbSocketAddress& ip) {
   // For IPv4, the private address range is defined by RFC 1918
-  // avaiable at https://tools.ietf.org/html/rfc1918#section-3.
+  // available at https://tools.ietf.org/html/rfc1918#section-3.
   if (ip.type == kSbSocketAddressTypeIpv4) {
     if (ip.address[0] == 10) {
       // IP is in range 10.0.0.0 - 10.255.255.255 (10/8 prefix).
diff --git a/src/cobalt/network/network_module.cc b/src/cobalt/network/network_module.cc
index 42032dd..dbacd7a 100644
--- a/src/cobalt/network/network_module.cc
+++ b/src/cobalt/network/network_module.cc
@@ -68,7 +68,7 @@
 
   // This will run the above task, and then stop the thread.
   thread_.reset(NULL);
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
   object_watch_multiplexer_.reset(NULL);
 #endif
   network_system_.reset(NULL);
@@ -92,15 +92,15 @@
 
 void NetworkModule::SetEnableQuic(bool enable_quic) {
   task_runner()->PostTask(
-      FROM_HERE, base::Bind(&URLRequestContext::SetEnableQuic,
-                            base::Unretained(url_request_context_.get()),
-                            enable_quic));
+      FROM_HERE,
+      base::Bind(&URLRequestContext::SetEnableQuic,
+                 base::Unretained(url_request_context_.get()), enable_quic));
 }
 
 void NetworkModule::Initialize(const std::string& user_agent_string,
                                base::EventDispatcher* event_dispatcher) {
   thread_.reset(new base::Thread("NetworkModule"));
-#if !defined(OS_STARBOARD)
+#if !defined(STARBOARD)
   object_watch_multiplexer_.reset(new base::ObjectWatchMultiplexer());
 #endif
   network_system_ = NetworkSystem::Create(event_dispatcher);
@@ -117,6 +117,12 @@
         options_.preferred_language, custom_user_agent));
   }
 
+  if (command_line->HasSwitch(switches::kMaxNetworkDelay)) {
+    base::StringToInt64(
+        command_line->GetSwitchValueASCII(switches::kMaxNetworkDelay),
+        &options_.max_network_delay);
+  }
+
 #if defined(ENABLE_NETWORK_LOGGING)
   if (command_line->HasSwitch(switches::kNetLog)) {
     // If this is not a valid path, net logs will be sent to VLOG(1).
diff --git a/src/cobalt/network/network_module.h b/src/cobalt/network/network_module.h
index b463e22..be655f9 100644
--- a/src/cobalt/network/network_module.h
+++ b/src/cobalt/network/network_module.h
@@ -59,12 +59,14 @@
         : cookie_policy(net::StaticCookiePolicy::BLOCK_ALL_THIRD_PARTY_COOKIES),
           ignore_certificate_errors(false),
           https_requirement(network::kHTTPSRequired),
-          preferred_language("en-US") {}
+          preferred_language("en-US"),
+          max_network_delay(0) {}
     net::StaticCookiePolicy::Type cookie_policy;
     bool ignore_certificate_errors;
     HTTPSRequirement https_requirement;
     std::string preferred_language;
     std::string custom_proxy;
+    SbTime max_network_delay;
   };
 
   // Simple constructor intended to be used only by tests.
@@ -80,13 +82,12 @@
   URLRequestContext* url_request_context() const {
     return url_request_context_.get();
   }
-  NetworkDelegate* network_delegate() const {
-    return network_delegate_.get();
-  }
+  NetworkDelegate* network_delegate() const { return network_delegate_.get(); }
   std::string GetUserAgent() const;
   const std::string& preferred_language() const {
     return options_.preferred_language;
   }
+  SbTime max_network_delay() const { return options_.max_network_delay; }
   scoped_refptr<URLRequestContextGetter> url_request_context_getter() const {
     return url_request_context_getter_;
   }
diff --git a/src/cobalt/network/switches.cc b/src/cobalt/network/switches.cc
index 469b8ae..e0c1650 100644
--- a/src/cobalt/network/switches.cc
+++ b/src/cobalt/network/switches.cc
@@ -31,6 +31,12 @@
 const char kNetLogCaptureMode[] = "net_log_capture_mode";
 
 const char kUserAgent[] = "user_agent";
+
+const char kMaxNetworkDelay[] = "max_network_delay";
+const char kMaxNetworkDelayHelp[] =
+    "Add an artificial random delay (up to the value specified) before the "
+    "start of network requests to simulate low-latency networks.  The value "
+    "is specified in microseconds.";
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
 
 // Switch to disable use of the Quic network protocol.
diff --git a/src/cobalt/network/switches.h b/src/cobalt/network/switches.h
index a3c3894..b9fa3a6 100644
--- a/src/cobalt/network/switches.h
+++ b/src/cobalt/network/switches.h
@@ -23,6 +23,8 @@
 extern const char kNetLog[];
 extern const char kNetLogCaptureMode[];
 extern const char kUserAgent[];
+extern const char kMaxNetworkDelay[];
+extern const char kMaxNetworkDelayHelp[];
 #endif  // ENABLE_DEBUG_COMMAND_LINE_SWITCHES
 extern const char kDisableQuic[];
 
diff --git a/src/cobalt/overlay_info/overlay_info_registry.cc b/src/cobalt/overlay_info/overlay_info_registry.cc
index 1341374..863d9b1 100644
--- a/src/cobalt/overlay_info/overlay_info_registry.cc
+++ b/src/cobalt/overlay_info/overlay_info_registry.cc
@@ -35,7 +35,7 @@
   void RetrieveAndClear(std::string* infos);
 
  private:
-  // Reserve enough data for |infos_| to avoid extra allcations.
+  // Reserve enough data for |infos_| to avoid extra allocations.
   static const size_t kReservedSize = 4096;
 
   OverlayInfoRegistryImpl() = default;
diff --git a/src/cobalt/render_tree/animations/animation_list.h b/src/cobalt/render_tree/animations/animation_list.h
index ca3b4e7..ec7b3ca 100644
--- a/src/cobalt/render_tree/animations/animation_list.h
+++ b/src/cobalt/render_tree/animations/animation_list.h
@@ -41,7 +41,7 @@
   // on any render_tree::Node object of the specified template type argument.
   //
   // As an example, one could create an animation that linearly interpolates
-  // between two color values on a TextNode object by first definining the
+  // between two color values on a TextNode object by first defining the
   // animation function (assuming ColorRGBA has operator*() defined):
   //
   //   void InterpolateTextColor(
diff --git a/src/cobalt/render_tree/brush.h b/src/cobalt/render_tree/brush.h
index 0369ae5..bddad82 100644
--- a/src/cobalt/render_tree/brush.h
+++ b/src/cobalt/render_tree/brush.h
@@ -121,7 +121,7 @@
 // respective directions.
 class LinearGradientBrush : public Brush {
  public:
-  // The ColorStopList passed into LienarGradientBrush must have at least two
+  // The ColorStopList passed into LinearGradientBrush must have at least two
   // stops and they must be sorted in order of increasing position.
   LinearGradientBrush(const math::PointF& source, const math::PointF& dest,
                       const ColorStopList& color_stops);
diff --git a/src/cobalt/render_tree/rounded_corners.h b/src/cobalt/render_tree/rounded_corners.h
index 9094bc1..fa33923 100644
--- a/src/cobalt/render_tree/rounded_corners.h
+++ b/src/cobalt/render_tree/rounded_corners.h
@@ -46,7 +46,7 @@
     return horizontal >= other.horizontal && vertical >= other.vertical;
   }
 
-  // |horizontal| and |vertial| represent the horizontal radius and vertical
+  // |horizontal| and |vertical| represent the horizontal radius and vertical
   // radius of a corner.
   float horizontal;
   float vertical;
diff --git a/src/cobalt/renderer/backend/egl/framebuffer.cc b/src/cobalt/renderer/backend/egl/framebuffer.cc
index 472bac9..16a20e7 100644
--- a/src/cobalt/renderer/backend/egl/framebuffer.cc
+++ b/src/cobalt/renderer/backend/egl/framebuffer.cc
@@ -54,10 +54,10 @@
   }
 
   GL_CALL(glBindTexture(GL_TEXTURE_2D, color_handle));
-  GL_CALL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-  GL_CALL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-  GL_CALL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-  GL_CALL(glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
+  GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+  GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+  GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+  GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
   GL_CALL_SIMPLE(glTexImage2D(GL_TEXTURE_2D, 0, color_format, size_.width(),
                               size_.height(), 0, color_format, GL_UNSIGNED_BYTE,
                               0));
diff --git a/src/cobalt/renderer/backend/egl/resource_context.h b/src/cobalt/renderer/backend/egl/resource_context.h
index 0d718d1..ccbc073 100644
--- a/src/cobalt/renderer/backend/egl/resource_context.h
+++ b/src/cobalt/renderer/backend/egl/resource_context.h
@@ -34,7 +34,7 @@
 // created by the GraphicsSystem that owns this ResourceContext.  This class
 // is useful when one wishes to create and allocate pixel buffer data (e.g. for
 // a texture) from any thread, that can later be converted to a texture for
-// a specific grpahics context.  Resource management GL operations can be
+// a specific graphics context.  Resource management GL operations can be
 // performed (from any thread) by calling the method
 // RunSynchronouslyWithinResourceContext() and passing a function which one
 // wishes to run under the resource management GL context.
diff --git a/src/cobalt/renderer/backend/egl/texture_data_pbo.cc b/src/cobalt/renderer/backend/egl/texture_data_pbo.cc
index bd53b68..a18e16d 100644
--- a/src/cobalt/renderer/backend/egl/texture_data_pbo.cc
+++ b/src/cobalt/renderer/backend/egl/texture_data_pbo.cc
@@ -71,10 +71,10 @@
   // synchronize existing draw calls with it, both things which should be
   // implied anyways since this is a brand new buffer, but we specify just in
   // case.
-  mapped_data_ = static_cast<GLubyte*>(glMapBufferRange(
-      GL_PIXEL_UNPACK_BUFFER, 0, data_size_, GL_MAP_WRITE_BIT |
-                                                 GL_MAP_INVALIDATE_BUFFER_BIT |
-                                                 GL_MAP_UNSYNCHRONIZED_BIT));
+  mapped_data_ = static_cast<GLubyte*>(
+      glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, data_size_,
+                       GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT |
+                           GL_MAP_UNSYNCHRONIZED_BIT));
   if (glGetError() != GL_NO_ERROR || !mapped_data_) {
     LOG(ERROR) << "Error mapping PBO buffer data.";
     error_ = true;
@@ -192,7 +192,7 @@
   DCHECK_EQ(GL_NO_ERROR, glGetError());
   GL_CALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
 
-  // Finally, determine the offset within |mapped_data_| necessary to acheive
+  // Finally, determine the offset within |mapped_data_| necessary to achieve
   // the desired alignment.
   intptr_t alignment_remainder =
       reinterpret_cast<size_t>(mapped_data_) % alignment_;
diff --git a/src/cobalt/renderer/backend/graphics_system_test.cc b/src/cobalt/renderer/backend/graphics_system_test.cc
index f6ad30c..06514a4 100644
--- a/src/cobalt/renderer/backend/graphics_system_test.cc
+++ b/src/cobalt/renderer/backend/graphics_system_test.cc
@@ -33,7 +33,7 @@
 const int kReferenceCount = 5;
 }  // namespace
 
-TEST(GraphicsSystemTest, GraphicsSystemCanBeInitializedOften) {
+TEST(GraphicsSystemTest, FLAKY_GraphicsSystemCanBeInitializedOften) {
   // Test whether the graphics system can be initialized often without slowing
   // down.
   std::unique_ptr<GraphicsSystem> graphics_system;
@@ -70,7 +70,7 @@
   }
 }
 
-TEST(GraphicsSystemTest, GraphicsContextCanBeInitializedOften) {
+TEST(GraphicsSystemTest, FLAKY_GraphicsContextCanBeInitializedOften) {
   // Test whether the graphics system and graphics context can be initialized
   // often without slowing down.
   std::unique_ptr<GraphicsSystem> graphics_system;
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold.glsl
new file mode 100644
index 0000000..6950864
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold.glsl
@@ -0,0 +1,72 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec4 vinCircleEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = length(vTransformedCoords_0_Stage0);
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp vec4 circleEdge;
+        circleEdge = vinCircleEdge_Stage0;
+        outputColor_Stage0 = vinColor_Stage0;
+        highp float d = length(circleEdge.xy);
+        mediump float distanceToOuterEdge = circleEdge.z * (1.0 - d);
+        mediump float edgeAlpha = clamp(distanceToOuterEdge, 0.0, 1.0);
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl
new file mode 100644
index 0000000..1380682
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_2.glsl
@@ -0,0 +1,75 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec4 vinCircleEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    {
+        child.xyz *= child.w;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp vec4 circleEdge;
+        circleEdge = vinCircleEdge_Stage0;
+        outputColor_Stage0 = vinColor_Stage0;
+        highp float d = length(circleEdge.xy);
+        mediump float distanceToOuterEdge = circleEdge.z * (1.0 - d);
+        mediump float edgeAlpha = clamp(distanceToOuterEdge, 0.0, 1.0);
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_3.glsl
new file mode 100644
index 0000000..8ca842b
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_threshold_3.glsl
@@ -0,0 +1,75 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec4 vinCircleEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp vec4 circleEdge;
+        circleEdge = vinCircleEdge_Stage0;
+        outputColor_Stage0 = vinColor_Stage0;
+        highp float d = length(circleEdge.xy);
+        mediump float distanceToOuterEdge = circleEdge.z * (1.0 - d);
+        mediump float edgeAlpha = clamp(distanceToOuterEdge, 0.0, 1.0);
+        mediump float distanceToInnerEdge = circleEdge.z * (d - circleEdge.w);
+        mediump float innerAlpha = clamp(distanceToInnerEdge, 0.0, 1.0);
+        edgeAlpha *= innerAlpha;
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl
new file mode 100644
index 0000000..63ff1ed
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_circle_color_scale_thresholds.glsl
@@ -0,0 +1,93 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec4 vinCircleEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp vec4 circleEdge;
+        circleEdge = vinCircleEdge_Stage0;
+        highp float d = length(circleEdge.xy);
+        mediump float distanceToOuterEdge = circleEdge.z * (1.0 - d);
+        mediump float edgeAlpha = clamp(distanceToOuterEdge, 0.0, 1.0);
+        mediump float distanceToInnerEdge = circleEdge.z * (d - circleEdge.w);
+        mediump float innerAlpha = clamp(distanceToInnerEdge, 0.0, 1.0);
+        edgeAlpha *= innerAlpha;
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold.glsl
new file mode 100644
index 0000000..e1600ec
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold.glsl
@@ -0,0 +1,70 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uColor_Stage0;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump float vinCoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = length(vTransformedCoords_0_Stage0);
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float alpha = 1.0;
+        alpha = vinCoverage_Stage0;
+        outputCoverage_Stage0 = vec4(alpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl
new file mode 100644
index 0000000..9c5c1f3
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_2.glsl
@@ -0,0 +1,67 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uColor_Stage0;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump float vinCoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float alpha = 1.0;
+        alpha = vinCoverage_Stage0;
+        outputCoverage_Stage0 = vec4(alpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_3.glsl
new file mode 100644
index 0000000..3d40e8a
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_threshold_3.glsl
@@ -0,0 +1,66 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+varying highp float vcoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp float coverage = vcoverage_Stage0;
+        outputCoverage_Stage0 = vec4(coverage);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl
new file mode 100644
index 0000000..cbcba0c
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds.glsl
@@ -0,0 +1,83 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+varying highp float vcoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp float coverage = vcoverage_Stage0;
+        outputCoverage_Stage0 = vec4(coverage);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl
new file mode 100644
index 0000000..083f5e4
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_2.glsl
@@ -0,0 +1,69 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+varying highp float vcoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        highp float coverage = vcoverage_Stage0;
+        outputCoverage_Stage0 = vec4(coverage);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl
new file mode 100644
index 0000000..e737a75
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_3.glsl
@@ -0,0 +1,93 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uColor_Stage0;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias8_9_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump float vinCoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.w) {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    } else {
+        {
+            {
+                scale = uscale8_9_Stage1_c0_c0_c1_c0;
+                bias = ubias8_9_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float alpha = 1.0;
+        alpha = vinCoverage_Stage0;
+        outputCoverage_Stage0 = vec4(alpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_4.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_4.glsl
new file mode 100644
index 0000000..7a83670
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_coverage_scale_thresholds_4.glsl
@@ -0,0 +1,98 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uColor_Stage0;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale10_11_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias10_11_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump float vinCoverage_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = length(vTransformedCoords_0_Stage0);
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.w) {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    } else {
+        {
+            if (t < uthresholds9_13_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale8_9_Stage1_c0_c0_c1_c0;
+                bias = ubias8_9_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale10_11_Stage1_c0_c0_c1_c0;
+                bias = ubias10_11_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float alpha = 1.0;
+        alpha = vinCoverage_Stage0;
+        outputCoverage_Stage0 = vec4(alpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl
new file mode 100644
index 0000000..d3a03a4
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_decal_scaletranslate_texdom_texturew_threshold.glsl
@@ -0,0 +1,89 @@
+#version 100
+
+uniform highp float u_skRTHeight;
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uscaleAndTranslate_Stage2;
+uniform mediump vec4 uTexDom_Stage2;
+uniform mediump vec3 uDecalParams_Stage2;
+uniform sampler2D uTextureSampler_0_Stage2;
+varying mediump vec4 vcolor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    {
+        child.xyz *= child.w;
+    }
+    return child;
+}
+void main() {
+highp     vec4 sk_FragCoord = vec4(gl_FragCoord.x, u_skRTHeight - gl_FragCoord.y, gl_FragCoord.z, gl_FragCoord.w);
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    mediump vec4 output_Stage2;
+    {
+        mediump vec2 coords = sk_FragCoord.xy * uscaleAndTranslate_Stage2.xy + uscaleAndTranslate_Stage2.zw;
+        {
+            highp vec2 origCoord = coords;
+            highp vec2 clampedCoord = clamp(origCoord, uTexDom_Stage2.xy, uTexDom_Stage2.zw);
+            mediump vec4 inside = texture2D(uTextureSampler_0_Stage2, clampedCoord).wwww;
+            mediump float err = max(abs(clampedCoord.x - origCoord.x) * uDecalParams_Stage2.x, abs(clampedCoord.y - origCoord.y) * uDecalParams_Stage2.y);
+            if (err > uDecalParams_Stage2.z) {
+                err = 1.0;
+            } else if (uDecalParams_Stage2.z < 1.0) {
+                err = 0.0;
+            }
+            output_Stage2 = mix(inside, vec4(0.0, 0.0, 0.0, 0.0), err);
+        }
+    }
+    {
+        gl_FragColor = output_Stage1 * output_Stage2;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl
new file mode 100644
index 0000000..5f2b1d3
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold.glsl
@@ -0,0 +1,76 @@
+#version 100
+
+#extension GL_OES_standard_derivatives : require
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vQuadEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float edgeAlpha;
+        mediump vec2 duvdx = dFdx(vQuadEdge_Stage0.xy);
+        mediump vec2 duvdy = -dFdy(vQuadEdge_Stage0.xy);
+        if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
+            edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
+        } else {
+            mediump vec2 gF = vec2((2.0 * vQuadEdge_Stage0.x) * duvdx.x - duvdx.y, (2.0 * vQuadEdge_Stage0.x) * duvdy.x - duvdy.y);
+            edgeAlpha = vQuadEdge_Stage0.x * vQuadEdge_Stage0.x - vQuadEdge_Stage0.y;
+            edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
+        }
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl
new file mode 100644
index 0000000..084c066
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_2.glsl
@@ -0,0 +1,78 @@
+#version 100
+
+#extension GL_OES_standard_derivatives : require
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vQuadEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    mediump vec4 outputCoverage_Stage0;
+    {
+        outputColor_Stage0 = vinColor_Stage0;
+        mediump float edgeAlpha;
+        mediump vec2 duvdx = dFdx(vQuadEdge_Stage0.xy);
+        mediump vec2 duvdy = -dFdy(vQuadEdge_Stage0.xy);
+        if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
+            edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
+        } else {
+            mediump vec2 gF = vec2((2.0 * vQuadEdge_Stage0.x) * duvdx.x - duvdx.y, (2.0 * vQuadEdge_Stage0.x) * duvdy.x - duvdy.y);
+            edgeAlpha = vQuadEdge_Stage0.x * vQuadEdge_Stage0.x - vQuadEdge_Stage0.y;
+            edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
+        }
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl
new file mode 100644
index 0000000..cb27f80
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_threshold_3.glsl
@@ -0,0 +1,79 @@
+#version 100
+
+#extension GL_OES_standard_derivatives : require
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vQuadEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float edgeAlpha;
+        mediump vec2 duvdx = dFdx(vQuadEdge_Stage0.xy);
+        mediump vec2 duvdy = -dFdy(vQuadEdge_Stage0.xy);
+        if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
+            edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
+        } else {
+            mediump vec2 gF = vec2((2.0 * vQuadEdge_Stage0.x) * duvdx.x - duvdx.y, (2.0 * vQuadEdge_Stage0.x) * duvdy.x - duvdy.y);
+            edgeAlpha = vQuadEdge_Stage0.x * vQuadEdge_Stage0.x - vQuadEdge_Stage0.y;
+            edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
+        }
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl
new file mode 100644
index 0000000..1ba24f6
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds.glsl
@@ -0,0 +1,88 @@
+#version 100
+
+#extension GL_OES_standard_derivatives : require
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vQuadEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float edgeAlpha;
+        mediump vec2 duvdx = dFdx(vQuadEdge_Stage0.xy);
+        mediump vec2 duvdy = -dFdy(vQuadEdge_Stage0.xy);
+        if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
+            edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
+        } else {
+            mediump vec2 gF = vec2((2.0 * vQuadEdge_Stage0.x) * duvdx.x - duvdx.y, (2.0 * vQuadEdge_Stage0.x) * duvdy.x - duvdy.y);
+            edgeAlpha = vQuadEdge_Stage0.x * vQuadEdge_Stage0.x - vQuadEdge_Stage0.y;
+            edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
+        }
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl
new file mode 100644
index 0000000..da56a36
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_quad_scale_thresholds_2.glsl
@@ -0,0 +1,93 @@
+#version 100
+
+#extension GL_OES_standard_derivatives : require
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vQuadEdge_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump float edgeAlpha;
+        mediump vec2 duvdx = dFdx(vQuadEdge_Stage0.xy);
+        mediump vec2 duvdy = -dFdy(vQuadEdge_Stage0.xy);
+        if (vQuadEdge_Stage0.z > 0.0 && vQuadEdge_Stage0.w > 0.0) {
+            edgeAlpha = min(min(vQuadEdge_Stage0.z, vQuadEdge_Stage0.w) + 0.5, 1.0);
+        } else {
+            mediump vec2 gF = vec2((2.0 * vQuadEdge_Stage0.x) * duvdx.x - duvdx.y, (2.0 * vQuadEdge_Stage0.x) * duvdy.x - duvdy.y);
+            edgeAlpha = vQuadEdge_Stage0.x * vQuadEdge_Stage0.x - vQuadEdge_Stage0.y;
+            edgeAlpha = clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);
+        }
+        outputCoverage_Stage0 = vec4(edgeAlpha);
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl
new file mode 100644
index 0000000..e2ec055
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold.glsl
@@ -0,0 +1,73 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage0;
+varying highp vec2 vTextureCoords_Stage0;
+varying highp float vTexIndex_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    mediump vec4 outputCoverage_Stage0;
+    {
+        outputColor_Stage0 = vinColor_Stage0;
+        mediump vec4 texColor;
+        {
+            texColor = texture2D(uTextureSampler_0_Stage0, vTextureCoords_Stage0).wwww;
+        }
+        outputCoverage_Stage0 = texColor;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl
new file mode 100644
index 0000000..fe3a8ae
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_2.glsl
@@ -0,0 +1,74 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage0;
+varying highp vec2 vTextureCoords_Stage0;
+varying highp float vTexIndex_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump vec4 texColor;
+        {
+            texColor = texture2D(uTextureSampler_0_Stage0, vTextureCoords_Stage0).wwww;
+        }
+        outputCoverage_Stage0 = texColor;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl
new file mode 100644
index 0000000..f1bbe9d
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_threshold_3.glsl
@@ -0,0 +1,71 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage0;
+varying highp vec2 vTextureCoords_Stage0;
+varying highp float vTexIndex_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump vec4 texColor;
+        {
+            texColor = texture2D(uTextureSampler_0_Stage0, vTextureCoords_Stage0).wwww;
+        }
+        outputCoverage_Stage0 = texColor;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl
new file mode 100644
index 0000000..b073544
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texindex_texturew_thresholds.glsl
@@ -0,0 +1,86 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage0;
+varying highp vec2 vTextureCoords_Stage0;
+varying highp float vTexIndex_Stage0;
+varying mediump vec4 vinColor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 outputCoverage_Stage0;
+    {
+        mediump vec4 texColor;
+        {
+            texColor = texture2D(uTextureSampler_0_Stage0, vTextureCoords_Stage0).wwww;
+        }
+        outputCoverage_Stage0 = texColor;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1 * outputCoverage_Stage0;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texture_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texture_threshold.glsl
new file mode 100644
index 0000000..4522b68
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texture_threshold.glsl
@@ -0,0 +1,89 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage2_c1_c0_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage2_c1_c0_c0_c0;
+uniform mediump float ubias_Stage2_c1_c0_c0_c0_c0_c0;
+uniform mediump float uscale_Stage2_c1_c0_c0_c0_c0_c0;
+uniform highp vec4 uscale01_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage2_c1_c0_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage2_c1_c0_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage1;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying highp vec2 vTransformedCoords_1_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    _sample1992 = _input * texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0);
+    return _sample1992;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c1_c0_c0_c0;
+    mediump float angle;
+    {
+        angle = atan(-vTransformedCoords_1_Stage0.y, -vTransformedCoords_1_Stage0.x);
+    }
+    mediump float t = ((angle * 0.15915493667125702 + 0.5) + ubias_Stage2_c1_c0_c0_c0_c0_c0) * uscale_Stage2_c1_c0_c0_c0_c0_c0;
+    _sample1099_c1_c0_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c1_c0_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage2_c1_c0_c0_c0_c1_c0) {
+        scale = uscale01_Stage2_c1_c0_c0_c0_c1_c0;
+        bias = ubias01_Stage2_c1_c0_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage2_c1_c0_c0_c0_c1_c0;
+        bias = ubias23_Stage2_c1_c0_c0_c0_c1_c0;
+    }
+    _sample1767_c1_c0_c0_c0 = t * scale + bias;
+    return _sample1767_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 child_c1_c0;
+    mediump vec4 _sample1099_c1_c0_c0_c0;
+    _sample1099_c1_c0_c0_c0 = stage_Stage2_c1_c0_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c1_c0_c0_c0;
+    if (t.x < 0.0) {
+        child_c1_c0 = uleftBorderColor_Stage2_c1_c0_c0_c0;
+    } else if (t.x > 1.0) {
+        child_c1_c0 = urightBorderColor_Stage2_c1_c0_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c1_c0_c0_c0;
+        _sample1767_c1_c0_c0_c0 = stage_Stage2_c1_c0_c0_c0_c1_c0(t);
+        child_c1_c0 = _sample1767_c1_c0_c0_c0;
+    }
+    {
+        child_c1_c0.xyz *= child_c1_c0.w;
+    }
+    return child_c1_c0;
+}
+mediump vec4 stage_Stage2_c1_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 child_c1_c0;
+    child_c1_c0 = stage_Stage2_c1_c0_c0_c0(vec4(1.0));
+    child = child_c1_c0 * _input.w;
+    return child;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    mediump vec4 output_Stage2;
+    {
+        mediump vec4 child;
+        child = stage_Stage2_c1_c0(vec4(1.0));
+        output_Stage2 = vec4(child.w);
+    }
+    {
+        gl_FragColor = output_Stage1 * output_Stage2;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texturew_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texturew_threshold.glsl
new file mode 100644
index 0000000..987a9fd
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_texturew_threshold.glsl
@@ -0,0 +1,69 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage2;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying highp vec2 vTransformedCoords_1_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    mediump vec4 output_Stage2;
+    {
+        output_Stage2 = texture2D(uTextureSampler_0_Stage2, vTransformedCoords_1_Stage0).wwww;
+    }
+    {
+        gl_FragColor = output_Stage1 * output_Stage2;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl
new file mode 100644
index 0000000..3657419
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold.glsl
@@ -0,0 +1,67 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    {
+        child.xyz *= child.w;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold_2.glsl
new file mode 100644
index 0000000..a80e7d6
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_threshold_2.glsl
@@ -0,0 +1,60 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c0_c0_c1_c0;
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl
new file mode 100644
index 0000000..6e1c100
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds.glsl
@@ -0,0 +1,84 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying mediump vec4 vcolor_Stage0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    {
+        child.xyz *= child.w;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl
new file mode 100644
index 0000000..e055c58
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_2.glsl
@@ -0,0 +1,84 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    {
+        child.xyz *= child.w;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_3.glsl
new file mode 100644
index 0000000..be9d988
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_3.glsl
@@ -0,0 +1,81 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_4.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_4.glsl
new file mode 100644
index 0000000..cb3bcb1
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_4.glsl
@@ -0,0 +1,91 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale10_11_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias10_11_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.w) {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    } else {
+        {
+            if (t < uthresholds9_13_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale8_9_Stage1_c0_c0_c1_c0;
+                bias = ubias8_9_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale10_11_Stage1_c0_c0_c1_c0;
+                bias = ubias10_11_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_5.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_5.glsl
new file mode 100644
index 0000000..68b87cd
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_5.glsl
@@ -0,0 +1,77 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_6.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_6.glsl
new file mode 100644
index 0000000..36f18a2
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_6.glsl
@@ -0,0 +1,94 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale10_11_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias10_11_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.w) {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    } else {
+        {
+            if (t < uthresholds9_13_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale8_9_Stage1_c0_c0_c1_c0;
+                bias = ubias8_9_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale10_11_Stage1_c0_c0_c1_c0;
+                bias = ubias10_11_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_7.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_7.glsl
new file mode 100644
index 0000000..a76b32a
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_7.glsl
@@ -0,0 +1,80 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        _sample1992 = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        _sample1992 = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        _sample1992 = _sample1767_c0_c0;
+    }
+    {
+        _sample1992.xyz *= _sample1992.w;
+    }
+    return _sample1992;
+}
+void main() {
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 _sample1992;
+        _sample1992 = stage_Stage1_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+        output_Stage1 = _sample1992;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_8.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_8.glsl
new file mode 100644
index 0000000..f5c5d14
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_8.glsl
@@ -0,0 +1,86 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    {
+        if (t < uthresholds1_7_Stage1_c0_c0_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c0_c0_c1_c0;
+            }
+        } else {
+            {
+                scale = uscale4_5_Stage1_c0_c0_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 child_c0_c0;
+    mediump vec4 _sample1099_c0_c0_c0_c0;
+    _sample1099_c0_c0_c0_c0 = stage_Stage1_c0_c0_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0_c0_c0;
+    if (t.x < 0.0) {
+        child_c0_c0 = uleftBorderColor_Stage1_c0_c0_c0_c0;
+    } else if (t.x > 1.0) {
+        child_c0_c0 = urightBorderColor_Stage1_c0_c0_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0_c0_c0;
+        _sample1767_c0_c0_c0_c0 = stage_Stage1_c0_c0_c0_c0_c1_c0(t);
+        child_c0_c0 = _sample1767_c0_c0_c0_c0;
+    }
+    {
+        child_c0_c0.xyz *= child_c0_c0.w;
+    }
+    return child_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 child_c0_c0;
+    child_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    child = child_c0_c0 * _input.w;
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = vec4(child.w);
+    }
+    {
+        gl_FragColor = outputColor_Stage0 * output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_9.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_9.glsl
new file mode 100644
index 0000000..58cdb65
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_border_color_scale_thresholds_9.glsl
@@ -0,0 +1,95 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform mediump vec4 uleftBorderColor_Stage1_c0_c0;
+uniform mediump vec4 urightBorderColor_Stage1_c0_c0;
+uniform highp vec4 uscale0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 uscale10_11_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias0_1_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias2_3_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias4_5_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias6_7_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias8_9_Stage1_c0_c0_c1_c0;
+uniform highp vec4 ubias10_11_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds1_7_Stage1_c0_c0_c1_c0;
+uniform mediump vec4 uthresholds9_13_Stage1_c0_c0_c1_c0;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1099_c0_c0;
+    mediump float t = vTransformedCoords_0_Stage0.x + 9.9999997473787516e-06;
+    _sample1099_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample1099_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1767_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.w) {
+        if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.y) {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale0_1_Stage1_c0_c0_c1_c0;
+                bias = ubias0_1_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale2_3_Stage1_c0_c0_c1_c0;
+                bias = ubias2_3_Stage1_c0_c0_c1_c0;
+            }
+        } else {
+            if (t < uthresholds1_7_Stage1_c0_c0_c1_c0.z) {
+                scale = uscale4_5_Stage1_c0_c0_c1_c0;
+                bias = ubias4_5_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale6_7_Stage1_c0_c0_c1_c0;
+                bias = ubias6_7_Stage1_c0_c0_c1_c0;
+            }
+        }
+    } else {
+        {
+            if (t < uthresholds9_13_Stage1_c0_c0_c1_c0.x) {
+                scale = uscale8_9_Stage1_c0_c0_c1_c0;
+                bias = ubias8_9_Stage1_c0_c0_c1_c0;
+            } else {
+                scale = uscale10_11_Stage1_c0_c0_c1_c0;
+                bias = ubias10_11_Stage1_c0_c0_c1_c0;
+            }
+        }
+    }
+    _sample1767_c0_c0 = t * scale + bias;
+    return _sample1767_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 child;
+    mediump vec4 _sample1099_c0_c0;
+    _sample1099_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample1099_c0_c0;
+    if (t.x < 0.0) {
+        child = uleftBorderColor_Stage1_c0_c0;
+    } else if (t.x > 1.0) {
+        child = urightBorderColor_Stage1_c0_c0;
+    } else {
+        mediump vec4 _sample1767_c0_c0;
+        _sample1767_c0_c0 = stage_Stage1_c0_c0_c1_c0(t);
+        child = _sample1767_c0_c0;
+    }
+    return child;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 child;
+        child = stage_Stage1_c0_c0(vec4(1.0));
+        output_Stage1 = child * outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold.glsl
new file mode 100644
index 0000000..62db91a
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold.glsl
@@ -0,0 +1,89 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform highp vec4 uscale01_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c1_c0_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c1_c0_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage1;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying highp vec2 vTransformedCoords_1_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 child_c0_c0;
+    child_c0_c0 = _input * texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0);
+    return child_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 xfer_src;
+    mediump vec4 child_c0_c0;
+    child_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    xfer_src = child_c0_c0 * _input.w;
+    return xfer_src;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    mediump float t = vTransformedCoords_1_Stage0.x + 9.9999997473787516e-06;
+    _sample453_c1_c0_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample453_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1464_c1_c0_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c1_c0_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c1_c0_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c1_c0_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c1_c0_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c1_c0_c0_c0_c1_c0;
+    }
+    _sample1464_c1_c0_c0_c0 = t * scale + bias;
+    return _sample1464_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992_c1_c0;
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    _sample453_c1_c0_c0_c0 = stage_Stage1_c1_c0_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample453_c1_c0_c0_c0;
+    {
+        {
+            t.x = fract(t.x);
+        }
+        mediump vec4 _sample1464_c1_c0_c0_c0;
+        _sample1464_c1_c0_c0_c0 = stage_Stage1_c1_c0_c0_c0_c1_c0(t);
+        _sample1992_c1_c0 = _sample1464_c1_c0_c0_c0;
+    }
+    {
+        _sample1992_c1_c0.xyz *= _sample1992_c1_c0.w;
+    }
+    return _sample1992_c1_c0;
+}
+mediump vec4 stage_Stage1_c1_c0(mediump vec4 _input) {
+    mediump vec4 xfer_dst;
+    mediump vec4 _sample1992_c1_c0;
+    _sample1992_c1_c0 = stage_Stage1_c1_c0_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+    xfer_dst = _sample1992_c1_c0;
+    return xfer_dst;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 inputColor = vec4(outputColor_Stage0.xyz, 1.0);
+        mediump vec4 xfer_src;
+        xfer_src = stage_Stage1_c0_c0(inputColor);
+        mediump vec4 xfer_dst;
+        xfer_dst = stage_Stage1_c1_c0(inputColor);
+        output_Stage1 = xfer_src * xfer_dst.w;
+        output_Stage1 *= outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_2.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_2.glsl
new file mode 100644
index 0000000..77855e7
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_2.glsl
@@ -0,0 +1,89 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform highp vec4 uscale01_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage1_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage1_c1_c0_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage1_c1_c0_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage1;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying highp vec2 vTransformedCoords_1_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 child_c0_c0;
+    child_c0_c0 = _input * texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0);
+    return child_c0_c0;
+}
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 xfer_src;
+    mediump vec4 child_c0_c0;
+    child_c0_c0 = stage_Stage1_c0_c0_c0_c0(vec4(1.0));
+    xfer_src = child_c0_c0 * _input.w;
+    return xfer_src;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    mediump float t = vTransformedCoords_1_Stage0.x + 9.9999997473787516e-06;
+    _sample453_c1_c0_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample453_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1464_c1_c0_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage1_c1_c0_c0_c0_c1_c0) {
+        scale = uscale01_Stage1_c1_c0_c0_c0_c1_c0;
+        bias = ubias01_Stage1_c1_c0_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage1_c1_c0_c0_c0_c1_c0;
+        bias = ubias23_Stage1_c1_c0_c0_c0_c1_c0;
+    }
+    _sample1464_c1_c0_c0_c0 = t * scale + bias;
+    return _sample1464_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage1_c1_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992_c1_c0;
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    _sample453_c1_c0_c0_c0 = stage_Stage1_c1_c0_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t = _sample453_c1_c0_c0_c0;
+    {
+        {
+            t.x = fract(t.x);
+        }
+        mediump vec4 _sample1464_c1_c0_c0_c0;
+        _sample1464_c1_c0_c0_c0 = stage_Stage1_c1_c0_c0_c0_c1_c0(t);
+        _sample1992_c1_c0 = _sample1464_c1_c0_c0_c0;
+    }
+    {
+        _sample1992_c1_c0.xyz *= _sample1992_c1_c0.w;
+    }
+    return _sample1992_c1_c0;
+}
+mediump vec4 stage_Stage1_c1_c0(mediump vec4 _input) {
+    mediump vec4 xfer_dst;
+    mediump vec4 _sample1992_c1_c0;
+    _sample1992_c1_c0 = stage_Stage1_c1_c0_c0_c0(vec4(1.0, 1.0, 1.0, 1.0));
+    xfer_dst = _sample1992_c1_c0;
+    return xfer_dst;
+}
+void main() {
+    mediump vec4 outputColor_Stage0;
+    {
+        outputColor_Stage0 = vcolor_Stage0;
+    }
+    mediump vec4 output_Stage1;
+    {
+        mediump vec4 inputColor = vec4(outputColor_Stage0.xyz, 1.0);
+        mediump vec4 xfer_src;
+        xfer_src = stage_Stage1_c0_c0(inputColor);
+        mediump vec4 xfer_dst;
+        xfer_dst = stage_Stage1_c1_c0(inputColor);
+        output_Stage1 = xfer_src * (1.0 - xfer_dst.w);
+        output_Stage1 *= outputColor_Stage0.w;
+    }
+    {
+        gl_FragColor = output_Stage1;
+    }
+}
diff --git a/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_3.glsl b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_3.glsl
new file mode 100644
index 0000000..52553ba
--- /dev/null
+++ b/src/cobalt/renderer/glimp_shaders/glsl/fragment_skia_bias_color_scale_texture_threshold_3.glsl
@@ -0,0 +1,80 @@
+#version 100
+
+precision mediump float;
+precision mediump sampler2D;
+uniform highp vec4 uscale01_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias01_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 uscale23_Stage2_c1_c0_c0_c0_c1_c0;
+uniform highp vec4 ubias23_Stage2_c1_c0_c0_c0_c1_c0;
+uniform mediump float uthreshold_Stage2_c1_c0_c0_c0_c1_c0;
+uniform sampler2D uTextureSampler_0_Stage1;
+varying highp vec2 vTransformedCoords_0_Stage0;
+varying highp vec2 vTransformedCoords_1_Stage0;
+varying mediump vec4 vcolor_Stage0;
+mediump vec4 stage_Stage1_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample1992;
+    _sample1992 = _input * texture2D(uTextureSampler_0_Stage1, vTransformedCoords_0_Stage0);
+    return _sample1992;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    mediump float t = vTransformedCoords_1_Stage0.x + 9.9999997473787516e-06;
+    _sample453_c1_c0_c0_c0 = vec4(t, 1.0, 0.0, 0.0);
+    return _sample453_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0_c1_c0(mediump vec4 _input) {
+    mediump vec4 _sample1464_c1_c0_c0_c0;
+    mediump float t = _input.x;
+    highp vec4 scale, bias;
+    if (t < uthreshold_Stage2_c1_c0_c0_c0_c1_c0) {
+        scale = uscale01_Stage2_c1_c0_c0_c0_c1_c0;
+        bias = ubias01_Stage2_c1_c0_c0_c0_c1_c0;
+    } else {
+        scale = uscale23_Stage2_c1_c0_c0_c0_c1_c0;
+        bias = ubias23_Stage2_c1_c0_c0_c0_c1_c0;
+    }
+    _sample1464_c1_c0_c0_c0 = t * scale + bias;
+    return _sample1464_c1_c0_c0_c0;
+}
+mediump vec4 stage_Stage2_c1_c0_c0_c0(mediump vec4 _input) {
+    mediump vec4 child_c1_c0;
+    mediump vec4 _sample453_c1_c0_c0_c0;
+    _sample453_c1_c0_c0_c0 = stage_Stage2_c1_c0_c0_c0_c0_c0(vec4(1.0));
+    mediump vec4 t =