diff --git a/cc/BUILD.gn b/cc/BUILD.gn
deleted file mode 100644
index 1f723c0..0000000
--- a/cc/BUILD.gn
+++ /dev/null
@@ -1,387 +0,0 @@
-# Copyright 2014 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.
-
-import("//testing/test.gni")
-
-source_set("cc") {
-  sources = [
-    "debug/frame_timing_request.cc",
-    "debug/frame_timing_request.h",
-    "debug/lap_timer.cc",
-    "debug/lap_timer.h",
-    "debug/paint_time_counter.cc",
-    "debug/paint_time_counter.h",
-    "debug/rendering_stats.cc",
-    "debug/rendering_stats.h",
-    "debug/rendering_stats_instrumentation.cc",
-    "debug/rendering_stats_instrumentation.h",
-    "debug/ring_buffer.h",
-    "debug/traced_value.cc",
-    "debug/traced_value.h",
-    "output/begin_frame_args.cc",
-    "output/begin_frame_args.h",
-    "output/bsp_tree.cc",
-    "output/bsp_tree.h",
-    "output/bsp_walk_action.cc",
-    "output/bsp_walk_action.h",
-    "output/compositor_frame.cc",
-    "output/compositor_frame.h",
-    "output/compositor_frame_ack.cc",
-    "output/compositor_frame_ack.h",
-    "output/compositor_frame_metadata.cc",
-    "output/compositor_frame_metadata.h",
-    "output/context_provider.cc",
-    "output/context_provider.h",
-    "output/copy_output_request.cc",
-    "output/copy_output_request.h",
-    "output/copy_output_result.cc",
-    "output/copy_output_result.h",
-    "output/delegated_frame_data.cc",
-    "output/delegated_frame_data.h",
-    "output/delegating_renderer.cc",
-    "output/delegating_renderer.h",
-    "output/direct_renderer.cc",
-    "output/direct_renderer.h",
-    "output/dynamic_geometry_binding.cc",
-    "output/dynamic_geometry_binding.h",
-    "output/filter_operation.cc",
-    "output/filter_operation.h",
-    "output/filter_operations.cc",
-    "output/filter_operations.h",
-    "output/geometry_binding.cc",
-    "output/geometry_binding.h",
-    "output/gl_frame_data.cc",
-    "output/gl_frame_data.h",
-    "output/gl_renderer.cc",
-    "output/gl_renderer.h",
-    "output/gl_renderer_draw_cache.cc",
-    "output/gl_renderer_draw_cache.h",
-    "output/output_surface.cc",
-    "output/output_surface.h",
-    "output/output_surface_client.h",
-    "output/overlay_candidate.cc",
-    "output/overlay_candidate.h",
-    "output/overlay_candidate_validator.h",
-    "output/overlay_processor.cc",
-    "output/overlay_processor.h",
-    "output/overlay_strategy_single_on_top.cc",
-    "output/overlay_strategy_single_on_top.h",
-    "output/program_binding.cc",
-    "output/program_binding.h",
-    "output/render_surface_filters.cc",
-    "output/render_surface_filters.h",
-    "output/renderer.cc",
-    "output/renderer.h",
-    "output/renderer_capabilities.cc",
-    "output/renderer_capabilities.h",
-    "output/renderer_settings.cc",
-    "output/renderer_settings.h",
-    "output/shader.cc",
-    "output/shader.h",
-    "output/software_frame_data.cc",
-    "output/software_frame_data.h",
-    "output/software_output_device.cc",
-    "output/software_output_device.h",
-    "output/software_renderer.cc",
-    "output/software_renderer.h",
-    "output/static_geometry_binding.cc",
-    "output/static_geometry_binding.h",
-    "output/vsync_parameter_observer.h",
-    "quads/checkerboard_draw_quad.cc",
-    "quads/checkerboard_draw_quad.h",
-    "quads/content_draw_quad_base.cc",
-    "quads/content_draw_quad_base.h",
-    "quads/debug_border_draw_quad.cc",
-    "quads/debug_border_draw_quad.h",
-    "quads/draw_polygon.cc",
-    "quads/draw_polygon.h",
-    "quads/draw_quad.cc",
-    "quads/draw_quad.h",
-    "quads/io_surface_draw_quad.cc",
-    "quads/io_surface_draw_quad.h",
-    "quads/largest_draw_quad.cc",
-    "quads/largest_draw_quad.h",
-    "quads/list_container.cc",
-    "quads/list_container.h",
-    "quads/render_pass.cc",
-    "quads/render_pass.h",
-    "quads/render_pass_draw_quad.cc",
-    "quads/render_pass_draw_quad.h",
-    "quads/render_pass_id.cc",
-    "quads/render_pass_id.h",
-    "quads/shared_quad_state.cc",
-    "quads/shared_quad_state.h",
-    "quads/solid_color_draw_quad.cc",
-    "quads/solid_color_draw_quad.h",
-    "quads/stream_video_draw_quad.cc",
-    "quads/stream_video_draw_quad.h",
-    "quads/surface_draw_quad.cc",
-    "quads/surface_draw_quad.h",
-    "quads/texture_draw_quad.cc",
-    "quads/texture_draw_quad.h",
-    "quads/tile_draw_quad.cc",
-    "quads/tile_draw_quad.h",
-    "quads/yuv_video_draw_quad.cc",
-    "quads/yuv_video_draw_quad.h",
-    "resources/layer_quad.cc",
-    "resources/layer_quad.h",
-    "resources/platform_color.h",
-    "resources/release_callback.h",
-    "resources/resource.cc",
-    "resources/resource.h",
-    "resources/resource_format.cc",
-    "resources/resource_format.h",
-    "resources/resource_pool.cc",
-    "resources/resource_pool.h",
-    "resources/resource_provider.cc",
-    "resources/resource_provider.h",
-    "resources/returned_resource.h",
-    "resources/scoped_resource.cc",
-    "resources/scoped_resource.h",
-    "resources/shared_bitmap.cc",
-    "resources/shared_bitmap.h",
-    "resources/shared_bitmap_manager.h",
-    "resources/single_release_callback.cc",
-    "resources/single_release_callback.h",
-    "resources/single_release_callback_impl.cc",
-    "resources/single_release_callback_impl.h",
-    "resources/texture_compressor.cc",
-    "resources/texture_compressor.h",
-    "resources/texture_compressor_etc1.cc",
-    "resources/texture_compressor_etc1.h",
-    "resources/texture_mailbox.cc",
-    "resources/texture_mailbox.h",
-    "resources/texture_mailbox_deleter.cc",
-    "resources/texture_mailbox_deleter.h",
-    "resources/texture_uploader.cc",
-    "resources/texture_uploader.h",
-    "resources/transferable_resource.cc",
-    "resources/transferable_resource.h",
-    "scheduler/begin_frame_source.cc",
-    "scheduler/begin_frame_source.h",
-    "scheduler/commit_earlyout_reason.h",
-    "scheduler/delay_based_time_source.cc",
-    "scheduler/delay_based_time_source.h",
-    "scheduler/draw_result.h",
-    "scheduler/scheduler.cc",
-    "scheduler/scheduler.h",
-    "scheduler/scheduler_settings.cc",
-    "scheduler/scheduler_settings.h",
-    "scheduler/scheduler_state_machine.cc",
-    "scheduler/scheduler_state_machine.h",
-  ]
-
-  # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
-  public_deps = [
-    "//cc/base",
-    "//skia",
-  ]
-  deps = [
-    "//base",
-    "//base/third_party/dynamic_annotations",
-    "//cc/surfaces:surface_id",
-    "//gpu",
-    "//gpu/command_buffer/client:gles2_interface",
-    "//gpu/command_buffer/client:gpu_memory_buffer_manager",
-    "//ui/events:events_base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-  ]
-
-  defines = [ "CC_IMPLEMENTATION=1" ]
-
-  if (!is_debug && (is_win || is_android)) {
-    configs -= [ "//build/config/compiler:optimize" ]
-    configs += [ "//build/config/compiler:optimize_max" ]
-  }
-}
-
-source_set("test_support") {
-  testonly = true
-  sources = [
-    "test/begin_frame_args_test.cc",
-    "test/begin_frame_args_test.h",
-    "test/failure_output_surface.cc",
-    "test/failure_output_surface.h",
-    "test/fake_external_begin_frame_source.cc",
-    "test/fake_external_begin_frame_source.h",
-    "test/fake_output_surface.cc",
-    "test/fake_output_surface.h",
-    "test/fake_output_surface_client.cc",
-    "test/fake_output_surface_client.h",
-    "test/fake_renderer_client.cc",
-    "test/fake_renderer_client.h",
-    "test/geometry_test_utils.cc",
-    "test/geometry_test_utils.h",
-    "test/mock_occlusion_tracker.h",
-    "test/ordered_simple_task_runner.cc",
-    "test/ordered_simple_task_runner.h",
-    "test/ordered_texture_map.cc",
-    "test/ordered_texture_map.h",
-    "test/paths.cc",
-    "test/paths.h",
-    "test/pixel_comparator.cc",
-    "test/pixel_comparator.h",
-    "test/pixel_test.cc",
-    "test/pixel_test.h",
-    "test/pixel_test_output_surface.cc",
-    "test/pixel_test_output_surface.h",
-    "test/pixel_test_software_output_device.cc",
-    "test/pixel_test_software_output_device.h",
-    "test/pixel_test_utils.cc",
-    "test/pixel_test_utils.h",
-    "test/render_pass_test_common.cc",
-    "test/render_pass_test_common.h",
-    "test/render_pass_test_utils.cc",
-    "test/render_pass_test_utils.h",
-    "test/scheduler_test_common.cc",
-    "test/scheduler_test_common.h",
-    "test/skia_common.cc",
-    "test/skia_common.h",
-    "test/test_context_provider.cc",
-    "test/test_context_provider.h",
-    "test/test_context_support.cc",
-    "test/test_context_support.h",
-    "test/test_gles2_interface.cc",
-    "test/test_gles2_interface.h",
-    "test/test_gpu_memory_buffer_manager.cc",
-    "test/test_gpu_memory_buffer_manager.h",
-    "test/test_image_factory.cc",
-    "test/test_image_factory.h",
-    "test/test_in_process_context_provider.cc",
-    "test/test_in_process_context_provider.h",
-    "test/test_now_source.cc",
-    "test/test_now_source.h",
-    "test/test_occlusion_tracker.h",
-    "test/test_shared_bitmap_manager.cc",
-    "test/test_shared_bitmap_manager.h",
-    "test/test_task_graph_runner.cc",
-    "test/test_task_graph_runner.h",
-    "test/test_texture.cc",
-    "test/test_texture.h",
-  ]
-
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
-  include_dirs = [
-    ".",
-    "test",
-  ]
-
-  public_deps = [
-    ":cc",
-    "//gpu:test_support",
-  ]
-  deps = [
-    "//base",
-    "//base/test:test_support",
-    "//base/third_party/dynamic_annotations",
-    "//gpu/command_buffer/client:gles2_c_lib",
-    "//gpu/command_buffer/client:gles2_implementation",
-    "//gpu/command_buffer/client:gpu_memory_buffer_manager",
-    "//gpu/command_buffer/client:gl_in_process_context",
-    "//gpu/command_buffer/common:gles2_utils",
-    "//gpu/skia_bindings",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/gfx:test_support",
-    "//ui/gl",
-  ]
-
-  if (!is_android) {  # TODO(GYP) Enable on Android when osmesa links.
-    deps += [ "//third_party/mesa:osmesa" ]
-  }
-}
-
-test("cc_unittests") {
-  sources = [
-    "base/float_quad_unittest.cc",
-    "base/math_util_unittest.cc",
-    "base/scoped_ptr_vector_unittest.cc",
-    "base/util_unittest.cc",
-    "output/begin_frame_args_unittest.cc",
-    "output/delegating_renderer_unittest.cc",
-    "output/filter_operations_unittest.cc",
-    "output/gl_renderer_unittest.cc",
-    "output/output_surface_unittest.cc",
-    "output/overlay_unittest.cc",
-    "output/renderer_pixeltest.cc",
-    "output/renderer_unittest.cc",
-    "output/shader_unittest.cc",
-    "output/software_renderer_unittest.cc",
-    "quads/draw_quad_unittest.cc",
-    "quads/list_container_unittest.cc",
-    "quads/render_pass_unittest.cc",
-    "resources/platform_color_unittest.cc",
-    "resources/resource_provider_unittest.cc",
-    "scheduler/begin_frame_source_unittest.cc",
-    "scheduler/delay_based_time_source_unittest.cc",
-    "scheduler/scheduler_state_machine_unittest.cc",
-    "scheduler/scheduler_unittest.cc",
-
-    # Surfaces test files.
-    "surfaces/surface_aggregator_test_helpers.cc",
-    "surfaces/surface_aggregator_test_helpers.h",
-    "surfaces/surface_aggregator_unittest.cc",
-    "surfaces/surface_unittest.cc",
-    "surfaces/surfaces_pixeltest.cc",
-
-    # Setup.
-    "test/cc_test_suite.cc",
-    "test/run_all_unittests.cc",
-  ]
-
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
-  deps = [
-    ":cc",
-    ":test_support",
-    "//base/test:test_support",
-    "//cc/surfaces",
-    "//cc/surfaces:surface_id",
-    "//gpu",
-    "//gpu:test_support",
-    "//gpu/command_buffer/client:gles2_interface",
-    "//gpu/command_buffer/common:gles2_utils",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//ui/events:events_base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/gfx:test_support",
-    "//ui/gl",
-  ]
-}
-
-test("cc_perftests") {
-  sources = [
-    "resources/texture_compressor_perftest.cc",
-    "test/cc_test_suite.cc",
-    "test/run_all_perftests.cc",
-  ]
-
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
-
-  deps = [
-    ":cc",
-    ":test_support",
-    "//base",
-    "//base/test:test_support",
-    "//gpu",
-    "//gpu:test_support",
-    "//gpu/command_buffer/common:gles2_utils",
-    "//skia",
-    "//testing/gmock",
-    "//testing/gtest",
-    "//testing/perf",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-    "//ui/gl",
-  ]
-}
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py
deleted file mode 100644
index b34027a..0000000
--- a/cc/PRESUBMIT.py
+++ /dev/null
@@ -1,328 +0,0 @@
-# Copyright (c) 2012 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.
-
-"""Top-level presubmit script for cc.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into depot_tools.
-"""
-
-import re
-import string
-
-CC_SOURCE_FILES=(r'^cc[\\/].*\.(cc|h)$',)
-
-def CheckChangeLintsClean(input_api, output_api):
-  source_filter = lambda x: input_api.FilterSourceFile(
-    x, white_list=CC_SOURCE_FILES, black_list=None)
-
-  return input_api.canned_checks.CheckChangeLintsClean(
-      input_api, output_api, source_filter, lint_filters=[], verbose_level=1)
-
-def CheckAsserts(input_api, output_api, white_list=CC_SOURCE_FILES, black_list=None):
-  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x, white_list, black_list)
-
-  assert_files = []
-  notreached_files = []
-
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    # WebKit ASSERT() is not allowed.
-    if re.search(r"\bASSERT\(", contents):
-      assert_files.append(f.LocalPath())
-    # WebKit ASSERT_NOT_REACHED() is not allowed.
-    if re.search(r"ASSERT_NOT_REACHED\(", contents):
-      notreached_files.append(f.LocalPath())
-
-  if assert_files:
-    return [output_api.PresubmitError(
-      'These files use ASSERT instead of using DCHECK:',
-      items=assert_files)]
-  if notreached_files:
-    return [output_api.PresubmitError(
-      'These files use ASSERT_NOT_REACHED instead of using NOTREACHED:',
-      items=notreached_files)]
-  return []
-
-def CheckStdAbs(input_api, output_api,
-                white_list=CC_SOURCE_FILES, black_list=None):
-  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x,
-                                                            white_list,
-                                                            black_list)
-
-  using_std_abs_files = []
-  found_fabs_files = []
-  missing_std_prefix_files = []
-
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    if re.search(r"using std::f?abs;", contents):
-      using_std_abs_files.append(f.LocalPath())
-    if re.search(r"\bfabsf?\(", contents):
-      found_fabs_files.append(f.LocalPath());
-
-    no_std_prefix = r"(?<!std::)"
-    # Matches occurrences of abs/absf/fabs/fabsf without a "std::" prefix.
-    abs_without_prefix = r"%s(\babsf?\()" % no_std_prefix
-    fabs_without_prefix = r"%s(\bfabsf?\()" % no_std_prefix
-    # Skips matching any lines that have "// NOLINT".
-    no_nolint = r"(?![^\n]*//\s+NOLINT)"
-
-    expression = re.compile("(%s|%s)%s" %
-        (abs_without_prefix, fabs_without_prefix, no_nolint))
-    if expression.search(contents):
-      missing_std_prefix_files.append(f.LocalPath())
-
-  result = []
-  if using_std_abs_files:
-    result.append(output_api.PresubmitError(
-        'These files have "using std::abs" which is not permitted.',
-        items=using_std_abs_files))
-  if found_fabs_files:
-    result.append(output_api.PresubmitError(
-        'std::abs() should be used instead of std::fabs() for consistency.',
-        items=found_fabs_files))
-  if missing_std_prefix_files:
-    result.append(output_api.PresubmitError(
-        'These files use abs(), absf(), fabs(), or fabsf() without qualifying '
-        'the std namespace. Please use std::abs() in all places.',
-        items=missing_std_prefix_files))
-  return result
-
-def CheckPassByValue(input_api,
-                     output_api,
-                     white_list=CC_SOURCE_FILES,
-                     black_list=None):
-  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x,
-                                                            white_list,
-                                                            black_list)
-
-  local_errors = []
-
-  # Well-defined simple classes containing only <= 4 ints, or <= 2 floats.
-  pass_by_value_types = ['base::Time',
-                         'base::TimeTicks',
-                         ]
-
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    match = re.search(
-      r'\bconst +' + '(?P<type>(%s))&' %
-        string.join(pass_by_value_types, '|'),
-      contents)
-    if match:
-      local_errors.append(output_api.PresubmitError(
-        '%s passes %s by const ref instead of by value.' %
-        (f.LocalPath(), match.group('type'))))
-  return local_errors
-
-def CheckTodos(input_api, output_api):
-  errors = []
-
-  source_file_filter = lambda x: x
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    if ('FIX'+'ME') in contents:
-      errors.append(f.LocalPath())
-
-  if errors:
-    return [output_api.PresubmitError(
-      'All TODO comments should be of the form TODO(name). ' +
-      'Use TODO instead of FIX' + 'ME',
-      items=errors)]
-  return []
-
-def CheckDoubleAngles(input_api, output_api, white_list=CC_SOURCE_FILES,
-                      black_list=None):
-  errors = []
-
-  source_file_filter = lambda x: input_api.FilterSourceFile(x,
-                                                            white_list,
-                                                            black_list)
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    if ('> >') in contents:
-      errors.append(f.LocalPath())
-
-  if errors:
-    return [output_api.PresubmitError('Use >> instead of > >:', items=errors)]
-  return []
-
-def CheckScopedPtr(input_api, output_api,
-                   white_list=CC_SOURCE_FILES, black_list=None):
-  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x,
-                                                            white_list,
-                                                            black_list)
-  errors = []
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    for line_number, line in f.ChangedContents():
-      # Disallow:
-      # return scoped_ptr<T>(foo);
-      # bar = scoped_ptr<T>(foo);
-      # But allow:
-      # return scoped_ptr<T[]>(foo);
-      # bar = scoped_ptr<T[]>(foo);
-      if re.search(r'(=|\breturn)\s*scoped_ptr<.*?(?<!])>\([^)]+\)', line):
-        errors.append(output_api.PresubmitError(
-          ('%s:%d uses explicit scoped_ptr constructor. ' +
-           'Use make_scoped_ptr() instead.') % (f.LocalPath(), line_number)))
-      # Disallow:
-      # scoped_ptr<T>()
-      if re.search(r'\bscoped_ptr<.*?>\(\)', line):
-        errors.append(output_api.PresubmitError(
-          '%s:%d uses scoped_ptr<T>(). Use nullptr instead.' %
-          (f.LocalPath(), line_number)))
-  return errors
-
-def FindUnquotedQuote(contents, pos):
-  match = re.search(r"(?<!\\)(?P<quote>\")", contents[pos:])
-  return -1 if not match else match.start("quote") + pos
-
-def FindUselessIfdefs(input_api, output_api):
-  errors = []
-  source_file_filter = lambda x: x
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    if re.search(r'#if\s*0\s', contents):
-      errors.append(f.LocalPath())
-  if errors:
-    return [output_api.PresubmitError(
-      'Don\'t use #if '+'0; just delete the code.',
-      items=errors)]
-  return []
-
-def FindNamespaceInBlock(pos, namespace, contents, whitelist=[]):
-  open_brace = -1
-  close_brace = -1
-  quote = -1
-  name = -1
-  brace_count = 1
-  quote_count = 0
-  while pos < len(contents) and brace_count > 0:
-    if open_brace < pos: open_brace = contents.find("{", pos)
-    if close_brace < pos: close_brace = contents.find("}", pos)
-    if quote < pos: quote = FindUnquotedQuote(contents, pos)
-    if name < pos: name = contents.find(("%s::" % namespace), pos)
-
-    if name < 0:
-      return False # The namespace is not used at all.
-    if open_brace < 0:
-      open_brace = len(contents)
-    if close_brace < 0:
-      close_brace = len(contents)
-    if quote < 0:
-      quote = len(contents)
-
-    next = min(open_brace, min(close_brace, min(quote, name)))
-
-    if next == open_brace:
-      brace_count += 1
-    elif next == close_brace:
-      brace_count -= 1
-    elif next == quote:
-      quote_count = 0 if quote_count else 1
-    elif next == name and not quote_count:
-      in_whitelist = False
-      for w in whitelist:
-        if re.match(w, contents[next:]):
-          in_whitelist = True
-          break
-      if not in_whitelist:
-        return True
-    pos = next + 1
-  return False
-
-# Checks for the use of cc:: within the cc namespace, which is usually
-# redundant.
-def CheckNamespace(input_api, output_api):
-  errors = []
-
-  source_file_filter = lambda x: x
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    contents = input_api.ReadFile(f, 'rb')
-    match = re.search(r'namespace\s*cc\s*{', contents)
-    if match:
-      whitelist = [
-        r"cc::remove_if\b",
-        ]
-      if FindNamespaceInBlock(match.end(), 'cc', contents, whitelist=whitelist):
-        errors.append(f.LocalPath())
-
-  if errors:
-    return [output_api.PresubmitError(
-      'Do not use cc:: inside of the cc namespace.',
-      items=errors)]
-  return []
-
-def CheckForUseOfWrongClock(input_api,
-                            output_api,
-                            white_list=CC_SOURCE_FILES,
-                            black_list=None):
-  """Make sure new lines of code don't use a clock susceptible to skew."""
-  black_list = tuple(black_list or input_api.DEFAULT_BLACK_LIST)
-  source_file_filter = lambda x: input_api.FilterSourceFile(x,
-                                                            white_list,
-                                                            black_list)
-  # Regular expression that should detect any explicit references to the
-  # base::Time type (or base::Clock/DefaultClock), whether in using decls,
-  # typedefs, or to call static methods.
-  base_time_type_pattern = r'(^|\W)base::(Time|Clock|DefaultClock)(\W|$)'
-
-  # Regular expression that should detect references to the base::Time class
-  # members, such as a call to base::Time::Now.
-  base_time_member_pattern = r'(^|\W)(Time|Clock|DefaultClock)::'
-
-  # Regular expression to detect "using base::Time" declarations.  We want to
-  # prevent these from triggerring a warning.  For example, it's perfectly
-  # reasonable for code to be written like this:
-  #
-  #   using base::Time;
-  #   ...
-  #   int64 foo_us = foo_s * Time::kMicrosecondsPerSecond;
-  using_base_time_decl_pattern = r'^\s*using\s+(::)?base::Time\s*;'
-
-  # Regular expression to detect references to the kXXX constants in the
-  # base::Time class.  We want to prevent these from triggerring a warning.
-  base_time_konstant_pattern = r'(^|\W)Time::k\w+'
-
-  problem_re = input_api.re.compile(
-      r'(' + base_time_type_pattern + r')|(' + base_time_member_pattern + r')')
-  exception_re = input_api.re.compile(
-      r'(' + using_base_time_decl_pattern + r')|(' +
-      base_time_konstant_pattern + r')')
-  problems = []
-  for f in input_api.AffectedSourceFiles(source_file_filter):
-    for line_number, line in f.ChangedContents():
-      if problem_re.search(line):
-        if not exception_re.search(line):
-          problems.append(
-              '  %s:%d\n    %s' % (f.LocalPath(), line_number, line.strip()))
-
-  if problems:
-    return [output_api.PresubmitPromptOrNotify(
-        'You added one or more references to the base::Time class and/or one\n'
-        'of its member functions (or base::Clock/DefaultClock). In cc code,\n'
-        'it is most certainly incorrect! Instead use base::TimeTicks.\n\n'
-        '\n'.join(problems))]
-  else:
-    return []
-
-def CheckChangeOnUpload(input_api, output_api):
-  results = []
-  results += CheckAsserts(input_api, output_api)
-  results += CheckStdAbs(input_api, output_api)
-  results += CheckPassByValue(input_api, output_api)
-  results += CheckChangeLintsClean(input_api, output_api)
-  results += CheckTodos(input_api, output_api)
-  results += CheckDoubleAngles(input_api, output_api)
-  results += CheckScopedPtr(input_api, output_api)
-  results += CheckNamespace(input_api, output_api)
-  results += CheckForUseOfWrongClock(input_api, output_api)
-  results += FindUselessIfdefs(input_api, output_api)
-  results += input_api.canned_checks.CheckPatchFormatted(input_api, output_api)
-  return results
diff --git a/cc/base/BUILD.gn b/cc/base/BUILD.gn
deleted file mode 100644
index b9a803c..0000000
--- a/cc/base/BUILD.gn
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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.
-
-source_set("base") {
-  visibility = [ "//cc" ]
-
-  sources = [
-    "blocking_task_runner.cc",
-    "blocking_task_runner.h",
-    "completion_event.h",
-    "math_util.cc",
-    "math_util.h",
-    "scoped_ptr_deque.h",
-    "scoped_ptr_vector.h",
-    "switches.cc",
-    "switches.h",
-    "util.h",
-  ]
-
-  deps = [
-    "//base",
-    "//base/third_party/dynamic_annotations",
-    "//skia",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-  ]
-
-  defines = [ "CC_IMPLEMENTATION=1" ]
-
-  if (!is_debug && (is_win || is_android)) {
-    configs -= [ "//build/config/compiler:optimize" ]
-    configs += [ "//build/config/compiler:optimize_max" ]
-  }
-}
diff --git a/cc/base/blocking_task_runner.cc b/cc/base/blocking_task_runner.cc
deleted file mode 100644
index d19d237..0000000
--- a/cc/base/blocking_task_runner.cc
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/base/blocking_task_runner.h"
-
-#include <utility>
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop_proxy.h"
-
-namespace cc {
-
-// static
-scoped_ptr<BlockingTaskRunner> BlockingTaskRunner::Create(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  return make_scoped_ptr(new BlockingTaskRunner(task_runner));
-}
-
-BlockingTaskRunner::BlockingTaskRunner(
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : thread_id_(base::PlatformThread::CurrentId()),
-      task_runner_(task_runner),
-      capture_(0) {
-}
-
-BlockingTaskRunner::~BlockingTaskRunner() {
-}
-
-bool BlockingTaskRunner::BelongsToCurrentThread() {
-  return base::PlatformThread::CurrentId() == thread_id_;
-}
-
-bool BlockingTaskRunner::PostTask(const tracked_objects::Location& from_here,
-                                  const base::Closure& task) {
-  base::AutoLock lock(lock_);
-  DCHECK(task_runner_.get() || capture_);
-  if (!capture_)
-    return task_runner_->PostTask(from_here, task);
-  captured_tasks_.push_back(task);
-  return true;
-}
-
-void BlockingTaskRunner::SetCapture(bool capture) {
-  DCHECK(BelongsToCurrentThread());
-
-  std::vector<base::Closure> tasks;
-
-  {
-    base::AutoLock lock(lock_);
-    capture_ += capture ? 1 : -1;
-    DCHECK_GE(capture_, 0);
-
-    if (capture_)
-      return;
-
-    // We're done capturing, so grab all the captured tasks and run them.
-    tasks.swap(captured_tasks_);
-  }
-  for (size_t i = 0; i < tasks.size(); ++i)
-    tasks[i].Run();
-}
-
-BlockingTaskRunner::CapturePostTasks::CapturePostTasks(
-    BlockingTaskRunner* blocking_runner)
-    : blocking_runner_(blocking_runner) {
-  blocking_runner_->SetCapture(true);
-}
-
-BlockingTaskRunner::CapturePostTasks::~CapturePostTasks() {
-  blocking_runner_->SetCapture(false);
-}
-
-}  // namespace cc
diff --git a/cc/base/blocking_task_runner.h b/cc/base/blocking_task_runner.h
deleted file mode 100644
index f74e21f..0000000
--- a/cc/base/blocking_task_runner.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_BASE_BLOCKING_TASK_RUNNER_H_
-#define CC_BASE_BLOCKING_TASK_RUNNER_H_
-
-#include <vector>
-
-#include "base/location.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/platform_thread.h"
-
-namespace cc {
-
-// This class wraps a SingleThreadTaskRunner but allows posted tasks to be
-// run without a round trip through the message loop. This shortcutting
-// removes guarantees about ordering. Tasks posted while the
-// BlockingTaskRunner is in a capturing state will run in order, and tasks
-// posted while the BlockingTaskRunner is /not/ in a capturing state will
-// run in order, but the two sets of tasks will *not* run in order relative
-// to when they were posted.
-//
-// To use this class, post tasks to the task runner returned by
-// BlockingTaskRunner::Create(). The thread it is created on identifies the
-// thread you want the tasks to run on. The SingleThreadTaskRunner which is
-// passed into Create() is used to run tasks that are posted when not in a
-// capturing state.
-//
-// Then, on the thread that the given task runner belongs to, you may
-// instantiate a BlockingTaskRunner::CapturePostTasks. While this object
-// exists, the task runner will collect any PostTasks called on it, posting
-// tasks to that thread from anywhere. This CapturePostTasks object provides
-// a window in time where tasks can shortcut past the MessageLoop. As soon
-// as the CapturePostTasks object is destroyed (goes out of scope), all
-// tasks that had been posted to the thread during the window will be executed
-// immediately.
-//
-// Beware of re-entrancy, make sure the CapturePostTasks object is destroyed at
-// a time when it makes sense for the embedder to call arbitrary things.
-class BlockingTaskRunner {
- public:
-  // Creates a BlockingTaskRunner for a given SingleThreadTaskRunner.
-  // |task_runner| will be used to run the tasks which are posted while we are
-  // not capturing. |task_runner| should belong to same the thread on which
-  // capturing is done.
-  static scoped_ptr<BlockingTaskRunner> Create(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
-  ~BlockingTaskRunner();
-
-  // While an object of this type is held alive on a thread, any tasks
-  // posted to the thread will be captured and run as soon as the object
-  // is destroyed, shortcutting past the task runner.
-  class CapturePostTasks {
-   public:
-    explicit CapturePostTasks(BlockingTaskRunner* blocking_runner);
-    ~CapturePostTasks();
-
-   private:
-    BlockingTaskRunner* blocking_runner_;
-
-    DISALLOW_COPY_AND_ASSIGN(CapturePostTasks);
-  };
-
-  // True if tasks posted to the BlockingTaskRunner will run on the current
-  // thread.
-  bool BelongsToCurrentThread();
-
-  // Posts a task using the contained SingleThreadTaskRunner unless |capture_|
-  // is true. When |capture_| is true, tasks posted will be caught and stored
-  // until the capturing stops. At that time the tasks will be run directly
-  // instead of being posted to the SingleThreadTaskRunner.
-  bool PostTask(const tracked_objects::Location& from_here,
-                const base::Closure& task);
-
- private:
-  explicit BlockingTaskRunner(
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
-  void SetCapture(bool capture);
-
-  base::PlatformThreadId thread_id_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-  base::Lock lock_;
-  int capture_;
-  std::vector<base::Closure> captured_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(BlockingTaskRunner);
-};
-
-}  // namespace cc
-
-#endif  // CC_BASE_BLOCKING_TASK_RUNNER_H_
diff --git a/cc/base/completion_event.h b/cc/base/completion_event.h
deleted file mode 100644
index 6bae765..0000000
--- a/cc/base/completion_event.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_BASE_COMPLETION_EVENT_H_
-#define CC_BASE_COMPLETION_EVENT_H_
-
-#include "base/logging.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread_restrictions.h"
-
-namespace cc {
-
-// Used for making blocking calls from one thread to another. Use only when
-// absolutely certain that doing-so will not lead to a deadlock.
-//
-// It is safe to destroy this object as soon as Wait() returns.
-class CompletionEvent {
- public:
-  CompletionEvent()
-      : event_(false /* manual_reset */, false /* initially_signaled */) {
-#if DCHECK_IS_ON()
-    waited_ = false;
-    signaled_ = false;
-#endif
-  }
-
-  ~CompletionEvent() {
-#if DCHECK_IS_ON()
-    DCHECK(waited_);
-    DCHECK(signaled_);
-#endif
-  }
-
-  void Wait() {
-#if DCHECK_IS_ON()
-    DCHECK(!waited_);
-    waited_ = true;
-#endif
-    base::ThreadRestrictions::ScopedAllowWait allow_wait;
-    event_.Wait();
-  }
-
-  void Signal() {
-#if DCHECK_IS_ON()
-    DCHECK(!signaled_);
-    signaled_ = true;
-#endif
-    event_.Signal();
-  }
-
- private:
-  base::WaitableEvent event_;
-#if DCHECK_IS_ON()
-  // Used to assert that Wait() and Signal() are each called exactly once.
-  bool waited_;
-  bool signaled_;
-#endif
-};
-
-}  // namespace cc
-
-#endif  // CC_BASE_COMPLETION_EVENT_H_
diff --git a/cc/base/float_quad_unittest.cc b/cc/base/float_quad_unittest.cc
deleted file mode 100644
index 6d9ce02..0000000
--- a/cc/base/float_quad_unittest.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/base/math_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/quad_f.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-// TODO(danakj) Move this test to ui/gfx/ when we don't need MathUtil::MapQuad.
-TEST(FloatQuadTest, IsRectilinearTest) {
-  const int kNumRectilinear = 8;
-  gfx::Transform rectilinear_trans[kNumRectilinear];
-  rectilinear_trans[1].Rotate(90.f);
-  rectilinear_trans[2].Rotate(180.f);
-  rectilinear_trans[3].Rotate(270.f);
-  rectilinear_trans[4].SkewX(0.00000000001f);
-  rectilinear_trans[5].SkewY(0.00000000001f);
-  rectilinear_trans[6].Scale(0.00001f, 0.00001f);
-  rectilinear_trans[6].Rotate(180.f);
-  rectilinear_trans[7].Scale(100000.f, 100000.f);
-  rectilinear_trans[7].Rotate(180.f);
-
-  gfx::QuadF original(
-      gfx::RectF(0.01010101f, 0.01010101f, 100.01010101f, 100.01010101f));
-
-  for (int i = 0; i < kNumRectilinear; ++i) {
-    bool clipped = false;
-    gfx::QuadF quad =
-        MathUtil::MapQuad(rectilinear_trans[i], original, &clipped);
-    ASSERT_TRUE(!clipped) << "case " << i;
-    EXPECT_TRUE(quad.IsRectilinear()) << "case " << i;
-  }
-
-  const int kNumNonRectilinear = 10;
-  gfx::Transform non_rectilinear_trans[kNumNonRectilinear];
-  non_rectilinear_trans[0].Rotate(359.9999f);
-  non_rectilinear_trans[1].Rotate(0.0000001f);
-  non_rectilinear_trans[2].Rotate(89.9999f);
-  non_rectilinear_trans[3].Rotate(90.00001f);
-  non_rectilinear_trans[4].Rotate(179.9999f);
-  non_rectilinear_trans[5].Rotate(180.00001f);
-  non_rectilinear_trans[6].Rotate(269.9999f);
-  non_rectilinear_trans[7].Rotate(270.0001f);
-  non_rectilinear_trans[8].SkewX(0.00001f);
-  non_rectilinear_trans[9].SkewY(0.00001f);
-
-  for (int i = 0; i < kNumNonRectilinear; ++i) {
-    bool clipped = false;
-    gfx::QuadF quad =
-        MathUtil::MapQuad(non_rectilinear_trans[i], original, &clipped);
-    ASSERT_TRUE(!clipped) << "case " << i;
-    EXPECT_FALSE(quad.IsRectilinear()) << "case " << i;
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/base/math_util.cc b/cc/base/math_util.cc
deleted file mode 100644
index e2fd565..0000000
--- a/cc/base/math_util.cc
+++ /dev/null
@@ -1,870 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/base/math_util.h"
-
-#include <algorithm>
-#include <cmath>
-#include <limits>
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "ui/gfx/geometry/quad_f.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-const double MathUtil::kPiDouble = 3.14159265358979323846;
-const float MathUtil::kPiFloat = 3.14159265358979323846f;
-
-static HomogeneousCoordinate ProjectHomogeneousPoint(
-    const gfx::Transform& transform,
-    const gfx::PointF& p) {
-  // In this case, the layer we are trying to project onto is perpendicular to
-  // ray (point p and z-axis direction) that we are trying to project. This
-  // happens when the layer is rotated so that it is infinitesimally thin, or
-  // when it is co-planar with the camera origin -- i.e. when the layer is
-  // invisible anyway.
-  if (!transform.matrix().get(2, 2))
-    return HomogeneousCoordinate(0.0, 0.0, 0.0, 1.0);
-
-  SkMScalar z = -(transform.matrix().get(2, 0) * p.x() +
-             transform.matrix().get(2, 1) * p.y() +
-             transform.matrix().get(2, 3)) /
-             transform.matrix().get(2, 2);
-  HomogeneousCoordinate result(p.x(), p.y(), z, 1.0);
-  transform.matrix().mapMScalars(result.vec, result.vec);
-  return result;
-}
-
-static HomogeneousCoordinate ProjectHomogeneousPoint(
-    const gfx::Transform& transform,
-    const gfx::PointF& p,
-    bool* clipped) {
-  HomogeneousCoordinate h = ProjectHomogeneousPoint(transform, p);
-  *clipped = h.w() <= 0;
-  return h;
-}
-
-static HomogeneousCoordinate MapHomogeneousPoint(
-    const gfx::Transform& transform,
-    const gfx::Point3F& p) {
-  HomogeneousCoordinate result(p.x(), p.y(), p.z(), 1.0);
-  transform.matrix().mapMScalars(result.vec, result.vec);
-  return result;
-}
-
-static HomogeneousCoordinate ComputeClippedPointForEdge(
-    const HomogeneousCoordinate& h1,
-    const HomogeneousCoordinate& h2) {
-  // Points h1 and h2 form a line in 4d, and any point on that line can be
-  // represented as an interpolation between h1 and h2:
-  //    p = (1-t) h1 + (t) h2
-  //
-  // We want to compute point p such that p.w == epsilon, where epsilon is a
-  // small non-zero number. (but the smaller the number is, the higher the risk
-  // of overflow)
-  // To do this, we solve for t in the following equation:
-  //    p.w = epsilon = (1-t) * h1.w + (t) * h2.w
-  //
-  // Once paramter t is known, the rest of p can be computed via
-  //    p = (1-t) h1 + (t) h2.
-
-  // Technically this is a special case of the following assertion, but its a
-  // good idea to keep it an explicit sanity check here.
-  DCHECK_NE(h2.w(), h1.w());
-  // Exactly one of h1 or h2 (but not both) must be on the negative side of the
-  // w plane when this is called.
-  DCHECK(h1.ShouldBeClipped() ^ h2.ShouldBeClipped());
-
-  // ...or any positive non-zero small epsilon
-  SkMScalar w = 0.00001f;
-  SkMScalar t = (w - h1.w()) / (h2.w() - h1.w());
-
-  SkMScalar x = (SK_MScalar1 - t) * h1.x() + t * h2.x();
-  SkMScalar y = (SK_MScalar1 - t) * h1.y() + t * h2.y();
-  SkMScalar z = (SK_MScalar1 - t) * h1.z() + t * h2.z();
-
-  return HomogeneousCoordinate(x, y, z, w);
-}
-
-static inline void ExpandBoundsToIncludePoint(float* xmin,
-                                              float* xmax,
-                                              float* ymin,
-                                              float* ymax,
-                                              const gfx::PointF& p) {
-  *xmin = std::min(p.x(), *xmin);
-  *xmax = std::max(p.x(), *xmax);
-  *ymin = std::min(p.y(), *ymin);
-  *ymax = std::max(p.y(), *ymax);
-}
-
-static inline void AddVertexToClippedQuad(const gfx::PointF& new_vertex,
-                                          gfx::PointF clipped_quad[8],
-                                          int* num_vertices_in_clipped_quad) {
-  clipped_quad[*num_vertices_in_clipped_quad] = new_vertex;
-  (*num_vertices_in_clipped_quad)++;
-}
-
-static inline void AddVertexToClippedQuad3d(const gfx::Point3F& new_vertex,
-                                            gfx::Point3F clipped_quad[8],
-                                            int* num_vertices_in_clipped_quad) {
-  clipped_quad[*num_vertices_in_clipped_quad] = new_vertex;
-  (*num_vertices_in_clipped_quad)++;
-}
-
-gfx::Rect MathUtil::MapEnclosingClippedRect(const gfx::Transform& transform,
-                                            const gfx::Rect& src_rect) {
-  if (transform.IsIdentityOrIntegerTranslation()) {
-    gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)),
-                         static_cast<int>(transform.matrix().getFloat(1, 3)));
-    return src_rect + offset;
-  }
-  return gfx::ToEnclosingRect(MapClippedRect(transform, gfx::RectF(src_rect)));
-}
-
-gfx::RectF MathUtil::MapClippedRect(const gfx::Transform& transform,
-                                    const gfx::RectF& src_rect) {
-  if (transform.IsIdentityOrTranslation()) {
-    gfx::Vector2dF offset(transform.matrix().getFloat(0, 3),
-                          transform.matrix().getFloat(1, 3));
-    return src_rect + offset;
-  }
-
-  // Apply the transform, but retain the result in homogeneous coordinates.
-
-  SkMScalar quad[4 * 2];  // input: 4 x 2D points
-  quad[0] = src_rect.x();
-  quad[1] = src_rect.y();
-  quad[2] = src_rect.right();
-  quad[3] = src_rect.y();
-  quad[4] = src_rect.right();
-  quad[5] = src_rect.bottom();
-  quad[6] = src_rect.x();
-  quad[7] = src_rect.bottom();
-
-  SkMScalar result[4 * 4];  // output: 4 x 4D homogeneous points
-  transform.matrix().map2(quad, 4, result);
-
-  HomogeneousCoordinate hc0(result[0], result[1], result[2], result[3]);
-  HomogeneousCoordinate hc1(result[4], result[5], result[6], result[7]);
-  HomogeneousCoordinate hc2(result[8], result[9], result[10], result[11]);
-  HomogeneousCoordinate hc3(result[12], result[13], result[14], result[15]);
-  return ComputeEnclosingClippedRect(hc0, hc1, hc2, hc3);
-}
-
-gfx::Rect MathUtil::ProjectEnclosingClippedRect(const gfx::Transform& transform,
-                                                const gfx::Rect& src_rect) {
-  if (transform.IsIdentityOrIntegerTranslation()) {
-    gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)),
-                         static_cast<int>(transform.matrix().getFloat(1, 3)));
-    return src_rect + offset;
-  }
-  return gfx::ToEnclosingRect(
-      ProjectClippedRect(transform, gfx::RectF(src_rect)));
-}
-
-gfx::RectF MathUtil::ProjectClippedRect(const gfx::Transform& transform,
-                                        const gfx::RectF& src_rect) {
-  if (transform.IsIdentityOrTranslation()) {
-    gfx::Vector2dF offset(transform.matrix().getFloat(0, 3),
-                          transform.matrix().getFloat(1, 3));
-    return src_rect + offset;
-  }
-
-  // Perform the projection, but retain the result in homogeneous coordinates.
-  gfx::QuadF q = gfx::QuadF(src_rect);
-  HomogeneousCoordinate h1 = ProjectHomogeneousPoint(transform, q.p1());
-  HomogeneousCoordinate h2 = ProjectHomogeneousPoint(transform, q.p2());
-  HomogeneousCoordinate h3 = ProjectHomogeneousPoint(transform, q.p3());
-  HomogeneousCoordinate h4 = ProjectHomogeneousPoint(transform, q.p4());
-
-  return ComputeEnclosingClippedRect(h1, h2, h3, h4);
-}
-
-gfx::Rect MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(
-    const gfx::Transform& transform,
-    const gfx::Rect& rect) {
-  DCHECK(transform.Preserves2dAxisAlignment());
-
-  if (transform.IsIdentityOrIntegerTranslation()) {
-    gfx::Vector2d offset(static_cast<int>(transform.matrix().getFloat(0, 3)),
-                         static_cast<int>(transform.matrix().getFloat(1, 3)));
-    return rect + offset;
-  }
-  if (transform.IsIdentityOrTranslation()) {
-    gfx::Vector2dF offset(transform.matrix().getFloat(0, 3),
-                          transform.matrix().getFloat(1, 3));
-    return gfx::ToEnclosedRect(rect + offset);
-  }
-
-  SkMScalar quad[2 * 2];  // input: 2 x 2D points
-  quad[0] = rect.x();
-  quad[1] = rect.y();
-  quad[2] = rect.right();
-  quad[3] = rect.bottom();
-
-  SkMScalar result[4 * 2];  // output: 2 x 4D homogeneous points
-  transform.matrix().map2(quad, 2, result);
-
-  HomogeneousCoordinate hc0(result[0], result[1], result[2], result[3]);
-  HomogeneousCoordinate hc1(result[4], result[5], result[6], result[7]);
-  DCHECK(!hc0.ShouldBeClipped());
-  DCHECK(!hc1.ShouldBeClipped());
-
-  gfx::PointF top_left(hc0.CartesianPoint2d());
-  gfx::PointF bottom_right(hc1.CartesianPoint2d());
-  return gfx::ToEnclosedRect(gfx::BoundingRect(top_left, bottom_right));
-}
-
-void MathUtil::MapClippedQuad(const gfx::Transform& transform,
-                              const gfx::QuadF& src_quad,
-                              gfx::PointF clipped_quad[8],
-                              int* num_vertices_in_clipped_quad) {
-  HomogeneousCoordinate h1 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p1()));
-  HomogeneousCoordinate h2 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p2()));
-  HomogeneousCoordinate h3 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p3()));
-  HomogeneousCoordinate h4 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p4()));
-
-  // The order of adding the vertices to the array is chosen so that
-  // clockwise / counter-clockwise orientation is retained.
-
-  *num_vertices_in_clipped_quad = 0;
-
-  if (!h1.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        h1.CartesianPoint2d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h1.ShouldBeClipped() ^ h2.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        ComputeClippedPointForEdge(h1, h2).CartesianPoint2d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h2.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        h2.CartesianPoint2d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h2.ShouldBeClipped() ^ h3.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        ComputeClippedPointForEdge(h2, h3).CartesianPoint2d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h3.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        h3.CartesianPoint2d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h3.ShouldBeClipped() ^ h4.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        ComputeClippedPointForEdge(h3, h4).CartesianPoint2d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h4.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        h4.CartesianPoint2d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped()) {
-    AddVertexToClippedQuad(
-        ComputeClippedPointForEdge(h4, h1).CartesianPoint2d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  DCHECK_LE(*num_vertices_in_clipped_quad, 8);
-}
-
-bool MathUtil::MapClippedQuad3d(const gfx::Transform& transform,
-                                const gfx::QuadF& src_quad,
-                                gfx::Point3F clipped_quad[8],
-                                int* num_vertices_in_clipped_quad) {
-  HomogeneousCoordinate h1 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p1()));
-  HomogeneousCoordinate h2 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p2()));
-  HomogeneousCoordinate h3 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p3()));
-  HomogeneousCoordinate h4 =
-      MapHomogeneousPoint(transform, gfx::Point3F(src_quad.p4()));
-
-  // The order of adding the vertices to the array is chosen so that
-  // clockwise / counter-clockwise orientation is retained.
-
-  *num_vertices_in_clipped_quad = 0;
-
-  if (!h1.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        h1.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h1.ShouldBeClipped() ^ h2.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        ComputeClippedPointForEdge(h1, h2).CartesianPoint3d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h2.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        h2.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h2.ShouldBeClipped() ^ h3.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        ComputeClippedPointForEdge(h2, h3).CartesianPoint3d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h3.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        h3.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h3.ShouldBeClipped() ^ h4.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        ComputeClippedPointForEdge(h3, h4).CartesianPoint3d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  if (!h4.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        h4.CartesianPoint3d(), clipped_quad, num_vertices_in_clipped_quad);
-  }
-
-  if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped()) {
-    AddVertexToClippedQuad3d(
-        ComputeClippedPointForEdge(h4, h1).CartesianPoint3d(),
-        clipped_quad,
-        num_vertices_in_clipped_quad);
-  }
-
-  DCHECK_LE(*num_vertices_in_clipped_quad, 8);
-  return (*num_vertices_in_clipped_quad >= 4);
-}
-
-gfx::RectF MathUtil::ComputeEnclosingRectOfVertices(
-    const gfx::PointF vertices[],
-    int num_vertices) {
-  if (num_vertices < 2)
-    return gfx::RectF();
-
-  float xmin = std::numeric_limits<float>::max();
-  float xmax = -std::numeric_limits<float>::max();
-  float ymin = std::numeric_limits<float>::max();
-  float ymax = -std::numeric_limits<float>::max();
-
-  for (int i = 0; i < num_vertices; ++i)
-    ExpandBoundsToIncludePoint(&xmin, &xmax, &ymin, &ymax, vertices[i]);
-
-  return gfx::RectF(gfx::PointF(xmin, ymin),
-                    gfx::SizeF(xmax - xmin, ymax - ymin));
-}
-
-gfx::RectF MathUtil::ComputeEnclosingClippedRect(
-    const HomogeneousCoordinate& h1,
-    const HomogeneousCoordinate& h2,
-    const HomogeneousCoordinate& h3,
-    const HomogeneousCoordinate& h4) {
-  // This function performs clipping as necessary and computes the enclosing 2d
-  // gfx::RectF of the vertices. Doing these two steps simultaneously allows us
-  // to avoid the overhead of storing an unknown number of clipped vertices.
-
-  // If no vertices on the quad are clipped, then we can simply return the
-  // enclosing rect directly.
-  bool something_clipped = h1.ShouldBeClipped() || h2.ShouldBeClipped() ||
-                           h3.ShouldBeClipped() || h4.ShouldBeClipped();
-  if (!something_clipped) {
-    gfx::QuadF mapped_quad = gfx::QuadF(h1.CartesianPoint2d(),
-                                        h2.CartesianPoint2d(),
-                                        h3.CartesianPoint2d(),
-                                        h4.CartesianPoint2d());
-    return mapped_quad.BoundingBox();
-  }
-
-  bool everything_clipped = h1.ShouldBeClipped() && h2.ShouldBeClipped() &&
-                            h3.ShouldBeClipped() && h4.ShouldBeClipped();
-  if (everything_clipped)
-    return gfx::RectF();
-
-  float xmin = std::numeric_limits<float>::max();
-  float xmax = -std::numeric_limits<float>::max();
-  float ymin = std::numeric_limits<float>::max();
-  float ymax = -std::numeric_limits<float>::max();
-
-  if (!h1.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin, &xmax, &ymin, &ymax,
-                               h1.CartesianPoint2d());
-
-  if (h1.ShouldBeClipped() ^ h2.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin,
-                               &xmax,
-                               &ymin,
-                               &ymax,
-                               ComputeClippedPointForEdge(h1, h2)
-                                   .CartesianPoint2d());
-
-  if (!h2.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin, &xmax, &ymin, &ymax,
-                               h2.CartesianPoint2d());
-
-  if (h2.ShouldBeClipped() ^ h3.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin,
-                               &xmax,
-                               &ymin,
-                               &ymax,
-                               ComputeClippedPointForEdge(h2, h3)
-                                   .CartesianPoint2d());
-
-  if (!h3.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin, &xmax, &ymin, &ymax,
-                               h3.CartesianPoint2d());
-
-  if (h3.ShouldBeClipped() ^ h4.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin,
-                               &xmax,
-                               &ymin,
-                               &ymax,
-                               ComputeClippedPointForEdge(h3, h4)
-                                   .CartesianPoint2d());
-
-  if (!h4.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin, &xmax, &ymin, &ymax,
-                               h4.CartesianPoint2d());
-
-  if (h4.ShouldBeClipped() ^ h1.ShouldBeClipped())
-    ExpandBoundsToIncludePoint(&xmin,
-                               &xmax,
-                               &ymin,
-                               &ymax,
-                               ComputeClippedPointForEdge(h4, h1)
-                                   .CartesianPoint2d());
-
-  return gfx::RectF(gfx::PointF(xmin, ymin),
-                    gfx::SizeF(xmax - xmin, ymax - ymin));
-}
-
-gfx::QuadF MathUtil::MapQuad(const gfx::Transform& transform,
-                             const gfx::QuadF& q,
-                             bool* clipped) {
-  if (transform.IsIdentityOrTranslation()) {
-    gfx::QuadF mapped_quad(q);
-    mapped_quad += gfx::Vector2dF(transform.matrix().getFloat(0, 3),
-                                  transform.matrix().getFloat(1, 3));
-    *clipped = false;
-    return mapped_quad;
-  }
-
-  HomogeneousCoordinate h1 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p1()));
-  HomogeneousCoordinate h2 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p2()));
-  HomogeneousCoordinate h3 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p3()));
-  HomogeneousCoordinate h4 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p4()));
-
-  *clipped = h1.ShouldBeClipped() || h2.ShouldBeClipped() ||
-            h3.ShouldBeClipped() || h4.ShouldBeClipped();
-
-  // Result will be invalid if clipped == true. But, compute it anyway just in
-  // case, to emulate existing behavior.
-  return gfx::QuadF(h1.CartesianPoint2d(),
-                    h2.CartesianPoint2d(),
-                    h3.CartesianPoint2d(),
-                    h4.CartesianPoint2d());
-}
-
-gfx::QuadF MathUtil::MapQuad3d(const gfx::Transform& transform,
-                               const gfx::QuadF& q,
-                               gfx::Point3F* p,
-                               bool* clipped) {
-  if (transform.IsIdentityOrTranslation()) {
-    gfx::QuadF mapped_quad(q);
-    mapped_quad += gfx::Vector2dF(transform.matrix().getFloat(0, 3),
-                                  transform.matrix().getFloat(1, 3));
-    *clipped = false;
-    p[0] = gfx::Point3F(mapped_quad.p1().x(), mapped_quad.p1().y(), 0.0f);
-    p[1] = gfx::Point3F(mapped_quad.p2().x(), mapped_quad.p2().y(), 0.0f);
-    p[2] = gfx::Point3F(mapped_quad.p3().x(), mapped_quad.p3().y(), 0.0f);
-    p[3] = gfx::Point3F(mapped_quad.p4().x(), mapped_quad.p4().y(), 0.0f);
-    return mapped_quad;
-  }
-
-  HomogeneousCoordinate h1 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p1()));
-  HomogeneousCoordinate h2 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p2()));
-  HomogeneousCoordinate h3 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p3()));
-  HomogeneousCoordinate h4 =
-      MapHomogeneousPoint(transform, gfx::Point3F(q.p4()));
-
-  *clipped = h1.ShouldBeClipped() || h2.ShouldBeClipped() ||
-             h3.ShouldBeClipped() || h4.ShouldBeClipped();
-
-  // Result will be invalid if clipped == true. But, compute it anyway just in
-  // case, to emulate existing behavior.
-  p[0] = h1.CartesianPoint3d();
-  p[1] = h2.CartesianPoint3d();
-  p[2] = h3.CartesianPoint3d();
-  p[3] = h4.CartesianPoint3d();
-
-  return gfx::QuadF(h1.CartesianPoint2d(),
-                    h2.CartesianPoint2d(),
-                    h3.CartesianPoint2d(),
-                    h4.CartesianPoint2d());
-}
-
-gfx::PointF MathUtil::MapPoint(const gfx::Transform& transform,
-                               const gfx::PointF& p,
-                               bool* clipped) {
-  HomogeneousCoordinate h = MapHomogeneousPoint(transform, gfx::Point3F(p));
-
-  if (h.w() > 0) {
-    *clipped = false;
-    return h.CartesianPoint2d();
-  }
-
-  // The cartesian coordinates will be invalid after dividing by w.
-  *clipped = true;
-
-  // Avoid dividing by w if w == 0.
-  if (!h.w())
-    return gfx::PointF();
-
-  // This return value will be invalid because clipped == true, but (1) users of
-  // this code should be ignoring the return value when clipped == true anyway,
-  // and (2) this behavior is more consistent with existing behavior of WebKit
-  // transforms if the user really does not ignore the return value.
-  return h.CartesianPoint2d();
-}
-
-gfx::Point3F MathUtil::MapPoint(const gfx::Transform& transform,
-                                const gfx::Point3F& p,
-                                bool* clipped) {
-  HomogeneousCoordinate h = MapHomogeneousPoint(transform, p);
-
-  if (h.w() > 0) {
-    *clipped = false;
-    return h.CartesianPoint3d();
-  }
-
-  // The cartesian coordinates will be invalid after dividing by w.
-  *clipped = true;
-
-  // Avoid dividing by w if w == 0.
-  if (!h.w())
-    return gfx::Point3F();
-
-  // This return value will be invalid because clipped == true, but (1) users of
-  // this code should be ignoring the return value when clipped == true anyway,
-  // and (2) this behavior is more consistent with existing behavior of WebKit
-  // transforms if the user really does not ignore the return value.
-  return h.CartesianPoint3d();
-}
-
-gfx::QuadF MathUtil::ProjectQuad(const gfx::Transform& transform,
-                                 const gfx::QuadF& q,
-                                 bool* clipped) {
-  gfx::QuadF projected_quad;
-  bool clipped_point;
-  projected_quad.set_p1(ProjectPoint(transform, q.p1(), &clipped_point));
-  *clipped = clipped_point;
-  projected_quad.set_p2(ProjectPoint(transform, q.p2(), &clipped_point));
-  *clipped |= clipped_point;
-  projected_quad.set_p3(ProjectPoint(transform, q.p3(), &clipped_point));
-  *clipped |= clipped_point;
-  projected_quad.set_p4(ProjectPoint(transform, q.p4(), &clipped_point));
-  *clipped |= clipped_point;
-
-  return projected_quad;
-}
-
-gfx::PointF MathUtil::ProjectPoint(const gfx::Transform& transform,
-                                   const gfx::PointF& p,
-                                   bool* clipped) {
-  HomogeneousCoordinate h = ProjectHomogeneousPoint(transform, p, clipped);
-  // Avoid dividing by w if w == 0.
-  if (!h.w())
-    return gfx::PointF();
-
-  // This return value will be invalid if clipped == true, but (1) users of
-  // this code should be ignoring the return value when clipped == true anyway,
-  // and (2) this behavior is more consistent with existing behavior of WebKit
-  // transforms if the user really does not ignore the return value.
-  return h.CartesianPoint2d();
-}
-
-gfx::Point3F MathUtil::ProjectPoint3D(const gfx::Transform& transform,
-                                      const gfx::PointF& p,
-                                      bool* clipped) {
-  HomogeneousCoordinate h = ProjectHomogeneousPoint(transform, p, clipped);
-  if (!h.w())
-    return gfx::Point3F();
-  return h.CartesianPoint3d();
-}
-
-gfx::RectF MathUtil::ScaleRectProportional(const gfx::RectF& input_outer_rect,
-                                           const gfx::RectF& scale_outer_rect,
-                                           const gfx::RectF& scale_inner_rect) {
-  gfx::RectF output_inner_rect = input_outer_rect;
-  float scale_rect_to_input_scale_x =
-      scale_outer_rect.width() / input_outer_rect.width();
-  float scale_rect_to_input_scale_y =
-      scale_outer_rect.height() / input_outer_rect.height();
-
-  gfx::Vector2dF top_left_diff =
-      scale_inner_rect.origin() - scale_outer_rect.origin();
-  gfx::Vector2dF bottom_right_diff =
-      scale_inner_rect.bottom_right() - scale_outer_rect.bottom_right();
-  output_inner_rect.Inset(top_left_diff.x() / scale_rect_to_input_scale_x,
-                          top_left_diff.y() / scale_rect_to_input_scale_y,
-                          -bottom_right_diff.x() / scale_rect_to_input_scale_x,
-                          -bottom_right_diff.y() / scale_rect_to_input_scale_y);
-  return output_inner_rect;
-}
-
-static inline bool NearlyZero(double value) {
-  return std::abs(value) < std::numeric_limits<double>::epsilon();
-}
-
-static inline float ScaleOnAxis(double a, double b, double c) {
-  if (NearlyZero(b) && NearlyZero(c))
-    return std::abs(a);
-  if (NearlyZero(a) && NearlyZero(c))
-    return std::abs(b);
-  if (NearlyZero(a) && NearlyZero(b))
-    return std::abs(c);
-
-  // Do the sqrt as a double to not lose precision.
-  return static_cast<float>(std::sqrt(a * a + b * b + c * c));
-}
-
-gfx::Vector2dF MathUtil::ComputeTransform2dScaleComponents(
-    const gfx::Transform& transform,
-    float fallback_value) {
-  if (transform.HasPerspective())
-    return gfx::Vector2dF(fallback_value, fallback_value);
-  float x_scale = ScaleOnAxis(transform.matrix().getDouble(0, 0),
-                              transform.matrix().getDouble(1, 0),
-                              transform.matrix().getDouble(2, 0));
-  float y_scale = ScaleOnAxis(transform.matrix().getDouble(0, 1),
-                              transform.matrix().getDouble(1, 1),
-                              transform.matrix().getDouble(2, 1));
-  return gfx::Vector2dF(x_scale, y_scale);
-}
-
-float MathUtil::SmallestAngleBetweenVectors(const gfx::Vector2dF& v1,
-                                            const gfx::Vector2dF& v2) {
-  double dot_product = gfx::DotProduct(v1, v2) / v1.Length() / v2.Length();
-  // Clamp to compensate for rounding errors.
-  dot_product = std::max(-1.0, std::min(1.0, dot_product));
-  return static_cast<float>(Rad2Deg(std::acos(dot_product)));
-}
-
-gfx::Vector2dF MathUtil::ProjectVector(const gfx::Vector2dF& source,
-                                       const gfx::Vector2dF& destination) {
-  float projected_length =
-      gfx::DotProduct(source, destination) / destination.LengthSquared();
-  return gfx::Vector2dF(projected_length * destination.x(),
-                        projected_length * destination.y());
-}
-
-scoped_ptr<base::Value> MathUtil::AsValue(const gfx::Size& s) {
-  scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue());
-  res->SetDouble("width", s.width());
-  res->SetDouble("height", s.height());
-  return res.Pass();
-}
-
-scoped_ptr<base::Value> MathUtil::AsValue(const gfx::Rect& r) {
-  scoped_ptr<base::ListValue> res(new base::ListValue());
-  res->AppendInteger(r.x());
-  res->AppendInteger(r.y());
-  res->AppendInteger(r.width());
-  res->AppendInteger(r.height());
-  return res.Pass();
-}
-
-bool MathUtil::FromValue(const base::Value* raw_value, gfx::Rect* out_rect) {
-  const base::ListValue* value = nullptr;
-  if (!raw_value->GetAsList(&value))
-    return false;
-
-  if (value->GetSize() != 4)
-    return false;
-
-  int x, y, w, h;
-  bool ok = true;
-  ok &= value->GetInteger(0, &x);
-  ok &= value->GetInteger(1, &y);
-  ok &= value->GetInteger(2, &w);
-  ok &= value->GetInteger(3, &h);
-  if (!ok)
-    return false;
-
-  *out_rect = gfx::Rect(x, y, w, h);
-  return true;
-}
-
-scoped_ptr<base::Value> MathUtil::AsValue(const gfx::PointF& pt) {
-  scoped_ptr<base::ListValue> res(new base::ListValue());
-  res->AppendDouble(pt.x());
-  res->AppendDouble(pt.y());
-  return res.Pass();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Size& s,
-                                base::trace_event::TracedValue* res) {
-  res->BeginDictionary(name);
-  res->SetDouble("width", s.width());
-  res->SetDouble("height", s.height());
-  res->EndDictionary();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::SizeF& s,
-                                base::trace_event::TracedValue* res) {
-  res->BeginDictionary(name);
-  res->SetDouble("width", s.width());
-  res->SetDouble("height", s.height());
-  res->EndDictionary();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Rect& r,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendInteger(r.x());
-  res->AppendInteger(r.y());
-  res->AppendInteger(r.width());
-  res->AppendInteger(r.height());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::PointF& pt,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(pt.x());
-  res->AppendDouble(pt.y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Point3F& pt,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(pt.x());
-  res->AppendDouble(pt.y());
-  res->AppendDouble(pt.z());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Vector2d& v,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendInteger(v.x());
-  res->AppendInteger(v.y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Vector2dF& v,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(v.x());
-  res->AppendDouble(v.y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::ScrollOffset& v,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(v.x());
-  res->AppendDouble(v.y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::QuadF& q,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(q.p1().x());
-  res->AppendDouble(q.p1().y());
-  res->AppendDouble(q.p2().x());
-  res->AppendDouble(q.p2().y());
-  res->AppendDouble(q.p3().x());
-  res->AppendDouble(q.p3().y());
-  res->AppendDouble(q.p4().x());
-  res->AppendDouble(q.p4().y());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::RectF& rect,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendDouble(rect.x());
-  res->AppendDouble(rect.y());
-  res->AppendDouble(rect.width());
-  res->AppendDouble(rect.height());
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::Transform& transform,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  const SkMatrix44& m = transform.matrix();
-  for (int row = 0; row < 4; ++row) {
-    for (int col = 0; col < 4; ++col)
-      res->AppendDouble(m.getDouble(row, col));
-  }
-  res->EndArray();
-}
-
-void MathUtil::AddToTracedValue(const char* name,
-                                const gfx::BoxF& box,
-                                base::trace_event::TracedValue* res) {
-  res->BeginArray(name);
-  res->AppendInteger(box.x());
-  res->AppendInteger(box.y());
-  res->AppendInteger(box.z());
-  res->AppendInteger(box.width());
-  res->AppendInteger(box.height());
-  res->AppendInteger(box.depth());
-  res->EndArray();
-}
-
-double MathUtil::AsDoubleSafely(double value) {
-  return std::min(value, std::numeric_limits<double>::max());
-}
-
-float MathUtil::AsFloatSafely(float value) {
-  return std::min(value, std::numeric_limits<float>::max());
-}
-
-}  // namespace cc
diff --git a/cc/base/math_util.h b/cc/base/math_util.h
deleted file mode 100644
index 64a819e..0000000
--- a/cc/base/math_util.h
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_BASE_MATH_UTIL_H_
-#define CC_BASE_MATH_UTIL_H_
-
-#include <algorithm>
-#include <cmath>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "ui/gfx/geometry/box_f.h"
-#include "ui/gfx/geometry/point3_f.h"
-#include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/scroll_offset.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/transform.h"
-
-namespace base {
-class Value;
-namespace trace_event {
-class TracedValue;
-}
-}  // namespace base
-
-namespace gfx {
-class QuadF;
-class Rect;
-class RectF;
-class Transform;
-class Vector2dF;
-class Vector2d;
-}
-
-namespace cc {
-
-struct HomogeneousCoordinate {
-  HomogeneousCoordinate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar w) {
-    vec[0] = x;
-    vec[1] = y;
-    vec[2] = z;
-    vec[3] = w;
-  }
-
-  bool ShouldBeClipped() const { return w() <= 0.0; }
-
-  gfx::PointF CartesianPoint2d() const {
-    if (w() == SK_MScalar1)
-      return gfx::PointF(x(), y());
-
-    // For now, because this code is used privately only by MathUtil, it should
-    // never be called when w == 0, and we do not yet need to handle that case.
-    DCHECK(w());
-    SkMScalar inv_w = SK_MScalar1 / w();
-    return gfx::PointF(x() * inv_w, y() * inv_w);
-  }
-
-  gfx::Point3F CartesianPoint3d() const {
-    if (w() == SK_MScalar1)
-      return gfx::Point3F(x(), y(), z());
-
-    // For now, because this code is used privately only by MathUtil, it should
-    // never be called when w == 0, and we do not yet need to handle that case.
-    DCHECK(w());
-    SkMScalar inv_w = SK_MScalar1 / w();
-    return gfx::Point3F(x() * inv_w, y() * inv_w, z() * inv_w);
-  }
-
-  SkMScalar x() const { return vec[0]; }
-  SkMScalar y() const { return vec[1]; }
-  SkMScalar z() const { return vec[2]; }
-  SkMScalar w() const { return vec[3]; }
-
-  SkMScalar vec[4];
-};
-
-class MathUtil {
- public:
-  static const double kPiDouble;
-  static const float kPiFloat;
-
-  static double Deg2Rad(double deg) { return deg * kPiDouble / 180.0; }
-  static double Rad2Deg(double rad) { return rad * 180.0 / kPiDouble; }
-
-  static float Deg2Rad(float deg) { return deg * kPiFloat / 180.0f; }
-  static float Rad2Deg(float rad) { return rad * 180.0f / kPiFloat; }
-
-  static float Round(float f) {
-    return (f > 0.f) ? std::floor(f + 0.5f) : std::ceil(f - 0.5f);
-  }
-  static double Round(double d) {
-    return (d > 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
-  }
-
-  template <typename T> static T ClampToRange(T value, T min, T max) {
-    return std::min(std::max(value, min), max);
-  }
-
-  // Background: Existing transform code does not do the right thing in
-  // MapRect / MapQuad / ProjectQuad when there is a perspective projection that
-  // causes one of the transformed vertices to go to w < 0. In those cases, it
-  // is necessary to perform clipping in homogeneous coordinates, after applying
-  // the transform, before dividing-by-w to convert to cartesian coordinates.
-  //
-  // These functions return the axis-aligned rect that encloses the correctly
-  // clipped, transformed polygon.
-  static gfx::Rect MapEnclosingClippedRect(const gfx::Transform& transform,
-                                           const gfx::Rect& rect);
-  static gfx::RectF MapClippedRect(const gfx::Transform& transform,
-                                   const gfx::RectF& rect);
-  static gfx::Rect ProjectEnclosingClippedRect(const gfx::Transform& transform,
-                                               const gfx::Rect& rect);
-  static gfx::RectF ProjectClippedRect(const gfx::Transform& transform,
-                                       const gfx::RectF& rect);
-
-  // This function is only valid when the transform preserves 2d axis
-  // alignment and the resulting rect will not be clipped.
-  static gfx::Rect MapEnclosedRectWith2dAxisAlignedTransform(
-      const gfx::Transform& transform,
-      const gfx::Rect& rect);
-
-  // Returns an array of vertices that represent the clipped polygon. After
-  // returning, indexes from 0 to num_vertices_in_clipped_quad are valid in the
-  // clipped_quad array. Note that num_vertices_in_clipped_quad may be zero,
-  // which means the entire quad was clipped, and none of the vertices in the
-  // array are valid.
-  static void MapClippedQuad(const gfx::Transform& transform,
-                             const gfx::QuadF& src_quad,
-                             gfx::PointF clipped_quad[8],
-                             int* num_vertices_in_clipped_quad);
-  static bool MapClippedQuad3d(const gfx::Transform& transform,
-                               const gfx::QuadF& src_quad,
-                               gfx::Point3F clipped_quad[8],
-                               int* num_vertices_in_clipped_quad);
-
-  static gfx::RectF ComputeEnclosingRectOfVertices(const gfx::PointF vertices[],
-                                                   int num_vertices);
-  static gfx::RectF ComputeEnclosingClippedRect(
-      const HomogeneousCoordinate& h1,
-      const HomogeneousCoordinate& h2,
-      const HomogeneousCoordinate& h3,
-      const HomogeneousCoordinate& h4);
-
-  // NOTE: These functions do not do correct clipping against w = 0 plane, but
-  // they correctly detect the clipped condition via the boolean clipped.
-  static gfx::QuadF MapQuad(const gfx::Transform& transform,
-                            const gfx::QuadF& quad,
-                            bool* clipped);
-  static gfx::QuadF MapQuad3d(const gfx::Transform& transform,
-                              const gfx::QuadF& q,
-                              gfx::Point3F* p,
-                              bool* clipped);
-  static gfx::PointF MapPoint(const gfx::Transform& transform,
-                              const gfx::PointF& point,
-                              bool* clipped);
-  static gfx::Point3F MapPoint(const gfx::Transform&,
-                               const gfx::Point3F&,
-                               bool* clipped);
-  static gfx::QuadF ProjectQuad(const gfx::Transform& transform,
-                                const gfx::QuadF& quad,
-                                bool* clipped);
-  static gfx::PointF ProjectPoint(const gfx::Transform& transform,
-                                  const gfx::PointF& point,
-                                  bool* clipped);
-  // Identical to the above function, but coerces the homogeneous coordinate to
-  // a 3d rather than a 2d point.
-  static gfx::Point3F ProjectPoint3D(const gfx::Transform& transform,
-                                     const gfx::PointF& point,
-                                     bool* clipped);
-
-  static gfx::Vector2dF ComputeTransform2dScaleComponents(const gfx::Transform&,
-                                                          float fallbackValue);
-
-  // Makes a rect that has the same relationship to input_outer_rect as
-  // scale_inner_rect has to scale_outer_rect. scale_inner_rect should be
-  // contained within scale_outer_rect, and likewise the rectangle that is
-  // returned will be within input_outer_rect at a similar relative, scaled
-  // position.
-  static gfx::RectF ScaleRectProportional(const gfx::RectF& input_outer_rect,
-                                          const gfx::RectF& scale_outer_rect,
-                                          const gfx::RectF& scale_inner_rect);
-
-  // Returns the smallest angle between the given two vectors in degrees.
-  // Neither vector is assumed to be normalized.
-  static float SmallestAngleBetweenVectors(const gfx::Vector2dF& v1,
-                                           const gfx::Vector2dF& v2);
-
-  // Projects the |source| vector onto |destination|. Neither vector is assumed
-  // to be normalized.
-  static gfx::Vector2dF ProjectVector(const gfx::Vector2dF& source,
-                                      const gfx::Vector2dF& destination);
-
-  // Conversion to value.
-  static scoped_ptr<base::Value> AsValue(const gfx::Size& s);
-  static scoped_ptr<base::Value> AsValue(const gfx::Rect& r);
-  static bool FromValue(const base::Value*, gfx::Rect* out_rect);
-  static scoped_ptr<base::Value> AsValue(const gfx::PointF& q);
-
-  static void AddToTracedValue(const char* name,
-                               const gfx::Size& s,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::SizeF& s,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::Rect& r,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::PointF& q,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::Point3F&,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::Vector2d& v,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::Vector2dF& v,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::ScrollOffset& v,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::QuadF& q,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::RectF& rect,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::Transform& transform,
-                               base::trace_event::TracedValue* res);
-  static void AddToTracedValue(const char* name,
-                               const gfx::BoxF& box,
-                               base::trace_event::TracedValue* res);
-
-  // Returns a base::Value representation of the floating point value.
-  // If the value is inf, returns max double/float representation.
-  static double AsDoubleSafely(double value);
-  static float AsFloatSafely(float value);
-};
-
-}  // namespace cc
-
-#endif  // CC_BASE_MATH_UTIL_H_
diff --git a/cc/base/math_util_unittest.cc b/cc/base/math_util_unittest.cc
deleted file mode 100644
index 325870d..0000000
--- a/cc/base/math_util_unittest.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/base/math_util.h"
-
-#include <cmath>
-
-#include "cc/test/geometry_test_utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-TEST(MathUtilTest, ProjectionOfPerpendicularPlane) {
-  // In this case, the m33() element of the transform becomes zero, which could
-  // cause a divide-by-zero when projecting points/quads.
-
-  gfx::Transform transform;
-  transform.MakeIdentity();
-  transform.matrix().set(2, 2, 0);
-
-  gfx::RectF rect = gfx::RectF(0, 0, 1, 1);
-  gfx::RectF projected_rect = MathUtil::ProjectClippedRect(transform, rect);
-
-  EXPECT_EQ(0, projected_rect.x());
-  EXPECT_EQ(0, projected_rect.y());
-  EXPECT_TRUE(projected_rect.IsEmpty());
-}
-
-TEST(MathUtilTest, EnclosingClippedRectUsesCorrectInitialBounds) {
-  HomogeneousCoordinate h1(-100, -100, 0, 1);
-  HomogeneousCoordinate h2(-10, -10, 0, 1);
-  HomogeneousCoordinate h3(10, 10, 0, -1);
-  HomogeneousCoordinate h4(100, 100, 0, -1);
-
-  // The bounds of the enclosing clipped rect should be -100 to -10 for both x
-  // and y. However, if there is a bug where the initial xmin/xmax/ymin/ymax are
-  // initialized to numeric_limits<float>::min() (which is zero, not -flt_max)
-  // then the enclosing clipped rect will be computed incorrectly.
-  gfx::RectF result = MathUtil::ComputeEnclosingClippedRect(h1, h2, h3, h4);
-
-  // Due to floating point math in ComputeClippedPointForEdge this result
-  // is fairly imprecise.  0.15f was empirically determined.
-  EXPECT_RECT_NEAR(
-      gfx::RectF(gfx::PointF(-100, -100), gfx::SizeF(90, 90)), result, 0.15f);
-}
-
-TEST(MathUtilTest, EnclosingRectOfVerticesUsesCorrectInitialBounds) {
-  gfx::PointF vertices[3];
-  int num_vertices = 3;
-
-  vertices[0] = gfx::PointF(-10, -100);
-  vertices[1] = gfx::PointF(-100, -10);
-  vertices[2] = gfx::PointF(-30, -30);
-
-  // The bounds of the enclosing rect should be -100 to -10 for both x and y.
-  // However, if there is a bug where the initial xmin/xmax/ymin/ymax are
-  // initialized to numeric_limits<float>::min() (which is zero, not -flt_max)
-  // then the enclosing clipped rect will be computed incorrectly.
-  gfx::RectF result =
-      MathUtil::ComputeEnclosingRectOfVertices(vertices, num_vertices);
-
-  EXPECT_FLOAT_RECT_EQ(gfx::RectF(gfx::PointF(-100, -100), gfx::SizeF(90, 90)),
-                       result);
-}
-
-TEST(MathUtilTest, SmallestAngleBetweenVectors) {
-  gfx::Vector2dF x(1, 0);
-  gfx::Vector2dF y(0, 1);
-  gfx::Vector2dF test_vector(0.5, 0.5);
-
-  // Orthogonal vectors are at an angle of 90 degress.
-  EXPECT_EQ(90, MathUtil::SmallestAngleBetweenVectors(x, y));
-
-  // A vector makes a zero angle with itself.
-  EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(x, x));
-  EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(y, y));
-  EXPECT_EQ(0, MathUtil::SmallestAngleBetweenVectors(test_vector, test_vector));
-
-  // Parallel but reversed vectors are at 180 degrees.
-  EXPECT_FLOAT_EQ(180, MathUtil::SmallestAngleBetweenVectors(x, -x));
-  EXPECT_FLOAT_EQ(180, MathUtil::SmallestAngleBetweenVectors(y, -y));
-  EXPECT_FLOAT_EQ(
-      180, MathUtil::SmallestAngleBetweenVectors(test_vector, -test_vector));
-
-  // The test vector is at a known angle.
-  EXPECT_FLOAT_EQ(
-      45, std::floor(MathUtil::SmallestAngleBetweenVectors(test_vector, x)));
-  EXPECT_FLOAT_EQ(
-      45, std::floor(MathUtil::SmallestAngleBetweenVectors(test_vector, y)));
-}
-
-TEST(MathUtilTest, VectorProjection) {
-  gfx::Vector2dF x(1, 0);
-  gfx::Vector2dF y(0, 1);
-  gfx::Vector2dF test_vector(0.3f, 0.7f);
-
-  // Orthogonal vectors project to a zero vector.
-  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), MathUtil::ProjectVector(x, y));
-  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), MathUtil::ProjectVector(y, x));
-
-  // Projecting a vector onto the orthonormal basis gives the corresponding
-  // component of the vector.
-  EXPECT_VECTOR_EQ(gfx::Vector2dF(test_vector.x(), 0),
-                   MathUtil::ProjectVector(test_vector, x));
-  EXPECT_VECTOR_EQ(gfx::Vector2dF(0, test_vector.y()),
-                   MathUtil::ProjectVector(test_vector, y));
-
-  // Finally check than an arbitrary vector projected to another one gives a
-  // vector parallel to the second vector.
-  gfx::Vector2dF target_vector(0.5, 0.2f);
-  gfx::Vector2dF projected_vector =
-      MathUtil::ProjectVector(test_vector, target_vector);
-  EXPECT_EQ(projected_vector.x() / target_vector.x(),
-            projected_vector.y() / target_vector.y());
-}
-
-TEST(MathUtilTest, MapEnclosedRectWith2dAxisAlignedTransform) {
-  gfx::Rect input(1, 2, 3, 4);
-  gfx::Rect output;
-  gfx::Transform transform;
-
-  // Identity.
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(input, output);
-
-  // Integer translate.
-  transform.Translate(2.0, 3.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(3, 5, 3, 4), output);
-
-  // Non-integer translate.
-  transform.Translate(0.5, 0.5);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(4, 6, 2, 3), output);
-
-  // Scale.
-  transform = gfx::Transform();
-  transform.Scale(2.0, 3.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(2, 6, 6, 12), output);
-
-  // Rotate Z.
-  transform = gfx::Transform();
-  transform.Translate(1.0, 2.0);
-  transform.RotateAboutZAxis(90.0);
-  transform.Translate(-1.0, -2.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(-3, 2, 4, 3), output);
-
-  // Rotate X.
-  transform = gfx::Transform();
-  transform.RotateAboutXAxis(90.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_TRUE(output.IsEmpty());
-
-  transform = gfx::Transform();
-  transform.RotateAboutXAxis(180.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(1, -6, 3, 4), output);
-
-  // Rotate Y.
-  transform = gfx::Transform();
-  transform.RotateAboutYAxis(90.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_TRUE(output.IsEmpty());
-
-  transform = gfx::Transform();
-  transform.RotateAboutYAxis(180.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(-4, 2, 3, 4), output);
-
-  // Translate Z.
-  transform = gfx::Transform();
-  transform.ApplyPerspectiveDepth(10.0);
-  transform.Translate3d(0.0, 0.0, 5.0);
-  output =
-      MathUtil::MapEnclosedRectWith2dAxisAlignedTransform(transform, input);
-  EXPECT_EQ(gfx::Rect(2, 4, 6, 8), output);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/base/scoped_ptr_deque.h b/cc/base/scoped_ptr_deque.h
deleted file mode 100644
index cb4adfc..0000000
--- a/cc/base/scoped_ptr_deque.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_BASE_SCOPED_PTR_DEQUE_H_
-#define CC_BASE_SCOPED_PTR_DEQUE_H_
-
-#include <algorithm>
-#include <deque>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
-
-namespace cc {
-
-// This type acts like a deque<scoped_ptr> based on top of std::deque. The
-// ScopedPtrDeque has ownership of all elements in the deque.
-template <typename T>
-class ScopedPtrDeque {
- public:
-  typedef typename std::deque<T*>::const_iterator const_iterator;
-  typedef typename std::deque<T*>::reverse_iterator reverse_iterator;
-  typedef typename std::deque<T*>::const_reverse_iterator
-      const_reverse_iterator;
-
-#if defined(OS_ANDROID)
-  // On Android the iterator is not a class, so we can't block assignment.
-  typedef typename std::deque<T*>::iterator iterator;
-#else
-  // Ban setting values on the iterator directly. New pointers must be passed
-  // to methods on the ScopedPtrDeque class to appear in the deque.
-  class iterator : public std::deque<T*>::iterator {
-   public:
-    explicit iterator(const typename std::deque<T*>::iterator& other)
-        : std::deque<T*>::iterator(other) {}
-    T* const& operator*() { return std::deque<T*>::iterator::operator*(); }
-  };
-#endif
-
-  ScopedPtrDeque() {}
-
-  ~ScopedPtrDeque() { clear(); }
-
-  size_t size() const {
-    return data_.size();
-  }
-
-  T* at(size_t index) const {
-    DCHECK(index < size());
-    return data_[index];
-  }
-
-  T* operator[](size_t index) const {
-    return at(index);
-  }
-
-  T* front() const {
-    DCHECK(!empty());
-    return at(0);
-  }
-
-  T* back() const {
-    DCHECK(!empty());
-    return at(size() - 1);
-  }
-
-  bool empty() const {
-    return data_.empty();
-  }
-
-  scoped_ptr<T> take_front() {
-    scoped_ptr<T> ret(front());
-    data_.pop_front();
-    return ret.Pass();
-  }
-
-  scoped_ptr<T> take_back() {
-    scoped_ptr<T> ret(back());
-    data_.pop_back();
-    return ret.Pass();
-  }
-
-  void clear() {
-    STLDeleteElements(&data_);
-  }
-
-  void push_front(scoped_ptr<T> item) {
-    data_.push_front(item.release());
-  }
-
-  void push_back(scoped_ptr<T> item) {
-    data_.push_back(item.release());
-  }
-
-  void insert(iterator position, scoped_ptr<T> item) {
-    DCHECK(position <= end());
-    data_.insert(position, item.release());
-  }
-
-  scoped_ptr<T> take(iterator position) {
-    DCHECK(position < end());
-    scoped_ptr<T> ret(*position);
-    data_.erase(position);
-    return ret.Pass();
-  }
-
-  void swap(iterator a, iterator b) {
-    DCHECK(a < end());
-    DCHECK(b < end());
-    if (a == end() || b == end() || a == b)
-      return;
-    typename std::deque<T*>::iterator writable_a = a;
-    typename std::deque<T*>::iterator writable_b = b;
-    std::swap(*writable_a, *writable_b);
-  }
-
-  iterator begin() { return static_cast<iterator>(data_.begin()); }
-  const_iterator begin() const { return data_.begin(); }
-  iterator end() { return static_cast<iterator>(data_.end()); }
-  const_iterator end() const { return data_.end(); }
-
-  reverse_iterator rbegin() { return data_.rbegin(); }
-  const_reverse_iterator rbegin() const { return data_.rbegin(); }
-  reverse_iterator rend() { return data_.rend(); }
-  const_reverse_iterator rend() const { return data_.rend(); }
-
- private:
-  std::deque<T*> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedPtrDeque);
-};
-
-}  // namespace cc
-
-#endif  // CC_BASE_SCOPED_PTR_DEQUE_H_
diff --git a/cc/base/scoped_ptr_vector.h b/cc/base/scoped_ptr_vector.h
deleted file mode 100644
index b552d73..0000000
--- a/cc/base/scoped_ptr_vector.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_BASE_SCOPED_PTR_VECTOR_H_
-#define CC_BASE_SCOPED_PTR_VECTOR_H_
-
-#include <algorithm>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/stl_util.h"
-
-namespace cc {
-
-// This type acts like a vector<scoped_ptr> based on top of std::vector. The
-// ScopedPtrVector has ownership of all elements in the vector.
-template <typename T>
-class ScopedPtrVector {
- public:
-  typedef typename std::vector<T*>::const_iterator const_iterator;
-  typedef typename std::vector<T*>::reverse_iterator reverse_iterator;
-  typedef typename std::vector<T*>::const_reverse_iterator
-      const_reverse_iterator;
-
-#if defined(OS_ANDROID)
-  // On Android the iterator is not a class, so we can't block assignment.
-  typedef typename std::vector<T*>::iterator iterator;
-#else
-  // Ban setting values on the iterator directly. New pointers must be passed
-  // to methods on the ScopedPtrVector class to appear in the vector.
-  class iterator : public std::vector<T*>::iterator {
-   public:
-    iterator(const typename std::vector<T*>::iterator& other) // NOLINT
-        : std::vector<T*>::iterator(other) {}
-    T* const& operator*() { return std::vector<T*>::iterator::operator*(); }
-  };
-#endif
-
-  ScopedPtrVector() {}
-
-  ~ScopedPtrVector() { clear(); }
-
-  size_t size() const {
-    return data_.size();
-  }
-
-  T* at(size_t index) const {
-    DCHECK(index < size());
-    return data_[index];
-  }
-
-  T* operator[](size_t index) const {
-    return at(index);
-  }
-
-  T* front() const {
-    DCHECK(!empty());
-    return at(0);
-  }
-
-  T* back() const {
-    DCHECK(!empty());
-    return at(size() - 1);
-  }
-
-  bool empty() const {
-    return data_.empty();
-  }
-
-  scoped_ptr<T> take(iterator position) {
-    if (position == end())
-      return nullptr;
-    DCHECK(position < end());
-
-    typename std::vector<T*>::iterator writable_position = position;
-    scoped_ptr<T> ret(*writable_position);
-    *writable_position = nullptr;
-    return ret.Pass();
-  }
-
-  scoped_ptr<T> take_back() {
-    DCHECK(!empty());
-    if (empty())
-      return nullptr;
-    return take(end() - 1);
-  }
-
-  void erase(iterator position) {
-    if (position == end())
-      return;
-    typename std::vector<T*>::iterator writable_position = position;
-    delete *writable_position;
-    data_.erase(position);
-  }
-
-  void erase(iterator first, iterator last) {
-    DCHECK(first <= last);
-    for (iterator it = first; it != last; ++it) {
-      DCHECK(it < end());
-
-      typename std::vector<T*>::iterator writable_it = it;
-      delete *writable_it;
-    }
-    data_.erase(first, last);
-  }
-
-  void reserve(size_t size) {
-    data_.reserve(size);
-  }
-
-  void clear() {
-    STLDeleteElements(&data_);
-  }
-
-  void push_back(scoped_ptr<T> item) {
-    data_.push_back(item.release());
-  }
-
-  void pop_back() {
-    delete data_.back();
-    data_.pop_back();
-  }
-
-  void insert(iterator position, scoped_ptr<T> item) {
-    DCHECK(position <= end());
-    data_.insert(position, item.release());
-  }
-
-  void insert_and_take(iterator position, ScopedPtrVector<T>* other) {
-    std::vector<T*> tmp_data;
-    for (ScopedPtrVector<T>::iterator it = other->begin(); it != other->end();
-         ++it) {
-      tmp_data.push_back(other->take(it).release());
-    }
-    data_.insert(position, tmp_data.begin(), tmp_data.end());
-  }
-
-  template <typename Predicate>
-  iterator partition(Predicate predicate) {
-    typename std::vector<T*>::iterator first = begin();
-    typename std::vector<T*>::iterator last = end();
-    return static_cast<iterator>(std::partition(first, last, predicate));
-  }
-
-  void swap(ScopedPtrVector<T>& other) {
-    data_.swap(other.data_);
-  }
-
-  void swap(iterator a, iterator b) {
-    DCHECK(a < end());
-    DCHECK(b < end());
-    if (a == end() || b == end() || a == b)
-      return;
-    typename std::vector<T*>::iterator writable_a = a;
-    typename std::vector<T*>::iterator writable_b = b;
-    std::swap(*writable_a, *writable_b);
-  }
-
-  // This acts like std::remove_if but with one key difference. The values to be
-  // removed to will each appear exactly once at or after the returned iterator,
-  // so that erase(foo.remove_if(P), foo.end()) will not leak or double-free the
-  // pointers in the vector.
-  template <typename Predicate>
-  iterator remove_if(Predicate predicate) {
-    typename std::vector<T*>::iterator it =
-        std::find_if(data_.begin(), data_.end(), predicate);
-    typename std::vector<T*>::iterator end = data_.end();
-    if (it == end)
-      return it;
-    typename std::vector<T*>::iterator result = it;
-    ++it;
-    for (; it != end; ++it) {
-      if (!static_cast<bool>(predicate(*it))) {
-        // Swap here instead of just assign to |result| so that all the
-        // pointers are preserved to be deleted afterward.
-        std::swap(*result, *it);
-        ++result;
-      }
-    }
-    return result;
-  }
-
-  template<class Compare>
-  inline void sort(Compare comp) {
-    std::sort(data_.begin(), data_.end(), comp);
-  }
-
-  template <class Compare>
-  inline void make_heap(Compare comp) {
-    std::make_heap(data_.begin(), data_.end(), comp);
-  }
-
-  template <class Compare>
-  inline void push_heap(Compare comp) {
-    std::push_heap(data_.begin(), data_.end(), comp);
-  }
-
-  template <class Compare>
-  inline void pop_heap(Compare comp) {
-    std::pop_heap(data_.begin(), data_.end(), comp);
-  }
-
-  iterator begin() { return static_cast<iterator>(data_.begin()); }
-  const_iterator begin() const { return data_.begin(); }
-  iterator end() { return static_cast<iterator>(data_.end()); }
-  const_iterator end() const { return data_.end(); }
-
-  reverse_iterator rbegin() { return data_.rbegin(); }
-  const_reverse_iterator rbegin() const { return data_.rbegin(); }
-  reverse_iterator rend() { return data_.rend(); }
-  const_reverse_iterator rend() const { return data_.rend(); }
-
- private:
-  std::vector<T*> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedPtrVector);
-};
-
-}  // namespace cc
-
-#endif  // CC_BASE_SCOPED_PTR_VECTOR_H_
diff --git a/cc/base/scoped_ptr_vector_unittest.cc b/cc/base/scoped_ptr_vector_unittest.cc
deleted file mode 100644
index 7b9a86b..0000000
--- a/cc/base/scoped_ptr_vector_unittest.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2012 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.
-
-#include <set>
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace cc {
-namespace {
-
-class Data {
- public:
-  static scoped_ptr<Data> Create(int i) { return make_scoped_ptr(new Data(i)); }
-  int data() const { return data_; }
- private:
-  explicit Data(int i) : data_(i) {}
-  int data_;
-};
-
-class IsOddPredicate {
- public:
-  bool operator()(const Data* data) { return (data->data() % 2) == 1; }
-};
-
-TEST(ScopedPtrVectorTest, PushBack) {
-  ScopedPtrVector<Data> v;
-
-  // Insert 5 things into the vector.
-  v.push_back(Data::Create(1));
-  v.push_back(Data::Create(2));
-  v.push_back(Data::Create(3));
-  v.push_back(Data::Create(4));
-  v.push_back(Data::Create(5));
-
-  EXPECT_EQ(5u, v.size());
-  EXPECT_EQ(1, v[0]->data());
-  EXPECT_EQ(2, v[1]->data());
-  EXPECT_EQ(3, v[2]->data());
-  EXPECT_EQ(4, v[3]->data());
-  EXPECT_EQ(5, v[4]->data());
-}
-
-TEST(ScopedPtrVectorTest, InsertAndTake) {
-  // Insert 3 things into each vector.
-  ScopedPtrVector<Data> v;
-  v.push_back(Data::Create(1));
-  v.push_back(Data::Create(2));
-  v.push_back(Data::Create(6));
-
-  ScopedPtrVector<Data> v2;
-  v2.push_back(Data::Create(3));
-  v2.push_back(Data::Create(4));
-  v2.push_back(Data::Create(5));
-
-  ScopedPtrVector<Data>::iterator it = v.begin();
-  ++it;
-  ++it;
-  EXPECT_EQ(6, (*it)->data());
-
-  v.insert_and_take(it, &v2);
-
-  EXPECT_EQ(6u, v.size());
-  EXPECT_EQ(1, v[0]->data());
-  EXPECT_EQ(2, v[1]->data());
-  EXPECT_EQ(3, v[2]->data());
-  EXPECT_EQ(4, v[3]->data());
-  EXPECT_EQ(5, v[4]->data());
-  EXPECT_EQ(6, v[5]->data());
-
-  EXPECT_EQ(3u, v2.size());
-  EXPECT_EQ(nullptr, v2[0]);
-  EXPECT_EQ(nullptr, v2[1]);
-  EXPECT_EQ(nullptr, v2[2]);
-}
-
-TEST(ScopedPtrVectorTest, Partition) {
-  ScopedPtrVector<Data> v;
-  v.push_back(Data::Create(1));
-  v.push_back(Data::Create(2));
-  v.push_back(Data::Create(3));
-  v.push_back(Data::Create(4));
-  v.push_back(Data::Create(5));
-
-  ScopedPtrVector<Data>::iterator it = v.partition(IsOddPredicate());
-  std::set<int> odd_numbers;
-  for (ScopedPtrVector<Data>::iterator second_it = v.begin();
-       second_it != it;
-       ++second_it) {
-    EXPECT_EQ(1, (*second_it)->data() % 2);
-    odd_numbers.insert((*second_it)->data());
-  }
-  EXPECT_EQ(3u, odd_numbers.size());
-
-  std::set<int> even_numbers;
-  for (; it != v.end(); ++it) {
-    EXPECT_EQ(0, (*it)->data() % 2);
-    even_numbers.insert((*it)->data());
-  }
-  EXPECT_EQ(2u, even_numbers.size());
-}
-
-class DataWithDestruction {
- public:
-  static scoped_ptr<DataWithDestruction> Create(int i, int* destroy_count) {
-    return make_scoped_ptr(new DataWithDestruction(i, destroy_count));
-  }
-  int data() const { return data_; }
-  ~DataWithDestruction() { ++(*destroy_count_); }
-
- private:
-  explicit DataWithDestruction(int i, int* destroy_count)
-      : data_(i), destroy_count_(destroy_count) {}
-  int data_;
-  int* destroy_count_;
-};
-
-TEST(ScopedPtrVectorTest, RemoveIf) {
-  ScopedPtrVector<DataWithDestruction> v;
-  int destroyed[6] = {0};
-  v.push_back(DataWithDestruction::Create(1, &destroyed[0]));
-  v.push_back(DataWithDestruction::Create(2, &destroyed[1]));
-  v.push_back(DataWithDestruction::Create(3, &destroyed[2]));
-  v.push_back(DataWithDestruction::Create(3, &destroyed[3]));
-  v.push_back(DataWithDestruction::Create(4, &destroyed[4]));
-  v.push_back(DataWithDestruction::Create(5, &destroyed[5]));
-
-  int expect_destroyed[6] = {0};
-
-  // Removing more than one thing that matches.
-  auto is_three = [](DataWithDestruction* d) { return d->data() == 3; };
-  v.erase(v.remove_if(is_three), v.end());
-  EXPECT_EQ(4u, v.size());
-  expect_destroyed[2]++;
-  expect_destroyed[3]++;
-  for (size_t i = 0; i < arraysize(destroyed); ++i)
-    EXPECT_EQ(expect_destroyed[i], destroyed[i]) << i;
-  {
-    int expect_data[4] = {1, 2, 4, 5};
-    for (size_t i = 0; i < arraysize(expect_data); ++i)
-      EXPECT_EQ(expect_data[i], v[i]->data()) << i;
-  }
-
-  // Removing from the back of the vector.
-  auto is_five = [](DataWithDestruction* d) { return d->data() == 5; };
-  v.erase(v.remove_if(is_five), v.end());
-  EXPECT_EQ(3u, v.size());
-  expect_destroyed[5]++;
-  for (size_t i = 0; i < arraysize(destroyed); ++i)
-    EXPECT_EQ(expect_destroyed[i], destroyed[i]) << i;
-  {
-    int expect_data[3] = {1, 2, 4};
-    for (size_t i = 0; i < arraysize(expect_data); ++i)
-      EXPECT_EQ(expect_data[i], v[i]->data()) << i;
-  }
-
-  // Removing from the front of the vector.
-  auto is_one = [](DataWithDestruction* d) { return d->data() == 1; };
-  v.erase(v.remove_if(is_one), v.end());
-  EXPECT_EQ(2u, v.size());
-  expect_destroyed[0]++;
-  for (size_t i = 0; i < arraysize(destroyed); ++i)
-    EXPECT_EQ(expect_destroyed[i], destroyed[i]) << i;
-  {
-    int expect_data[2] = {2, 4};
-    for (size_t i = 0; i < arraysize(expect_data); ++i)
-      EXPECT_EQ(expect_data[i], v[i]->data()) << i;
-  }
-
-  // Removing things that aren't in the vector does nothing.
-  v.erase(v.remove_if(is_one), v.end());
-  EXPECT_EQ(2u, v.size());
-  for (size_t i = 0; i < arraysize(destroyed); ++i)
-    EXPECT_EQ(expect_destroyed[i], destroyed[i]) << i;
-  {
-    int expect_data[2] = {2, 4};
-    for (size_t i = 0; i < arraysize(expect_data); ++i)
-      EXPECT_EQ(expect_data[i], v[i]->data()) << i;
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/base/switches.cc b/cc/base/switches.cc
deleted file mode 100644
index ae42482..0000000
--- a/cc/base/switches.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "cc/base/switches.h"
-
-#include "base/command_line.h"
-
-namespace cc {
-namespace switches {
-
-const char kDisableThreadedAnimation[] = "disable-threaded-animation";
-
-// Disables layer-edge anti-aliasing in the compositor.
-const char kDisableCompositedAntialiasing[] =
-    "disable-composited-antialiasing";
-
-// Disables sending the next BeginMainFrame before the previous commit
-// activates. Overrides the kEnableMainFrameBeforeActivation flag.
-const char kDisableMainFrameBeforeActivation[] =
-    "disable-main-frame-before-activation";
-
-// Enables sending the next BeginMainFrame before the previous commit activates.
-const char kEnableMainFrameBeforeActivation[] =
-    "enable-main-frame-before-activation";
-
-// Percentage of the top controls need to be hidden before they will auto hide.
-const char kTopControlsHideThreshold[] = "top-controls-hide-threshold";
-
-// Percentage of the top controls need to be shown before they will auto show.
-const char kTopControlsShowThreshold[] = "top-controls-show-threshold";
-
-// Re-rasters everything multiple times to simulate a much slower machine.
-// Give a scale factor to cause raster to take that many times longer to
-// complete, such as --slow-down-raster-scale-factor=25.
-const char kSlowDownRasterScaleFactor[] = "slow-down-raster-scale-factor";
-
-// Max tiles allowed for each tilings interest area.
-const char kMaxTilesForInterestArea[] = "max-tiles-for-interest-area";
-
-// The amount of unused resource memory compositor is allowed to keep around.
-const char kMaxUnusedResourceMemoryUsagePercentage[] =
-    "max-unused-resource-memory-usage-percentage";
-
-// Causes the compositor to render to textures which are then sent to the parent
-// through the texture mailbox mechanism.
-// Requires --enable-compositor-frame-message.
-const char kCompositeToMailbox[] = "composite-to-mailbox";
-
-// Check that property changes during paint do not occur.
-const char kStrictLayerPropertyChangeChecking[] =
-    "strict-layer-property-change-checking";
-
-// Virtual viewport for fixed-position elements, scrollbars during pinch.
-const char kEnablePinchVirtualViewport[] = "enable-pinch-virtual-viewport";
-const char kDisablePinchVirtualViewport[] = "disable-pinch-virtual-viewport";
-
-// Ensures that the draw properties computed via the property trees match those
-// computed by CalcDrawProperties.
-const char kEnablePropertyTreeVerification[] =
-    "enable-property-tree-verification";
-
-// Disable partial swap which is needed for some OpenGL drivers / emulators.
-const char kUIDisablePartialSwap[] = "ui-disable-partial-swap";
-
-// Enables the GPU benchmarking extension
-const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking";
-
-// Renders a border around compositor layers to help debug and study
-// layer compositing.
-const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
-const char kUIShowCompositedLayerBorders[] = "ui-show-layer-borders";
-
-// Draws a heads-up-display showing Frames Per Second as well as GPU memory
-// usage. If you also use --vmodule="head*=1" then FPS will also be output to
-// the console log.
-const char kShowFPSCounter[] = "show-fps-counter";
-const char kUIShowFPSCounter[] = "ui-show-fps-counter";
-
-// Renders a border that represents the bounding box for the layer's animation.
-const char kShowLayerAnimationBounds[] = "show-layer-animation-bounds";
-const char kUIShowLayerAnimationBounds[] = "ui-show-layer-animation-bounds";
-
-// Show rects in the HUD around layers whose properties have changed.
-const char kShowPropertyChangedRects[] = "show-property-changed-rects";
-const char kUIShowPropertyChangedRects[] = "ui-show-property-changed-rects";
-
-// Show rects in the HUD around damage as it is recorded into each render
-// surface.
-const char kShowSurfaceDamageRects[] = "show-surface-damage-rects";
-const char kUIShowSurfaceDamageRects[] = "ui-show-surface-damage-rects";
-
-// Show rects in the HUD around the screen-space transformed bounds of every
-// layer.
-const char kShowScreenSpaceRects[] = "show-screenspace-rects";
-const char kUIShowScreenSpaceRects[] = "ui-show-screenspace-rects";
-
-// Show rects in the HUD around the screen-space transformed bounds of every
-// layer's replica, when they have one.
-const char kShowReplicaScreenSpaceRects[] = "show-replica-screenspace-rects";
-const char kUIShowReplicaScreenSpaceRects[] =
-    "ui-show-replica-screenspace-rects";
-
-// Prevents the layer tree unit tests from timing out.
-const char kCCLayerTreeTestNoTimeout[] = "cc-layer-tree-test-no-timeout";
-
-// Makes pixel tests write their output instead of read it.
-const char kCCRebaselinePixeltests[] = "cc-rebaseline-pixeltests";
-
-}  // namespace switches
-}  // namespace cc
diff --git a/cc/base/switches.h b/cc/base/switches.h
deleted file mode 100644
index e6727ee..0000000
--- a/cc/base/switches.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 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.
-
-// Defines all the "cc" command-line switches.
-
-#ifndef CC_BASE_SWITCHES_H_
-#define CC_BASE_SWITCHES_H_
-
-// Since cc is used from the render process, anything that goes here also needs
-// to be added to render_process_host_impl.cc.
-
-namespace cc {
-namespace switches {
-
-// Switches for the renderer compositor only.
-extern const char kDisableThreadedAnimation[];
-extern const char kDisableCompositedAntialiasing[];
-extern const char kDisableMainFrameBeforeActivation[];
-extern const char kEnableMainFrameBeforeActivation[];
-extern const char kJankInsteadOfCheckerboard[];
-extern const char kTopControlsHideThreshold[];
-extern const char kTopControlsShowThreshold[];
-extern const char kSlowDownRasterScaleFactor[];
-extern const char kCompositeToMailbox[];
-extern const char kMaxTilesForInterestArea[];
-extern const char kMaxUnusedResourceMemoryUsagePercentage[];
-extern const char kEnablePinchVirtualViewport[];
-extern const char kDisablePinchVirtualViewport[];
-extern const char kStrictLayerPropertyChangeChecking[];
-extern const char kEnablePropertyTreeVerification[];
-
-// Switches for both the renderer and ui compositors.
-extern const char kUIDisablePartialSwap[];
-extern const char kEnableGpuBenchmarking[];
-
-// Debug visualizations.
-extern const char kShowCompositedLayerBorders[];
-extern const char kUIShowCompositedLayerBorders[];
-extern const char kShowFPSCounter[];
-extern const char kUIShowFPSCounter[];
-extern const char kShowLayerAnimationBounds[];
-extern const char kUIShowLayerAnimationBounds[];
-extern const char kShowPropertyChangedRects[];
-extern const char kUIShowPropertyChangedRects[];
-extern const char kShowSurfaceDamageRects[];
-extern const char kUIShowSurfaceDamageRects[];
-extern const char kShowScreenSpaceRects[];
-extern const char kUIShowScreenSpaceRects[];
-extern const char kShowReplicaScreenSpaceRects[];
-extern const char kUIShowReplicaScreenSpaceRects[];
-
-// Unit test related.
-extern const char kCCLayerTreeTestNoTimeout[];
-extern const char kCCRebaselinePixeltests[];
-
-}  // namespace switches
-}  // namespace cc
-
-#endif  // CC_BASE_SWITCHES_H_
diff --git a/cc/base/util.h b/cc/base/util.h
deleted file mode 100644
index a16d485..0000000
--- a/cc/base/util.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_BASE_UTIL_H_
-#define CC_BASE_UTIL_H_
-
-#include <limits>
-
-#include "base/basictypes.h"
-
-namespace cc {
-
-template <typename T> T RoundUp(T n, T mul) {
-  static_assert(std::numeric_limits<T>::is_integer,
-                "T must be an integer type");
-  return (n > 0) ? ((n + mul - 1) / mul) * mul
-                 : (n / mul) * mul;
-}
-
-template <typename T> T RoundDown(T n, T mul) {
-  static_assert(std::numeric_limits<T>::is_integer,
-                "T must be an integer type");
-  return (n > 0) ? (n / mul) * mul
-                 : (n == 0) ? 0
-                 : ((n - mul + 1) / mul) * mul;
-}
-
-}  // namespace cc
-
-#endif  // CC_BASE_UTIL_H_
diff --git a/cc/base/util_unittest.cc b/cc/base/util_unittest.cc
deleted file mode 100644
index 6665a6a..0000000
--- a/cc/base/util_unittest.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/base/util.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-TEST(UtilTest, RoundUp) {
-  for (int multiplier = 1; multiplier <= 10; ++multiplier) {
-    // Try attempts in descending order, so that we can
-    // determine the correct value before it's needed.
-    int correct;
-    for (int attempt = 5 * multiplier; attempt >= -5 * multiplier; --attempt) {
-      if ((attempt % multiplier) == 0)
-        correct = attempt;
-      EXPECT_EQ(correct, RoundUp(attempt, multiplier))
-          << "attempt=" << attempt << " multiplier=" << multiplier;
-    }
-  }
-
-  for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
-    // Try attempts in descending order, so that we can
-    // determine the correct value before it's needed.
-    unsigned correct;
-    for (unsigned attempt = 5 * multiplier; attempt > 0; --attempt) {
-      if ((attempt % multiplier) == 0)
-        correct = attempt;
-      EXPECT_EQ(correct, RoundUp(attempt, multiplier))
-          << "attempt=" << attempt << " multiplier=" << multiplier;
-    }
-    EXPECT_EQ(0u, RoundUp(0u, multiplier))
-        << "attempt=0 multiplier=" << multiplier;
-  }
-}
-
-TEST(UtilTest, RoundDown) {
-  for (int multiplier = 1; multiplier <= 10; ++multiplier) {
-    // Try attempts in ascending order, so that we can
-    // determine the correct value before it's needed.
-    int correct;
-    for (int attempt = -5 * multiplier; attempt <= 5 * multiplier; ++attempt) {
-      if ((attempt % multiplier) == 0)
-        correct = attempt;
-      EXPECT_EQ(correct, RoundDown(attempt, multiplier))
-          << "attempt=" << attempt << " multiplier=" << multiplier;
-    }
-  }
-
-  for (unsigned multiplier = 1; multiplier <= 10; ++multiplier) {
-    // Try attempts in ascending order, so that we can
-    // determine the correct value before it's needed.
-    unsigned correct;
-    for (unsigned attempt = 0; attempt <= 5 * multiplier; ++attempt) {
-      if ((attempt % multiplier) == 0)
-        correct = attempt;
-      EXPECT_EQ(correct, RoundDown(attempt, multiplier))
-          << "attempt=" << attempt << " multiplier=" << multiplier;
-    }
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/debug/OWNERS b/cc/debug/OWNERS
deleted file mode 100644
index 2de2d9b..0000000
--- a/cc/debug/OWNERS
+++ /dev/null
@@ -1,7 +0,0 @@
-# Changes to this file may break telemetry benchmarks
-per-file benchmark_instrumentation.h=set noparent
-per-file benchmark_instrumentation.h=ernstm@chromium.org
-per-file benchmark_instrumentation.h=nduca@chromium.org
-per-file benchmark_instrumentation.cc=set noparent
-per-file benchmark_instrumentation.cc=ernstm@chromium.org
-per-file benchmark_instrumentation.cc=nduca@chromium.org
diff --git a/cc/debug/frame_timing_request.cc b/cc/debug/frame_timing_request.cc
deleted file mode 100644
index 6c54ea2..0000000
--- a/cc/debug/frame_timing_request.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// 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.
-
-#include "cc/debug/frame_timing_request.h"
-
-namespace cc {
-
-FrameTimingRequest::FrameTimingRequest() : id_(0) {
-}
-
-FrameTimingRequest::FrameTimingRequest(int64_t request_id,
-                                       const gfx::Rect& rect)
-    : id_(request_id), rect_(rect) {
-}
-
-}  // namespace cc
diff --git a/cc/debug/frame_timing_request.h b/cc/debug/frame_timing_request.h
deleted file mode 100644
index aa5b83a..0000000
--- a/cc/debug/frame_timing_request.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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.
-
-#ifndef CC_DEBUG_FRAME_TIMING_REQUEST_H_
-#define CC_DEBUG_FRAME_TIMING_REQUEST_H_
-
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-// This class represents a request to record frame timing information about the
-// given rect (in layer space) and an associated request id. When this request
-// is propagated to the active LayerImpl, it will cause events to be saved in
-// FrameTimingTracker, which in turn can be consumed by the requester.
-class FrameTimingRequest {
- public:
-  FrameTimingRequest();
-  FrameTimingRequest(int64_t request_id, const gfx::Rect& rect);
-
-  // Return the ID for the request.
-  int64_t id() const { return id_; }
-
-  // Return the layer space rect for this request.
-  const gfx::Rect& rect() const { return rect_; }
-
- private:
-  int64_t id_;
-  gfx::Rect rect_;
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_FRAME_TIMING_REQUEST_H_
diff --git a/cc/debug/frame_timing_tracker.cc b/cc/debug/frame_timing_tracker.cc
deleted file mode 100644
index 009d298..0000000
--- a/cc/debug/frame_timing_tracker.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// 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.
-
-#include "cc/debug/frame_timing_tracker.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "base/metrics/histogram.h"
-#include "cc/trees/proxy.h"
-
-namespace cc {
-
-FrameTimingTracker::CompositeTimingEvent::CompositeTimingEvent(
-    int _frame_id,
-    base::TimeTicks _timestamp)
-    : frame_id(_frame_id), timestamp(_timestamp) {
-}
-
-FrameTimingTracker::CompositeTimingEvent::~CompositeTimingEvent() {
-}
-
-// static
-scoped_ptr<FrameTimingTracker> FrameTimingTracker::Create() {
-  return make_scoped_ptr(new FrameTimingTracker);
-}
-
-FrameTimingTracker::FrameTimingTracker() {
-}
-
-FrameTimingTracker::~FrameTimingTracker() {
-}
-
-void FrameTimingTracker::SaveTimeStamps(
-    base::TimeTicks timestamp,
-    const std::vector<FrameAndRectIds>& frame_ids) {
-  if (!composite_events_)
-    composite_events_.reset(new CompositeTimingSet);
-  for (const auto& pair : frame_ids)
-    (*composite_events_)[pair.second].push_back(
-        CompositeTimingEvent(pair.first, timestamp));
-}
-
-scoped_ptr<FrameTimingTracker::CompositeTimingSet>
-FrameTimingTracker::GroupCountsByRectId() {
-  if (!composite_events_)
-    return make_scoped_ptr(new CompositeTimingSet);
-  scoped_ptr<CompositeTimingSet> composite_info(new CompositeTimingSet);
-  for (auto& infos : *composite_events_)
-    std::sort(
-        infos.second.begin(), infos.second.end(),
-        [](const CompositeTimingEvent& lhs, const CompositeTimingEvent& rhs) {
-          return lhs.timestamp < rhs.timestamp;
-        });
-  return composite_events_.Pass();
-}
-
-}  // namespace cc
diff --git a/cc/debug/frame_timing_tracker.h b/cc/debug/frame_timing_tracker.h
deleted file mode 100644
index 7ac7a8a..0000000
--- a/cc/debug/frame_timing_tracker.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// 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.
-
-#ifndef CC_DEBUG_FRAME_TIMING_TRACKER_H_
-#define CC_DEBUG_FRAME_TIMING_TRACKER_H_
-
-#include <utility>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-
-namespace cc {
-
-// This class maintains a history of timestamps and rect IDs to communicate
-// frame events back to Blink
-// TODO(mpb): Start using this. crbug.com/442554
-class FrameTimingTracker {
- public:
-  struct CompositeTimingEvent {
-    CompositeTimingEvent(int, base::TimeTicks);
-    ~CompositeTimingEvent();
-
-    int frame_id;
-    base::TimeTicks timestamp;
-  };
-
-  using CompositeTimingSet =
-      base::hash_map<int, std::vector<CompositeTimingEvent>>;
-
-  static scoped_ptr<FrameTimingTracker> Create();
-
-  ~FrameTimingTracker();
-
-  // This routine takes all of the individual CompositeEvents stored in the
-  // tracker and collects them by "rect_id", as in the example below.
-  // [ {f_id1,r_id1,t1}, {f_id2,r_id1,t2}, {f_id3,r_id2,t3} ]
-  // ====>
-  // [ {r_id1,<{f_id1,t1},{f_id2,t2}>}, {r_id2,<{f_id3,t3}>} ]
-  scoped_ptr<CompositeTimingSet> GroupCountsByRectId();
-
-  // This routine takes a timestamp and an array of frame_id,rect_id pairs
-  // and generates CompositeTimingEvents (frame_id, timestamp) and adds them to
-  // internal hash_map keyed on rect_id
-  using FrameAndRectIds = std::pair<int, int64_t>;
-  void SaveTimeStamps(base::TimeTicks timestamp,
-                      const std::vector<FrameAndRectIds>& frame_ids);
-
- private:
-  FrameTimingTracker();
-
-  scoped_ptr<CompositeTimingSet> composite_events_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameTimingTracker);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_FRAME_TIMING_TRACKER_H_
diff --git a/cc/debug/frame_timing_tracker_unittest.cc b/cc/debug/frame_timing_tracker_unittest.cc
deleted file mode 100644
index 85f5716..0000000
--- a/cc/debug/frame_timing_tracker_unittest.cc
+++ /dev/null
@@ -1,125 +0,0 @@
-// 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.
-
-#include <string>
-
-#include "base/time/time.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/debug/frame_timing_tracker.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-static std::string ToString(
-    scoped_ptr<FrameTimingTracker::CompositeTimingSet> timingset) {
-  scoped_refptr<base::trace_event::TracedValue> value =
-      new base::trace_event::TracedValue();
-  value->BeginArray("values");
-  for (const auto& it : *timingset) {
-    value->BeginDictionary();
-    value->SetInteger("rect_id", it.first);
-    value->BeginArray("events");
-    for (const auto& event : it.second) {
-      value->BeginDictionary();
-      value->SetInteger("frame_id", event.frame_id);
-      value->SetInteger("timestamp", event.timestamp.ToInternalValue());
-      value->EndDictionary();
-    }
-    value->EndArray();
-    value->EndDictionary();
-  }
-  value->EndArray();
-  return value->ToString();
-}
-
-TEST(FrameTimingTrackerTest, DefaultTrackerIsEmpty) {
-  scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
-  EXPECT_EQ("{\"values\":[]}", ToString(tracker->GroupCountsByRectId()));
-}
-
-TEST(FrameTimingTrackerTest, NoFrameIdsIsEmpty) {
-  scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
-  std::vector<std::pair<int, int64_t>> ids;
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids);
-  EXPECT_EQ("{\"values\":[]}", ToString(tracker->GroupCountsByRectId()));
-}
-
-TEST(FrameTimingTrackerTest, OneFrameId) {
-  scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
-  std::vector<std::pair<int, int64_t>> ids;
-  ids.push_back(std::make_pair(1, 2));
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids);
-  EXPECT_EQ(
-      "{\"values\":[{\"events\":["
-      "{\"frame_id\":1,\"timestamp\":100}],\"rect_id\":2}]}",
-      ToString(tracker->GroupCountsByRectId()));
-}
-
-TEST(FrameTimingTrackerTest, UnsortedTimestampsIds) {
-  scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
-  std::vector<std::pair<int, int64_t>> ids;
-  ids.push_back(std::make_pair(1, 2));
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(200), ids);
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(400), ids);
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids);
-  EXPECT_EQ(
-      "{\"values\":[{\"events\":["
-      "{\"frame_id\":1,\"timestamp\":100},"
-      "{\"frame_id\":1,\"timestamp\":200},"
-      "{\"frame_id\":1,\"timestamp\":400}],\"rect_id\":2}]}",
-      ToString(tracker->GroupCountsByRectId()));
-}
-
-TEST(FrameTimingTrackerTest, MultipleFrameIds) {
-  scoped_ptr<FrameTimingTracker> tracker(FrameTimingTracker::Create());
-
-  std::vector<std::pair<int, int64_t>> ids200;
-  ids200.push_back(std::make_pair(1, 2));
-  ids200.push_back(std::make_pair(1, 3));
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(200), ids200);
-
-  std::vector<std::pair<int, int64_t>> ids400;
-  ids400.push_back(std::make_pair(2, 2));
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(400), ids400);
-
-  std::vector<std::pair<int, int64_t>> ids100;
-  ids100.push_back(std::make_pair(3, 2));
-  ids100.push_back(std::make_pair(2, 3));
-  ids100.push_back(std::make_pair(3, 4));
-  tracker->SaveTimeStamps(base::TimeTicks::FromInternalValue(100), ids100);
-
-  std::string result = ToString(tracker->GroupCountsByRectId());
-
-  EXPECT_EQ(strlen(
-                "{\"values\":[{\"events\":["
-                "{\"frame_id\":3,\"timestamp\":100},"
-                "{\"frame_id\":1,\"timestamp\":200},"
-                "{\"frame_id\":2,\"timestamp\":400}],\"rect_id\":2},"
-                "{\"events\":["
-                "{\"frame_id\":2,\"timestamp\":100},"
-                "{\"frame_id\":1,\"timestamp\":200}],\"rect_id\":3},"
-                "{\"events\":["
-                "{\"frame_id\":3,\"timestamp\":100}],\"rect_id\":4}"
-                "]}"),
-            result.size());
-  EXPECT_NE(std::string::npos,
-            result.find(
-                "{\"frame_id\":3,\"timestamp\":100},"
-                "{\"frame_id\":1,\"timestamp\":200},"
-                "{\"frame_id\":2,\"timestamp\":400}],\"rect_id\":2}"));
-  EXPECT_NE(std::string::npos,
-            result.find(
-                "{\"events\":["
-                "{\"frame_id\":2,\"timestamp\":100},"
-                "{\"frame_id\":1,\"timestamp\":200}],\"rect_id\":3}"));
-  EXPECT_NE(std::string::npos,
-            result.find(
-                "{\"events\":["
-                "{\"frame_id\":3,\"timestamp\":100}],\"rect_id\":4}"));
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/debug/frame_viewer_instrumentation.cc b/cc/debug/frame_viewer_instrumentation.cc
deleted file mode 100644
index 226cc88..0000000
--- a/cc/debug/frame_viewer_instrumentation.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/debug/frame_viewer_instrumentation.h"
-
-namespace cc {
-namespace frame_viewer_instrumentation {
-
-const char kCategoryLayerTree[] =
-    TRACE_DISABLED_BY_DEFAULT("cc.debug") ","
-    TRACE_DISABLED_BY_DEFAULT("cc.debug.quads") ","
-    TRACE_DISABLED_BY_DEFAULT("devtools.timeline.layers");
-
-namespace {
-
-const char kCategory[] = "cc," TRACE_DISABLED_BY_DEFAULT("devtools.timeline");
-const char kTileData[] = "tileData";
-const char kLayerId[] = "layerId";
-const char kTileId[] = "tileId";
-const char kTileResolution[] = "tileResolution";
-const char kSourceFrameNumber[] = "sourceFrameNumber";
-
-const char kAnalyzeTask[] = "AnalyzeTask";
-const char kRasterTask[] = "RasterTask";
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat> TileDataAsValue(
-    const void* tile_id,
-    TileResolution tile_resolution,
-    int source_frame_number,
-    int layer_id) {
-  scoped_refptr<base::trace_event::TracedValue> res(
-      new base::trace_event::TracedValue());
-  TracedValue::SetIDRef(tile_id, res.get(), kTileId);
-  res->SetString(kTileResolution, TileResolutionToString(tile_resolution));
-  res->SetInteger(kSourceFrameNumber, source_frame_number);
-  res->SetInteger(kLayerId, layer_id);
-  return res;
-}
-
-}  // namespace
-
-ScopedAnalyzeTask::ScopedAnalyzeTask(const void* tile_id,
-                                     TileResolution tile_resolution,
-                                     int source_frame_number,
-                                     int layer_id) {
-  TRACE_EVENT_BEGIN1(
-      kCategory, kAnalyzeTask, kTileData,
-      TileDataAsValue(tile_id, tile_resolution, source_frame_number, layer_id));
-}
-
-ScopedAnalyzeTask::~ScopedAnalyzeTask() {
-  TRACE_EVENT_END0(kCategory, kAnalyzeTask);
-}
-
-ScopedRasterTask::ScopedRasterTask(const void* tile_id,
-                                   TileResolution tile_resolution,
-                                   int source_frame_number,
-                                   int layer_id) {
-  TRACE_EVENT_BEGIN1(
-      kCategory, kRasterTask, kTileData,
-      TileDataAsValue(tile_id, tile_resolution, source_frame_number, layer_id));
-}
-
-ScopedRasterTask::~ScopedRasterTask() {
-  TRACE_EVENT_END0(kCategory, kRasterTask);
-}
-
-bool IsTracingLayerTreeSnapshots() {
-  bool category_enabled;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(kCategoryLayerTree, &category_enabled);
-  return category_enabled;
-}
-
-}  // namespace frame_viewer_instrumentation
-}  // namespace cc
diff --git a/cc/debug/frame_viewer_instrumentation.h b/cc/debug/frame_viewer_instrumentation.h
deleted file mode 100644
index b6736be..0000000
--- a/cc/debug/frame_viewer_instrumentation.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_DEBUG_FRAME_VIEWER_INSTRUMENTATION_H_
-#define CC_DEBUG_FRAME_VIEWER_INSTRUMENTATION_H_
-
-#include "base/trace_event/trace_event.h"
-#include "cc/resources/tile.h"
-
-namespace cc {
-namespace frame_viewer_instrumentation {
-
-extern const char kCategoryLayerTree[];
-
-class ScopedAnalyzeTask {
- public:
-  ScopedAnalyzeTask(const void* tile_id,
-                    TileResolution tile_resolution,
-                    int source_frame_number,
-                    int layer_id);
-  ~ScopedAnalyzeTask();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ScopedAnalyzeTask);
-};
-
-class ScopedRasterTask {
- public:
-  ScopedRasterTask(const void* tile_id,
-                   TileResolution tile_resolution,
-                   int source_frame_number,
-                   int layer_id);
-  ~ScopedRasterTask();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ScopedRasterTask);
-};
-
-bool IsTracingLayerTreeSnapshots();
-
-}  // namespace frame_viewer_instrumentation
-}  // namespace cc
-
-#endif  // CC_DEBUG_FRAME_VIEWER_INSTRUMENTATION_H_
diff --git a/cc/debug/lap_timer.cc b/cc/debug/lap_timer.cc
deleted file mode 100644
index 347e3a5..0000000
--- a/cc/debug/lap_timer.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/debug/lap_timer.h"
-
-#include "base/logging.h"
-
-namespace cc {
-
-namespace {
-
-base::TimeDelta Now() {
-  return base::ThreadTicks::IsSupported()
-             ? base::ThreadTicks::Now() - base::ThreadTicks()
-             : base::TimeTicks::Now() - base::TimeTicks();
-}
-
-}  // namespace
-
-LapTimer::LapTimer(int warmup_laps,
-                   base::TimeDelta time_limit,
-                   int check_interval)
-    : warmup_laps_(warmup_laps),
-      remaining_warmups_(0),
-      remaining_no_check_laps_(0),
-      time_limit_(time_limit),
-      check_interval_(check_interval) {
-  DCHECK_GT(check_interval, 0);
-  Reset();
-}
-
-void LapTimer::Reset() {
-  accumulator_ = base::TimeDelta();
-  num_laps_ = 0;
-  remaining_warmups_ = warmup_laps_;
-  remaining_no_check_laps_ = check_interval_;
-  Start();
-}
-
-void LapTimer::Start() {
-  start_time_ = Now();
-}
-
-bool LapTimer::IsWarmedUp() { return remaining_warmups_ <= 0; }
-
-void LapTimer::NextLap() {
-  if (!IsWarmedUp()) {
-    --remaining_warmups_;
-    if (IsWarmedUp()) {
-      Start();
-    }
-    return;
-  }
-  ++num_laps_;
-  --remaining_no_check_laps_;
-  if (!remaining_no_check_laps_) {
-    base::TimeDelta now = Now();
-    accumulator_ += now - start_time_;
-    start_time_ = now;
-    remaining_no_check_laps_ = check_interval_;
-  }
-}
-
-bool LapTimer::HasTimeLimitExpired() { return accumulator_ >= time_limit_; }
-
-bool LapTimer::HasTimedAllLaps() { return !(num_laps_ % check_interval_); }
-
-float LapTimer::MsPerLap() {
-  DCHECK(HasTimedAllLaps());
-  return accumulator_.InMillisecondsF() / num_laps_;
-}
-
-float LapTimer::LapsPerSecond() {
-  DCHECK(HasTimedAllLaps());
-  return num_laps_ / accumulator_.InSecondsF();
-}
-
-int LapTimer::NumLaps() { return num_laps_; }
-
-}  // namespace cc
diff --git a/cc/debug/lap_timer.h b/cc/debug/lap_timer.h
deleted file mode 100644
index 934723d..0000000
--- a/cc/debug/lap_timer.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_DEBUG_LAP_TIMER_H_
-#define CC_DEBUG_LAP_TIMER_H_
-
-#include "base/time/time.h"
-
-namespace cc {
-
-// LapTimer is used to calculate average times per "Lap" in perf tests.
-// Current() reports the time since the last call to Start().
-// Store() adds the time since the last call to Start() to the accumulator, and
-// resets the start time to now. Stored() returns the accumulated time.
-// NextLap increments the lap counter, used in counting the per lap averages.
-// If you initialize the LapTimer with a non zero warmup_laps, it will ignore
-// the times for that many laps at the start.
-// If you set the time_limit then you can use HasTimeLimitExpired() to see if
-// the current accumulated time has crossed that threshold, with an optimization
-// that it only tests this every check_interval laps.
-class LapTimer {
- public:
-  LapTimer(int warmup_laps, base::TimeDelta time_limit, int check_interval);
-  // Resets the timer back to it's starting state.
-  void Reset();
-  // Sets the start point to now.
-  void Start();
-  // Returns true if there are no more warmup laps to do.
-  bool IsWarmedUp();
-  // Advance the lap counter and update the accumulated time.
-  // The accumulated time is only updated every check_interval laps.
-  // If accumulating then the start point will also be updated.
-  void NextLap();
-  // Returns true if the stored time has exceeded the time limit specified.
-  // May cause a call to Store().
-  bool HasTimeLimitExpired();
-  // Returns true if all lap times have been timed. Only true every n'th
-  // lap, where n = check_interval.
-  bool HasTimedAllLaps();
-  // The average milliseconds per lap.
-  float MsPerLap();
-  // The number of laps per second.
-  float LapsPerSecond();
-  // The number of laps recorded.
-  int NumLaps();
-
- private:
-  base::TimeDelta start_time_;
-  base::TimeDelta accumulator_;
-  int num_laps_;
-  int warmup_laps_;
-  int remaining_warmups_;
-  int remaining_no_check_laps_;
-  base::TimeDelta time_limit_;
-  int check_interval_;
-
-  DISALLOW_COPY_AND_ASSIGN(LapTimer);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_LAP_TIMER_H_
diff --git a/cc/debug/paint_time_counter.cc b/cc/debug/paint_time_counter.cc
deleted file mode 100644
index 41ef1a3..0000000
--- a/cc/debug/paint_time_counter.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/debug/paint_time_counter.h"
-
-namespace cc {
-
-// static
-scoped_ptr<PaintTimeCounter> PaintTimeCounter::Create() {
-  return make_scoped_ptr(new PaintTimeCounter());
-}
-
-PaintTimeCounter::PaintTimeCounter() {
-}
-
-void PaintTimeCounter::SavePaintTime(const base::TimeDelta& paint_time) {
-  ring_buffer_.SaveToBuffer(paint_time);
-}
-
-void PaintTimeCounter::GetMinAndMaxPaintTime(base::TimeDelta* min,
-                                             base::TimeDelta* max) const {
-  *min = base::TimeDelta::FromDays(1);
-  *max = base::TimeDelta();
-
-  for (RingBufferType::Iterator it = ring_buffer_.Begin(); it; ++it) {
-    const base::TimeDelta paint_time = **it;
-
-    if (paint_time < *min)
-      *min = paint_time;
-    if (paint_time > *max)
-      *max = paint_time;
-  }
-
-  if (*min > *max)
-    *min = *max;
-}
-
-void PaintTimeCounter::ClearHistory() {
-  ring_buffer_.Clear();
-}
-
-}  // namespace cc
diff --git a/cc/debug/paint_time_counter.h b/cc/debug/paint_time_counter.h
deleted file mode 100644
index c93980b..0000000
--- a/cc/debug/paint_time_counter.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_DEBUG_PAINT_TIME_COUNTER_H_
-#define CC_DEBUG_PAINT_TIME_COUNTER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "cc/debug/ring_buffer.h"
-
-namespace cc {
-
-// Maintains a history of paint times for each frame
-class PaintTimeCounter {
- public:
-  static scoped_ptr<PaintTimeCounter> Create();
-
-  size_t HistorySize() const { return ring_buffer_.BufferSize(); }
-
-  // n = 0 returns the oldest and
-  // n = PaintTimeHistorySize() - 1 the most recent paint time.
-  base::TimeDelta GetPaintTimeOfRecentFrame(const size_t& n) const;
-
-  void SavePaintTime(const base::TimeDelta& total_paint_time);
-  void GetMinAndMaxPaintTime(base::TimeDelta* min, base::TimeDelta* max) const;
-
-  void ClearHistory();
-
-  typedef RingBuffer<base::TimeDelta, 200> RingBufferType;
-  RingBufferType::Iterator Begin() const { return ring_buffer_.Begin(); }
-  RingBufferType::Iterator End() const { return ring_buffer_.End(); }
-
- private:
-  PaintTimeCounter();
-
-  RingBufferType ring_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(PaintTimeCounter);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_PAINT_TIME_COUNTER_H_
diff --git a/cc/debug/rendering_stats.cc b/cc/debug/rendering_stats.cc
deleted file mode 100644
index 3a27c1d..0000000
--- a/cc/debug/rendering_stats.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/debug/rendering_stats.h"
-
-namespace cc {
-
-RenderingStats::TimeDeltaList::TimeDeltaList() {
-}
-
-RenderingStats::TimeDeltaList::~TimeDeltaList() {
-}
-
-void RenderingStats::TimeDeltaList::Append(base::TimeDelta value) {
-  values.push_back(value);
-}
-
-void RenderingStats::TimeDeltaList::AddToTracedValue(
-    const char* name,
-    base::trace_event::TracedValue* list_value) const {
-  list_value->BeginArray(name);
-  for (const auto& value : values) {
-    list_value->AppendDouble(value.InMillisecondsF());
-  }
-  list_value->EndArray();
-}
-
-void RenderingStats::TimeDeltaList::Add(const TimeDeltaList& other) {
-  values.insert(values.end(), other.values.begin(), other.values.end());
-}
-
-base::TimeDelta RenderingStats::TimeDeltaList::GetLastTimeDelta() const {
-  return values.empty() ? base::TimeDelta() : values.back();
-}
-
-RenderingStats::RenderingStats()
-    : frame_count(0),
-      visible_content_area(0),
-      approximated_visible_content_area(0) {
-}
-
-RenderingStats::~RenderingStats() {
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-RenderingStats::AsTraceableData() const {
-  scoped_refptr<base::trace_event::TracedValue> record_data =
-      new base::trace_event::TracedValue();
-  record_data->SetInteger("frame_count", frame_count);
-  record_data->SetInteger("visible_content_area", visible_content_area);
-  record_data->SetInteger("approximated_visible_content_area",
-                          approximated_visible_content_area);
-  draw_duration.AddToTracedValue("draw_duration_ms", record_data.get());
-
-  draw_duration_estimate.AddToTracedValue("draw_duration_estimate_ms",
-                                          record_data.get());
-
-  begin_main_frame_to_commit_duration.AddToTracedValue(
-      "begin_main_frame_to_commit_duration_ms", record_data.get());
-
-  begin_main_frame_to_commit_duration_estimate.AddToTracedValue(
-      "begin_main_frame_to_commit_duration_estimate_ms", record_data.get());
-
-  commit_to_activate_duration.AddToTracedValue("commit_to_activate_duration_ms",
-                                               record_data.get());
-
-  commit_to_activate_duration_estimate.AddToTracedValue(
-      "commit_to_activate_duration_estimate_ms", record_data.get());
-  return record_data;
-}
-
-void RenderingStats::Add(const RenderingStats& other) {
-  frame_count += other.frame_count;
-  visible_content_area += other.visible_content_area;
-  approximated_visible_content_area += other.approximated_visible_content_area;
-
-  draw_duration.Add(other.draw_duration);
-  draw_duration_estimate.Add(other.draw_duration_estimate);
-  begin_main_frame_to_commit_duration.Add(
-      other.begin_main_frame_to_commit_duration);
-  begin_main_frame_to_commit_duration_estimate.Add(
-      other.begin_main_frame_to_commit_duration_estimate);
-  commit_to_activate_duration.Add(other.commit_to_activate_duration);
-  commit_to_activate_duration_estimate.Add(
-      other.commit_to_activate_duration_estimate);
-}
-
-}  // namespace cc
diff --git a/cc/debug/rendering_stats.h b/cc/debug/rendering_stats.h
deleted file mode 100644
index 63c69a8..0000000
--- a/cc/debug/rendering_stats.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_DEBUG_RENDERING_STATS_H_
-#define CC_DEBUG_RENDERING_STATS_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/debug/traced_value.h"
-
-namespace cc {
-
-struct RenderingStats {
-  // Stores a sequence of TimeDelta objects.
-  class TimeDeltaList {
-   public:
-    TimeDeltaList();
-    ~TimeDeltaList();
-
-    void Append(base::TimeDelta value);
-    void AddToTracedValue(const char* name,
-                          base::trace_event::TracedValue* list_value) const;
-
-    void Add(const TimeDeltaList& other);
-
-    base::TimeDelta GetLastTimeDelta() const;
-
-   private:
-    std::vector<base::TimeDelta> values;
-  };
-
-  RenderingStats();
-  ~RenderingStats();
-
-  // Note: when adding new members, please remember to update Add in
-  // rendering_stats.cc.
-
-  int64 frame_count;
-  int64 visible_content_area;
-  int64 approximated_visible_content_area;
-
-  TimeDeltaList draw_duration;
-  TimeDeltaList draw_duration_estimate;
-  TimeDeltaList begin_main_frame_to_commit_duration;
-  TimeDeltaList begin_main_frame_to_commit_duration_estimate;
-  TimeDeltaList commit_to_activate_duration;
-  TimeDeltaList commit_to_activate_duration_estimate;
-
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsTraceableData()
-      const;
-  void Add(const RenderingStats& other);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_RENDERING_STATS_H_
diff --git a/cc/debug/rendering_stats_instrumentation.cc b/cc/debug/rendering_stats_instrumentation.cc
deleted file mode 100644
index 4621772..0000000
--- a/cc/debug/rendering_stats_instrumentation.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/debug/rendering_stats_instrumentation.h"
-
-namespace cc {
-
-// static
-scoped_ptr<RenderingStatsInstrumentation>
-    RenderingStatsInstrumentation::Create() {
-  return make_scoped_ptr(new RenderingStatsInstrumentation());
-}
-
-RenderingStatsInstrumentation::RenderingStatsInstrumentation()
-    : record_rendering_stats_(false) {
-}
-
-RenderingStatsInstrumentation::~RenderingStatsInstrumentation() {}
-
-RenderingStats RenderingStatsInstrumentation::impl_thread_rendering_stats() {
-  base::AutoLock scoped_lock(lock_);
-  return impl_thread_rendering_stats_;
-}
-
-RenderingStats RenderingStatsInstrumentation::GetRenderingStats() {
-  base::AutoLock scoped_lock(lock_);
-  RenderingStats rendering_stats;
-  rendering_stats = impl_thread_rendering_stats_accu_;
-  rendering_stats.Add(impl_thread_rendering_stats_);
-  return rendering_stats;
-}
-
-void RenderingStatsInstrumentation::AccumulateAndClearImplThreadStats() {
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_accu_.Add(impl_thread_rendering_stats_);
-  impl_thread_rendering_stats_ = RenderingStats();
-}
-
-base::TimeDelta RenderingStatsInstrumentation::StartRecording() const {
-  if (record_rendering_stats_) {
-    if (base::ThreadTicks::IsSupported())
-      return base::ThreadTicks::Now() - base::ThreadTicks();
-    return base::TimeTicks::Now() - base::TimeTicks();
-  }
-  return base::TimeDelta();
-}
-
-base::TimeDelta RenderingStatsInstrumentation::EndRecording(
-    base::TimeDelta start_time) const {
-  if (start_time != base::TimeDelta()) {
-    if (base::ThreadTicks::IsSupported())
-      return (base::ThreadTicks::Now() - base::ThreadTicks()) - start_time;
-    return (base::TimeTicks::Now() - base::TimeTicks()) - start_time;
-  }
-  return base::TimeDelta();
-}
-
-void RenderingStatsInstrumentation::IncrementFrameCount(int64 count) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.frame_count += count;
-}
-
-void RenderingStatsInstrumentation::AddVisibleContentArea(int64 area) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.visible_content_area += area;
-}
-
-void RenderingStatsInstrumentation::AddApproximatedVisibleContentArea(
-    int64 area) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.approximated_visible_content_area += area;
-}
-
-void RenderingStatsInstrumentation::AddDrawDuration(
-    base::TimeDelta draw_duration,
-    base::TimeDelta draw_duration_estimate) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.draw_duration.Append(draw_duration);
-  impl_thread_rendering_stats_.draw_duration_estimate.Append(
-      draw_duration_estimate);
-}
-
-void RenderingStatsInstrumentation::AddBeginMainFrameToCommitDuration(
-    base::TimeDelta begin_main_frame_to_commit_duration,
-    base::TimeDelta begin_main_frame_to_commit_duration_estimate) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.begin_main_frame_to_commit_duration.Append(
-      begin_main_frame_to_commit_duration);
-  impl_thread_rendering_stats_.begin_main_frame_to_commit_duration_estimate
-      .Append(begin_main_frame_to_commit_duration_estimate);
-}
-
-void RenderingStatsInstrumentation::AddCommitToActivateDuration(
-    base::TimeDelta commit_to_activate_duration,
-    base::TimeDelta commit_to_activate_duration_estimate) {
-  if (!record_rendering_stats_)
-    return;
-
-  base::AutoLock scoped_lock(lock_);
-  impl_thread_rendering_stats_.commit_to_activate_duration.Append(
-      commit_to_activate_duration);
-  impl_thread_rendering_stats_.commit_to_activate_duration_estimate.Append(
-      commit_to_activate_duration_estimate);
-}
-
-}  // namespace cc
diff --git a/cc/debug/rendering_stats_instrumentation.h b/cc/debug/rendering_stats_instrumentation.h
deleted file mode 100644
index 6861202..0000000
--- a/cc/debug/rendering_stats_instrumentation.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_DEBUG_RENDERING_STATS_INSTRUMENTATION_H_
-#define CC_DEBUG_RENDERING_STATS_INSTRUMENTATION_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/synchronization/lock.h"
-#include "cc/debug/rendering_stats.h"
-
-namespace cc {
-
-// RenderingStatsInstrumentation is shared among threads and manages conditional
-// recording of rendering stats into a private RenderingStats instance.
-class RenderingStatsInstrumentation {
- public:
-  static scoped_ptr<RenderingStatsInstrumentation> Create();
-  virtual ~RenderingStatsInstrumentation();
-
-  // Return copy of current impl thread rendering stats.
-  RenderingStats impl_thread_rendering_stats();
-
-  // Return the accumulated, combined rendering stats.
-  RenderingStats GetRenderingStats();
-
-  // Add current impl thread rendering stats to accumulator and
-  // clear current stats.
-  void AccumulateAndClearImplThreadStats();
-
-  // Read and write access to the record_rendering_stats_ flag is not locked to
-  // improve performance. The flag is commonly turned off and hardly changes
-  // it's value during runtime.
-  bool record_rendering_stats() const { return record_rendering_stats_; }
-  void set_record_rendering_stats(bool record_rendering_stats) {
-    if (record_rendering_stats_ != record_rendering_stats)
-      record_rendering_stats_ = record_rendering_stats;
-  }
-
-  base::TimeDelta StartRecording() const;
-  base::TimeDelta EndRecording(base::TimeDelta start_time) const;
-
-  void IncrementFrameCount(int64 count);
-  void AddVisibleContentArea(int64 area);
-  void AddApproximatedVisibleContentArea(int64 area);
-  void AddDrawDuration(base::TimeDelta draw_duration,
-                       base::TimeDelta draw_duration_estimate);
-  void AddBeginMainFrameToCommitDuration(
-      base::TimeDelta begin_main_frame_to_commit_duration,
-      base::TimeDelta begin_main_frame_to_commit_duration_estimate);
-  void AddCommitToActivateDuration(
-      base::TimeDelta commit_to_activate_duration,
-      base::TimeDelta commit_to_activate_duration_estimate);
-
- protected:
-  RenderingStatsInstrumentation();
-
- private:
-  RenderingStats impl_thread_rendering_stats_;
-  RenderingStats impl_thread_rendering_stats_accu_;
-
-  bool record_rendering_stats_;
-
-  base::Lock lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(RenderingStatsInstrumentation);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_RENDERING_STATS_INSTRUMENTATION_H_
diff --git a/cc/debug/rendering_stats_unittest.cc b/cc/debug/rendering_stats_unittest.cc
deleted file mode 100644
index 6784e09..0000000
--- a/cc/debug/rendering_stats_unittest.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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.
-
-#include <string>
-
-#include "base/time/time.h"
-#include "base/values.h"
-#include "cc/debug/rendering_stats.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-static std::string ToString(const RenderingStats::TimeDeltaList& list) {
-  scoped_refptr<base::trace_event::TracedValue> value =
-      new base::trace_event::TracedValue();
-  list.AddToTracedValue("list_value", value.get());
-  return value->ToString();
-}
-
-TEST(RenderingStatsTest, TimeDeltaListEmpty) {
-  RenderingStats::TimeDeltaList time_delta_list;
-  EXPECT_EQ("{\"list_value\":[]}", ToString(time_delta_list));
-}
-
-TEST(RenderingStatsTest, TimeDeltaListNonEmpty) {
-  RenderingStats::TimeDeltaList time_delta_list;
-  time_delta_list.Append(base::TimeDelta::FromMilliseconds(234));
-  time_delta_list.Append(base::TimeDelta::FromMilliseconds(827));
-
-  EXPECT_EQ("{\"list_value\":[234.0,827.0]}", ToString(time_delta_list));
-}
-
-TEST(RenderingStatsTest, TimeDeltaListAdd) {
-  RenderingStats::TimeDeltaList time_delta_list_a;
-  time_delta_list_a.Append(base::TimeDelta::FromMilliseconds(810));
-  time_delta_list_a.Append(base::TimeDelta::FromMilliseconds(32));
-
-  RenderingStats::TimeDeltaList time_delta_list_b;
-  time_delta_list_b.Append(base::TimeDelta::FromMilliseconds(43));
-  time_delta_list_b.Append(base::TimeDelta::FromMilliseconds(938));
-  time_delta_list_b.Append(base::TimeDelta::FromMilliseconds(2));
-
-  time_delta_list_a.Add(time_delta_list_b);
-  EXPECT_EQ("{\"list_value\":[810.0,32.0,43.0,938.0,2.0]}",
-            ToString(time_delta_list_a));
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/debug/ring_buffer.h b/cc/debug/ring_buffer.h
deleted file mode 100644
index f9a6749..0000000
--- a/cc/debug/ring_buffer.h
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_DEBUG_RING_BUFFER_H_
-#define CC_DEBUG_RING_BUFFER_H_
-
-#include "base/logging.h"
-
-namespace cc {
-
-template<typename T, size_t kSize>
-class RingBuffer {
- public:
-  RingBuffer() : current_index_(0) {}
-
-  size_t BufferSize() const {
-    return kSize;
-  }
-
-  size_t CurrentIndex() const {
-    return current_index_;
-  }
-
-  // tests if a value was saved to this index
-  bool IsFilledIndex(size_t n) const {
-    return BufferIndex(n) < current_index_;
-  }
-
-  // n = 0 returns the oldest value and
-  // n = bufferSize() - 1 returns the most recent value.
-  const T& ReadBuffer(size_t n) const {
-    DCHECK(IsFilledIndex(n));
-    return buffer_[BufferIndex(n)];
-  }
-
-  T* MutableReadBuffer(size_t n) {
-    DCHECK(IsFilledIndex(n));
-    return &buffer_[BufferIndex(n)];
-  }
-
-  void SaveToBuffer(const T& value) {
-    buffer_[BufferIndex(0)] = value;
-    current_index_++;
-  }
-
-  void Clear() {
-    current_index_ = 0;
-  }
-
-  // Iterator has const access to the RingBuffer it got retrieved from.
-  class Iterator {
-   public:
-    size_t index() const { return index_; }
-
-    const T* operator->() const { return &buffer_.ReadBuffer(index_); }
-    const T* operator*() const { return &buffer_.ReadBuffer(index_); }
-
-    Iterator& operator++() {
-      index_++;
-      if (index_ == kSize)
-        out_of_range_ = true;
-      return *this;
-    }
-
-    Iterator& operator--() {
-      if (index_ == 0)
-        out_of_range_ = true;
-      index_--;
-      return *this;
-    }
-
-    operator bool() const {
-      return buffer_.IsFilledIndex(index_) && !out_of_range_;
-    }
-
-   private:
-    Iterator(const RingBuffer<T, kSize>& buffer, size_t index)
-      : buffer_(buffer),
-        index_(index),
-        out_of_range_(false) {
-    }
-
-    const RingBuffer<T, kSize>& buffer_;
-    size_t index_;
-    bool out_of_range_;
-
-    friend class RingBuffer<T, kSize>;
-  };
-
-  // Returns an Iterator pointing to the oldest value in the buffer.
-  // Example usage (iterate from oldest to newest value):
-  //  for (RingBuffer<T, kSize>::Iterator it = ring_buffer.Begin(); it; ++it) {}
-  Iterator Begin() const {
-    if (current_index_ < kSize)
-      return Iterator(*this, kSize - current_index_);
-    return Iterator(*this, 0);
-  }
-
-  // Returns an Iterator pointing to the newest value in the buffer.
-  // Example usage (iterate backwards from newest to oldest value):
-  //  for (RingBuffer<T, kSize>::Iterator it = ring_buffer.End(); it; --it) {}
-  Iterator End() const {
-    return Iterator(*this, kSize - 1);
-  }
-
- private:
-  inline size_t BufferIndex(size_t n) const {
-    return (current_index_ + n) % kSize;
-  }
-
-  T buffer_[kSize];
-  size_t current_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(RingBuffer);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_RING_BUFFER_H_
diff --git a/cc/debug/traced_value.cc b/cc/debug/traced_value.cc
deleted file mode 100644
index c2ac7f5..0000000
--- a/cc/debug/traced_value.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "cc/debug/traced_value.h"
-
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event_argument.h"
-
-namespace cc {
-
-void TracedValue::AppendIDRef(const void* id,
-                              base::trace_event::TracedValue* state) {
-  state->BeginDictionary();
-  state->SetString("id_ref", base::StringPrintf("%p", id));
-  state->EndDictionary();
-}
-
-void TracedValue::SetIDRef(const void* id,
-                           base::trace_event::TracedValue* state,
-                           const char* name) {
-  state->BeginDictionary(name);
-  state->SetString("id_ref", base::StringPrintf("%p", id));
-  state->EndDictionary();
-}
-
-void TracedValue::MakeDictIntoImplicitSnapshot(
-    base::trace_event::TracedValue* dict,
-    const char* object_name,
-    const void* id) {
-  dict->SetString("id", base::StringPrintf("%s/%p", object_name, id));
-}
-
-void TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
-    const char* category,
-    base::trace_event::TracedValue* dict,
-    const char* object_name,
-    const void* id) {
-  dict->SetString("cat", category);
-  MakeDictIntoImplicitSnapshot(dict, object_name, id);
-}
-
-void TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
-    const char* category,
-    base::trace_event::TracedValue* dict,
-    const char* object_base_type_name,
-    const char* object_name,
-    const void* id) {
-  dict->SetString("cat", category);
-  dict->SetString("base_type", object_base_type_name);
-  MakeDictIntoImplicitSnapshot(dict, object_name, id);
-}
-
-}  // namespace cc
diff --git a/cc/debug/traced_value.h b/cc/debug/traced_value.h
deleted file mode 100644
index 34e79a7..0000000
--- a/cc/debug/traced_value.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_DEBUG_TRACED_VALUE_H_
-#define CC_DEBUG_TRACED_VALUE_H_
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-}
-
-namespace cc {
-
-class TracedValue {
- public:
-  static void AppendIDRef(const void* id,
-                          base::trace_event::TracedValue* array);
-  static void SetIDRef(const void* id,
-                       base::trace_event::TracedValue* dict,
-                       const char* name);
-  static void MakeDictIntoImplicitSnapshot(base::trace_event::TracedValue* dict,
-                                           const char* object_name,
-                                           const void* id);
-  static void MakeDictIntoImplicitSnapshotWithCategory(
-      const char* category,
-      base::trace_event::TracedValue* dict,
-      const char* object_name,
-      const void* id);
-  static void MakeDictIntoImplicitSnapshotWithCategory(
-      const char* category,
-      base::trace_event::TracedValue* dict,
-      const char* object_base_type_name,
-      const char* object_name,
-      const void* id);
-};
-
-}  // namespace cc
-
-#endif  // CC_DEBUG_TRACED_VALUE_H_
diff --git a/cc/output/begin_frame_args.cc b/cc/output/begin_frame_args.cc
deleted file mode 100644
index 3663125..0000000
--- a/cc/output/begin_frame_args.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/begin_frame_args.h"
-
-#include "base/trace_event/trace_event_argument.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-
-const char* BeginFrameArgs::TypeToString(BeginFrameArgsType type) {
-  switch (type) {
-    case BeginFrameArgs::INVALID:
-      return "INVALID";
-    case BeginFrameArgs::NORMAL:
-      return "NORMAL";
-    case BeginFrameArgs::SYNCHRONOUS:
-      return "SYNCHRONOUS";
-    case BeginFrameArgs::MISSED:
-      return "MISSED";
-    case BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX:
-      return "BEGIN_FRAME_ARGS_TYPE_MAX";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-BeginFrameArgs::BeginFrameArgs()
-    : frame_time(base::TimeTicks()),
-      deadline(base::TimeTicks()),
-      interval(base::TimeDelta::FromMicroseconds(-1)),
-      type(BeginFrameArgs::INVALID) {
-}
-
-BeginFrameArgs::BeginFrameArgs(base::TimeTicks frame_time,
-                               base::TimeTicks deadline,
-                               base::TimeDelta interval,
-                               BeginFrameArgs::BeginFrameArgsType type)
-    : frame_time(frame_time),
-      deadline(deadline),
-      interval(interval),
-      type(type) {
-}
-
-BeginFrameArgs BeginFrameArgs::Create(BeginFrameArgs::CreationLocation location,
-                                      base::TimeTicks frame_time,
-                                      base::TimeTicks deadline,
-                                      base::TimeDelta interval,
-                                      BeginFrameArgs::BeginFrameArgsType type) {
-  DCHECK_NE(type, BeginFrameArgs::INVALID);
-  DCHECK_NE(type, BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX);
-#ifdef NDEBUG
-  return BeginFrameArgs(frame_time, deadline, interval, type);
-#else
-  BeginFrameArgs args = BeginFrameArgs(frame_time, deadline, interval, type);
-  args.created_from = location;
-  return args;
-#endif
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-BeginFrameArgs::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-void BeginFrameArgs::AsValueInto(base::trace_event::TracedValue* state) const {
-  state->SetString("type", "BeginFrameArgs");
-  state->SetString("subtype", TypeToString(type));
-  state->SetDouble("frame_time_us", frame_time.ToInternalValue());
-  state->SetDouble("deadline_us", deadline.ToInternalValue());
-  state->SetDouble("interval_us", interval.InMicroseconds());
-#ifndef NDEBUG
-  state->SetString("created_from", created_from.ToString());
-#endif
-}
-
-// This is a hard-coded deadline adjustment that assumes 60Hz, to be used in
-// cases where a good estimated draw time is not known. Using 1/3 of the vsync
-// as the default adjustment gives the Browser the last 1/3 of a frame to
-// produce output, the Renderer Impl thread the middle 1/3 of a frame to produce
-// ouput, and the Renderer Main thread the first 1/3 of a frame to produce
-// output.
-base::TimeDelta BeginFrameArgs::DefaultEstimatedParentDrawTime() {
-  return base::TimeDelta::FromMicroseconds(16666 / 3);
-}
-
-base::TimeDelta BeginFrameArgs::DefaultInterval() {
-  return base::TimeDelta::FromMicroseconds(16666);
-}
-
-}  // namespace cc
diff --git a/cc/output/begin_frame_args.h b/cc/output/begin_frame_args.h
deleted file mode 100644
index 60788f7..0000000
--- a/cc/output/begin_frame_args.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_BEGIN_FRAME_ARGS_H_
-#define CC_OUTPUT_BEGIN_FRAME_ARGS_H_
-
-#include "base/location.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-class TracedValue;
-}
-}
-
-/**
- * In debug builds we trace the creation origin of BeginFrameArgs objects. We
- * reuse the tracked_objects::Location system to do that.
- *
- * However, in release builds we don't want this as it doubles the size of the
- * BeginFrameArgs object. As well it adds a number of largish strings to the
- * binary. Despite the argument being unused, most compilers are unable to
- * optimise it away even when unused. Instead we use the BEGINFRAME_FROM_HERE
- * macro to prevent the data even getting referenced.
- */
-#ifdef NDEBUG
-#define BEGINFRAME_FROM_HERE nullptr
-#else
-#define BEGINFRAME_FROM_HERE FROM_HERE
-#endif
-
-namespace cc {
-
-struct BeginFrameArgs {
-  enum BeginFrameArgsType {
-    INVALID,
-    NORMAL,
-    SYNCHRONOUS,
-    MISSED,
-    // Not a real type, but used by the IPC system. Should always remain the
-    // *last* value in this enum.
-    BEGIN_FRAME_ARGS_TYPE_MAX,
-  };
-  static const char* TypeToString(BeginFrameArgsType type);
-
-  // Creates an invalid set of values.
-  BeginFrameArgs();
-
-#ifdef NDEBUG
-  typedef const void* CreationLocation;
-#else
-  typedef const tracked_objects::Location& CreationLocation;
-  tracked_objects::Location created_from;
-#endif
-
-  // You should be able to find all instances where a BeginFrame has been
-  // created by searching for "BeginFrameArgs::Create".
-  // The location argument should **always** be BEGINFRAME_FROM_HERE macro.
-  static BeginFrameArgs Create(CreationLocation location,
-                               base::TimeTicks frame_time,
-                               base::TimeTicks deadline,
-                               base::TimeDelta interval,
-                               BeginFrameArgsType type);
-
-  // This is the default delta that will be used to adjust the deadline when
-  // proper draw-time estimations are not yet available.
-  static base::TimeDelta DefaultEstimatedParentDrawTime();
-
-  // This is the default interval to use to avoid sprinkling the code with
-  // magic numbers.
-  static base::TimeDelta DefaultInterval();
-
-  bool IsValid() const { return interval >= base::TimeDelta(); }
-
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* dict) const;
-
-  base::TimeTicks frame_time;
-  base::TimeTicks deadline;
-  base::TimeDelta interval;
-  BeginFrameArgsType type;
-
- private:
-  BeginFrameArgs(base::TimeTicks frame_time,
-                 base::TimeTicks deadline,
-                 base::TimeDelta interval,
-                 BeginFrameArgsType type);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_BEGIN_FRAME_ARGS_H_
diff --git a/cc/output/begin_frame_args_unittest.cc b/cc/output/begin_frame_args_unittest.cc
deleted file mode 100644
index 877a857..0000000
--- a/cc/output/begin_frame_args_unittest.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 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.
-
-#include <string>
-
-#include "cc/output/begin_frame_args.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "testing/gtest/include/gtest/gtest-spi.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-namespace {
-
-TEST(BeginFrameArgsTest, Helpers) {
-  // Quick create methods work
-  BeginFrameArgs args0 = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
-  EXPECT_TRUE(args0.IsValid()) << args0;
-
-  BeginFrameArgs args1 =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 0, -1);
-  EXPECT_FALSE(args1.IsValid()) << args1;
-
-  BeginFrameArgs args2 =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 1, 2, 3);
-  EXPECT_TRUE(args2.IsValid()) << args2;
-  EXPECT_EQ(1, args2.frame_time.ToInternalValue());
-  EXPECT_EQ(2, args2.deadline.ToInternalValue());
-  EXPECT_EQ(3, args2.interval.ToInternalValue());
-  EXPECT_EQ(BeginFrameArgs::NORMAL, args2.type);
-
-  BeginFrameArgs args3 =
-      CreateExpiredBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE);
-  EXPECT_TRUE(args3.IsValid()) << args3;
-  EXPECT_GT(gfx::FrameTime::Now(), args3.deadline);
-  EXPECT_EQ(BeginFrameArgs::NORMAL, args3.type);
-
-  BeginFrameArgs args4 = CreateBeginFrameArgsForTesting(
-      BEGINFRAME_FROM_HERE, 1, 2, 3, BeginFrameArgs::MISSED);
-  EXPECT_TRUE(args4.IsValid()) << args4;
-  EXPECT_EQ(1, args4.frame_time.ToInternalValue());
-  EXPECT_EQ(2, args4.deadline.ToInternalValue());
-  EXPECT_EQ(3, args4.interval.ToInternalValue());
-  EXPECT_EQ(BeginFrameArgs::MISSED, args4.type);
-
-  // operator==
-  EXPECT_EQ(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 4, 5, 6),
-            CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 4, 5, 6));
-
-  EXPECT_NONFATAL_FAILURE(
-      EXPECT_EQ(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 7, 8, 9,
-                                               BeginFrameArgs::MISSED),
-                CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 7, 8, 9)),
-      "");
-
-  EXPECT_NONFATAL_FAILURE(
-      EXPECT_EQ(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 4, 5, 6),
-                CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 7, 8, 9)),
-      "");
-
-  // operator<<
-  std::stringstream out1;
-  out1 << args1;
-  EXPECT_EQ("BeginFrameArgs(NORMAL, 0, 0, -1us)", out1.str());
-  std::stringstream out2;
-  out2 << args2;
-  EXPECT_EQ("BeginFrameArgs(NORMAL, 1, 2, 3us)", out2.str());
-
-  // PrintTo
-  EXPECT_EQ(std::string("BeginFrameArgs(NORMAL, 0, 0, -1us)"),
-            ::testing::PrintToString(args1));
-  EXPECT_EQ(std::string("BeginFrameArgs(NORMAL, 1, 2, 3us)"),
-            ::testing::PrintToString(args2));
-}
-
-TEST(BeginFrameArgsTest, Create) {
-  // BeginFrames are not valid by default
-  BeginFrameArgs args1;
-  EXPECT_FALSE(args1.IsValid()) << args1;
-
-  BeginFrameArgs args2 = BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, base::TimeTicks::FromInternalValue(1),
-      base::TimeTicks::FromInternalValue(2),
-      base::TimeDelta::FromInternalValue(3), BeginFrameArgs::NORMAL);
-  EXPECT_TRUE(args2.IsValid()) << args2;
-  EXPECT_EQ(1, args2.frame_time.ToInternalValue()) << args2;
-  EXPECT_EQ(2, args2.deadline.ToInternalValue()) << args2;
-  EXPECT_EQ(3, args2.interval.ToInternalValue()) << args2;
-  EXPECT_EQ(BeginFrameArgs::NORMAL, args2.type) << args2;
-}
-
-#ifndef NDEBUG
-TEST(BeginFrameArgsTest, Location) {
-  tracked_objects::Location expected_location = BEGINFRAME_FROM_HERE;
-
-  BeginFrameArgs args = CreateBeginFrameArgsForTesting(expected_location);
-  EXPECT_EQ(expected_location.ToString(), args.created_from.ToString());
-}
-#endif
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/bsp_compare_result.h b/cc/output/bsp_compare_result.h
deleted file mode 100644
index cdd251f..0000000
--- a/cc/output/bsp_compare_result.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_BSP_COMPARE_RESULT_H_
-#define CC_OUTPUT_BSP_COMPARE_RESULT_H_
-
-namespace cc {
-
-enum BspCompareResult {
-  BSP_FRONT,
-  BSP_BACK,
-  BSP_SPLIT,
-  BSP_COPLANAR_FRONT,
-  BSP_COPLANAR_BACK,
-  BSP_COPLANAR,
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_BSP_COMPARE_RESULT_H_
diff --git a/cc/output/bsp_tree.cc b/cc/output/bsp_tree.cc
deleted file mode 100644
index 4eb87cb..0000000
--- a/cc/output/bsp_tree.cc
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/bsp_tree.h"
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/bsp_compare_result.h"
-#include "cc/quads/draw_polygon.h"
-
-namespace cc {
-
-BspNode::BspNode(scoped_ptr<DrawPolygon> data) : node_data(data.Pass()) {
-}
-
-BspNode::~BspNode() {
-}
-
-BspTree::BspTree(ScopedPtrDeque<DrawPolygon>* list) {
-  if (list->size() == 0)
-    return;
-
-  root_ = make_scoped_ptr(new BspNode(list->take_front()));
-  BuildTree(root_.get(), list);
-}
-
-// The idea behind using a deque for BuildTree's input is that we want to be
-// able to place polygons that we've decided aren't splitting plane candidates
-// at the back of the queue while moving the candidate splitting planes to the
-// front when the heuristic decides that they're a better choice. This way we
-// can always simply just take from the front of the deque for our node's
-// data.
-void BspTree::BuildTree(BspNode* node,
-                        ScopedPtrDeque<DrawPolygon>* polygon_list) {
-  ScopedPtrDeque<DrawPolygon> front_list;
-  ScopedPtrDeque<DrawPolygon> back_list;
-
-  // We take in a list of polygons at this level of the tree, and have to
-  // find a splitting plane, then classify polygons as either in front of
-  // or behind that splitting plane.
-  while (polygon_list->size() > 0) {
-    // Is this particular polygon in front of or behind our splitting polygon.
-    BspCompareResult comparer_result =
-        GetNodePositionRelative(*polygon_list->front(), *(node->node_data));
-
-    // If it's clearly behind or in front of the splitting plane, we use the
-    // heuristic to decide whether or not we should put it at the back
-    // or front of the list.
-    switch (comparer_result) {
-      case BSP_FRONT:
-        front_list.push_back(polygon_list->take_front().Pass());
-        break;
-      case BSP_BACK:
-        back_list.push_back(polygon_list->take_front().Pass());
-        break;
-      case BSP_SPLIT:
-      {
-        scoped_ptr<DrawPolygon> polygon;
-        scoped_ptr<DrawPolygon> new_front;
-        scoped_ptr<DrawPolygon> new_back;
-        // Time to split this geometry, *it needs to be split by node_data.
-        polygon = polygon_list->take_front();
-        bool split_result =
-            polygon->Split(*(node->node_data), &new_front, &new_back);
-        DCHECK(split_result);
-        if (!split_result) {
-          break;
-        }
-        front_list.push_back(new_front.Pass());
-        back_list.push_back(new_back.Pass());
-        break;
-      }
-      case BSP_COPLANAR_FRONT:
-        node->coplanars_front.push_back(polygon_list->take_front());
-        break;
-      case BSP_COPLANAR_BACK:
-        node->coplanars_back.push_back(polygon_list->take_front());
-        break;
-      default:
-        NOTREACHED();
-        break;
-    }
-  }
-
-  // Build the back subtree using the front of the back_list as our splitter.
-  if (back_list.size() > 0) {
-    node->back_child = make_scoped_ptr(new BspNode(back_list.take_front()));
-    BuildTree(node->back_child.get(), &back_list);
-  }
-
-  // Build the front subtree using the front of the front_list as our splitter.
-  if (front_list.size() > 0) {
-    node->front_child =
-        scoped_ptr<BspNode>(new BspNode(front_list.take_front()));
-    BuildTree(node->front_child.get(), &front_list);
-  }
-}
-
-BspCompareResult BspTree::GetNodePositionRelative(const DrawPolygon& node_a,
-                                                  const DrawPolygon& node_b) {
-  return DrawPolygon::SideCompare(node_a, node_b);
-}
-
-// The base comparer with 0,0,0 as camera position facing forward
-BspCompareResult BspTree::GetCameraPositionRelative(const DrawPolygon& node) {
-  if (node.normal().z() > 0.0f) {
-    return BSP_FRONT;
-  }
-  return BSP_BACK;
-}
-
-BspTree::~BspTree() {
-}
-
-}  // namespace cc
diff --git a/cc/output/bsp_tree.h b/cc/output/bsp_tree.h
deleted file mode 100644
index 7dceb8d..0000000
--- a/cc/output/bsp_tree.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_BSP_TREE_H_
-#define CC_OUTPUT_BSP_TREE_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/bsp_compare_result.h"
-#include "cc/quads/draw_polygon.h"
-
-namespace cc {
-
-struct BspNode {
-  // This represents the splitting plane.
-  scoped_ptr<DrawPolygon> node_data;
-  // This represents any coplanar geometry we found while building the BSP.
-  ScopedPtrVector<DrawPolygon> coplanars_front;
-  ScopedPtrVector<DrawPolygon> coplanars_back;
-
-  scoped_ptr<BspNode> back_child;
-  scoped_ptr<BspNode> front_child;
-
-  explicit BspNode(scoped_ptr<DrawPolygon> data);
-  ~BspNode();
-};
-
-class BspTree {
- public:
-  explicit BspTree(ScopedPtrDeque<DrawPolygon>* list);
-  scoped_ptr<BspNode>& root() { return root_; }
-
-  template <typename ActionHandlerType>
-  void TraverseWithActionHandler(ActionHandlerType* action_handler) const {
-    if (root_) {
-      WalkInOrderRecursion<ActionHandlerType>(action_handler, root_.get());
-    }
-  }
-
-  ~BspTree();
-
- private:
-  scoped_ptr<BspNode> root_;
-
-  void FromList(ScopedPtrVector<DrawPolygon>* list);
-  void BuildTree(BspNode* node, ScopedPtrDeque<DrawPolygon>* data);
-
-  template <typename ActionHandlerType>
-  void WalkInOrderAction(ActionHandlerType* action_handler,
-                         DrawPolygon* item) const {
-    (*action_handler)(item);
-  }
-
-  template <typename ActionHandlerType>
-  void WalkInOrderVisitNodes(
-      ActionHandlerType* action_handler,
-      const BspNode* node,
-      const BspNode* first_child,
-      const BspNode* second_child,
-      const ScopedPtrVector<DrawPolygon>& first_coplanars,
-      const ScopedPtrVector<DrawPolygon>& second_coplanars) const {
-    if (first_child) {
-      WalkInOrderRecursion(action_handler, first_child);
-    }
-    for (size_t i = 0; i < first_coplanars.size(); i++) {
-      WalkInOrderAction(action_handler, first_coplanars[i]);
-    }
-    WalkInOrderAction(action_handler, node->node_data.get());
-    for (size_t i = 0; i < second_coplanars.size(); i++) {
-      WalkInOrderAction(action_handler, second_coplanars[i]);
-    }
-    if (second_child) {
-      WalkInOrderRecursion(action_handler, second_child);
-    }
-  }
-
-  template <typename ActionHandlerType>
-  void WalkInOrderRecursion(ActionHandlerType* action_handler,
-                            const BspNode* node) const {
-    // If our view is in front of the the polygon
-    // in this node then walk back then front.
-    if (GetCameraPositionRelative(*(node->node_data)) == BSP_FRONT) {
-      WalkInOrderVisitNodes<ActionHandlerType>(action_handler,
-                                               node,
-                                               node->back_child.get(),
-                                               node->front_child.get(),
-                                               node->coplanars_front,
-                                               node->coplanars_back);
-    } else {
-      WalkInOrderVisitNodes<ActionHandlerType>(action_handler,
-                                               node,
-                                               node->front_child.get(),
-                                               node->back_child.get(),
-                                               node->coplanars_back,
-                                               node->coplanars_front);
-    }
-  }
-
-  // Returns whether or not nodeA is on one or the other side of nodeB,
-  // coplanar, or whether it crosses nodeB's plane and needs to be split
-  static BspCompareResult GetNodePositionRelative(const DrawPolygon& node_a,
-                                                  const DrawPolygon& node_b);
-  // Returns whether or not our viewer is in front of or behind the plane
-  // defined by this polygon/node
-  static BspCompareResult GetCameraPositionRelative(const DrawPolygon& node);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_BSP_TREE_H_
diff --git a/cc/output/bsp_tree_unittest.cc b/cc/output/bsp_tree_unittest.cc
deleted file mode 100644
index 100bc91..0000000
--- a/cc/output/bsp_tree_unittest.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/bsp_tree.h"
-#include "cc/output/bsp_walk_action.h"
-#include "cc/quads/draw_polygon.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-#define EXPECT_SORTED_LISTS_EQ(polygon_list, compare_list)        \
-  do {                                                            \
-    EXPECT_EQ(polygon_list.size(), compare_list.size());          \
-    for (unsigned int i = 0; i < polygon_list.size(); i++) {      \
-      EXPECT_EQ(polygon_list[i]->order_index(), compare_list[i]); \
-    }                                                             \
-  } while (false);
-
-#define INT_VECTOR_FROM_ARRAY(array) \
-  std::vector<int>(array, array + arraysize(array))
-
-#define CREATE_DRAW_POLYGON(vertex_vector, normal, polygon_id) \
-  new DrawPolygon(NULL, vertex_vector, normal, polygon_id)
-
-class BspTreeTest {
- public:
-  static void RunTest(ScopedPtrDeque<DrawPolygon>* test_polygons,
-                      const std::vector<int>& compare_list) {
-    BspTree bsp_tree(test_polygons);
-
-    std::vector<DrawPolygon*> sorted_list;
-    BspWalkActionToVector action_handler(&sorted_list);
-    bsp_tree.TraverseWithActionHandler(&action_handler);
-
-    EXPECT_SORTED_LISTS_EQ(sorted_list, compare_list);
-    EXPECT_TRUE(VerifySidedness(bsp_tree.root()));
-  }
-
-  static bool VerifySidedness(const scoped_ptr<BspNode>& node) {
-    // We check if both the front and back child nodes have geometry that is
-    // completely on the expected side of the current node.
-    bool front_ok = true;
-    bool back_ok = true;
-    if (node->back_child) {
-      // Make sure the back child lies entirely behind this node.
-      BspCompareResult result = DrawPolygon::SideCompare(
-          *(node->back_child->node_data), *(node->node_data));
-      if (result != BSP_BACK) {
-        return false;
-      }
-      back_ok = VerifySidedness(node->back_child);
-    }
-    // Make sure the front child lies entirely in front of this node.
-    if (node->front_child) {
-      BspCompareResult result = DrawPolygon::SideCompare(
-          *(node->front_child->node_data), *(node->node_data));
-      if (result != BSP_FRONT) {
-        return false;
-      }
-      front_ok = VerifySidedness(node->front_child);
-    }
-    if (!back_ok || !front_ok) {
-      return false;
-    }
-
-    // Now we need to make sure our coplanar geometry is all actually coplanar.
-    for (size_t i = 0; i < node->coplanars_front.size(); i++) {
-      BspCompareResult result = DrawPolygon::SideCompare(
-          *(node->coplanars_front[i]), *(node->node_data));
-      if (result != BSP_COPLANAR_FRONT) {
-        return false;
-      }
-    }
-    for (size_t i = 0; i < node->coplanars_back.size(); i++) {
-      BspCompareResult result = DrawPolygon::SideCompare(
-          *(node->coplanars_back[i]), *(node->node_data));
-      if (result != BSP_COPLANAR_BACK) {
-        return false;
-      }
-    }
-    return true;
-  }
-};
-
-// Simple standing quads all parallel with each other, causing no splits.
-TEST(BspTreeTest, NoSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(0.0f, 10.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 0.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(10.0f, 0.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(10.0f, 10.0f, -5.0f));
-  std::vector<gfx::Point3F> vertices_c;
-  vertices_c.push_back(gfx::Point3F(0.0f, 10.0f, 5.0f));
-  vertices_c.push_back(gfx::Point3F(0.0f, 0.0f, 5.0f));
-  vertices_c.push_back(gfx::Point3F(10.0f, 0.0f, 5.0f));
-  vertices_c.push_back(gfx::Point3F(10.0f, 10.0f, 5.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1));
-  scoped_ptr<DrawPolygon> polygon_c(
-      CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_a.Pass());
-  polygon_list.push_back(polygon_b.Pass());
-  polygon_list.push_back(polygon_c.Pass());
-
-  int compare_ids[] = {1, 0, 2};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-// Basic two polygon split, can be viewed as a + from above.
-TEST(BspTreeTest, BasicSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, 5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, 5.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_a.Pass());
-  polygon_list.push_back(polygon_b.Pass());
-
-  int compare_ids[] = {1, 0, 1};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-// Same as above with the second quad offset so it doesn't intersect. One quad
-// should be very clearly on one side of the other, and no splitting should
-// occur.
-TEST(BspTreeTest, QuadOffset) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -15.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -15.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -10.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -10.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_a.Pass());
-  polygon_list.push_back(polygon_b.Pass());
-
-  int compare_ids[] = {1, 0};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-// Same as above, but this time we change the order in which the quads are
-// inserted into the tree, causing one to actually cross the plane of the other
-// and cause a split.
-TEST(BspTreeTest, QuadOffsetSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -15.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -15.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -10.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -10.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_b.Pass());
-  polygon_list.push_back(polygon_a.Pass());
-
-  int compare_ids[] = {0, 1, 0};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-// In addition to what can be viewed as a + from above, another piece of
-// geometry is inserted to cut these pieces right in the middle, viewed as
-// a quad from overhead.
-TEST(BspTreeTest, ThreeWaySplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, 5.0f, 5.0f));
-  vertices_b.push_back(gfx::Point3F(0.0f, -5.0f, 5.0f));
-  std::vector<gfx::Point3F> vertices_c;
-  vertices_c.push_back(gfx::Point3F(-5.0f, 0.0f, -5.0f));
-  vertices_c.push_back(gfx::Point3F(-5.0f, 0.0f, 5.0f));
-  vertices_c.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f));
-  vertices_c.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1));
-  scoped_ptr<DrawPolygon> polygon_c(
-      CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 2));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_a.Pass());
-  polygon_list.push_back(polygon_b.Pass());
-  polygon_list.push_back(polygon_c.Pass());
-
-  int compare_ids[] = {2, 1, 2, 0, 2, 1, 2};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-// This test checks whether coplanar geometry, when inserted into the tree in
-// order, comes back in the same order as it should.
-TEST(BspTreeTest, Coplanar) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(-4.0f, -4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(-4.0f, 4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(4.0f, 4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(4.0f, -4.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_c;
-  vertices_c.push_back(gfx::Point3F(-3.0f, -3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(-3.0f, 3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(3.0f, 3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(3.0f, -3.0f, 0.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1));
-  scoped_ptr<DrawPolygon> polygon_c(
-      CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2));
-
-  scoped_ptr<DrawPolygon> polygon_d = polygon_a->CreateCopy();
-  scoped_ptr<DrawPolygon> polygon_e = polygon_b->CreateCopy();
-  scoped_ptr<DrawPolygon> polygon_f = polygon_c->CreateCopy();
-
-  {
-    ScopedPtrDeque<DrawPolygon> polygon_list;
-    polygon_list.push_back(polygon_a.Pass());
-    polygon_list.push_back(polygon_b.Pass());
-    polygon_list.push_back(polygon_c.Pass());
-
-    int compare_ids[] = {0, 1, 2};
-    std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-    BspTreeTest::RunTest(&polygon_list, compare_list);
-  }
-
-  // Now check a different order and ensure we get that back as well
-  {
-    ScopedPtrDeque<DrawPolygon> polygon_list;
-    polygon_list.push_back(polygon_f.Pass());
-    polygon_list.push_back(polygon_d.Pass());
-    polygon_list.push_back(polygon_e.Pass());
-
-    int compare_ids[] = {0, 1, 2};
-    std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-    BspTreeTest::RunTest(&polygon_list, compare_list);
-  }
-}
-
-// A bunch of coplanar geometry should end up sharing a single node, and
-// result in the final piece of geometry splitting into just two pieces on
-// either side of the shared plane.
-TEST(BspTreeTest, CoplanarSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(-5.0f, -5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(-5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, 5.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(5.0f, -5.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(-4.0f, -4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(-4.0f, 4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(4.0f, 4.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(4.0f, -4.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_c;
-  vertices_c.push_back(gfx::Point3F(-3.0f, -3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(-3.0f, 3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(3.0f, 3.0f, 0.0f));
-  vertices_c.push_back(gfx::Point3F(3.0f, -3.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_d;
-  vertices_d.push_back(gfx::Point3F(0.0f, -15.0f, -15.0f));
-  vertices_d.push_back(gfx::Point3F(0.0f, 15.0f, -15.0f));
-  vertices_d.push_back(gfx::Point3F(0.0f, 15.0f, 15.0f));
-  vertices_d.push_back(gfx::Point3F(0.0f, -15.0f, 15.0f));
-
-  scoped_ptr<DrawPolygon> polygon_a(
-      CREATE_DRAW_POLYGON(vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0));
-  scoped_ptr<DrawPolygon> polygon_b(
-      CREATE_DRAW_POLYGON(vertices_b, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 1));
-  scoped_ptr<DrawPolygon> polygon_c(
-      CREATE_DRAW_POLYGON(vertices_c, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 2));
-  scoped_ptr<DrawPolygon> polygon_d(
-      CREATE_DRAW_POLYGON(vertices_d, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 3));
-
-  ScopedPtrDeque<DrawPolygon> polygon_list;
-  polygon_list.push_back(polygon_a.Pass());
-  polygon_list.push_back(polygon_b.Pass());
-  polygon_list.push_back(polygon_c.Pass());
-  polygon_list.push_back(polygon_d.Pass());
-
-  int compare_ids[] = {3, 0, 1, 2, 3};
-  std::vector<int> compare_list = INT_VECTOR_FROM_ARRAY(compare_ids);
-  BspTreeTest::RunTest(&polygon_list, compare_list);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/bsp_walk_action.cc b/cc/output/bsp_walk_action.cc
deleted file mode 100644
index 9ffc299..0000000
--- a/cc/output/bsp_walk_action.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/bsp_walk_action.h"
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/quads/draw_polygon.h"
-#include "cc/quads/draw_quad.h"
-
-namespace cc {
-
-BspWalkActionDrawPolygon::BspWalkActionDrawPolygon(
-    DirectRenderer* renderer,
-    DirectRenderer::DrawingFrame* frame,
-    const gfx::Rect& render_pass_scissor,
-    bool using_scissor_as_optimization)
-    : renderer_(renderer),
-      frame_(frame),
-      render_pass_scissor_(render_pass_scissor),
-      using_scissor_as_optimization_(using_scissor_as_optimization) {
-}
-
-void BspWalkActionDrawPolygon::operator()(DrawPolygon* item) {
-  gfx::Transform inverse_transform;
-  bool invertible =
-      item->original_ref()->quadTransform().GetInverse(&inverse_transform);
-  DCHECK(invertible);
-  item->TransformToLayerSpace(inverse_transform);
-  renderer_->DoDrawPolygon(*item, frame_, render_pass_scissor_,
-                           using_scissor_as_optimization_);
-}
-
-BspWalkActionToVector::BspWalkActionToVector(std::vector<DrawPolygon*>* in_list)
-    : list_(in_list) {
-}
-
-void BspWalkActionToVector::operator()(DrawPolygon* item) {
-  list_->push_back(item);
-}
-
-}  // namespace cc
diff --git a/cc/output/bsp_walk_action.h b/cc/output/bsp_walk_action.h
deleted file mode 100644
index 9ffc6c7..0000000
--- a/cc/output/bsp_walk_action.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_BSP_WALK_ACTION_H_
-#define CC_OUTPUT_BSP_WALK_ACTION_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/quads/draw_polygon.h"
-
-namespace cc {
-
-class BspWalkAction {
- public:
-  virtual void operator()(DrawPolygon* item) = 0;
-};
-
-// The BspTree class takes ownership of all the DrawPolygons returned in list_
-// so the BspTree must be preserved while elements in that vector are in use.
-class BspWalkActionDrawPolygon : public BspWalkAction {
- public:
-  void operator()(DrawPolygon* item) override;
-
-  BspWalkActionDrawPolygon(DirectRenderer* renderer,
-                           DirectRenderer::DrawingFrame* frame,
-                           const gfx::Rect& render_pass_scissor,
-                           bool using_scissor_as_optimization);
-
- private:
-  DirectRenderer* renderer_;
-  DirectRenderer::DrawingFrame* frame_;
-  const gfx::Rect& render_pass_scissor_;
-  bool using_scissor_as_optimization_;
-};
-
-class BspWalkActionToVector : public BspWalkAction {
- public:
-  explicit BspWalkActionToVector(std::vector<DrawPolygon*>* in_list);
-  void operator()(DrawPolygon* item) override;
-
- private:
-  std::vector<DrawPolygon*>* list_;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_BSP_WALK_ACTION_H_
diff --git a/cc/output/compositor_frame.cc b/cc/output/compositor_frame.cc
deleted file mode 100644
index e6d713d..0000000
--- a/cc/output/compositor_frame.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/compositor_frame.h"
-
-namespace cc {
-
-CompositorFrame::CompositorFrame() {}
-
-CompositorFrame::~CompositorFrame() {}
-
-void CompositorFrame::AssignTo(CompositorFrame* target) {
-  target->delegated_frame_data = delegated_frame_data.Pass();
-  target->gl_frame_data = gl_frame_data.Pass();
-  target->software_frame_data = software_frame_data.Pass();
-  target->metadata = metadata;
-}
-
-}  // namespace cc
diff --git a/cc/output/compositor_frame.h b/cc/output/compositor_frame.h
deleted file mode 100644
index 0f925cb..0000000
--- a/cc/output/compositor_frame.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_COMPOSITOR_FRAME_H_
-#define CC_OUTPUT_COMPOSITOR_FRAME_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/output/gl_frame_data.h"
-#include "cc/output/software_frame_data.h"
-
-namespace cc {
-
-class CompositorFrame {
- public:
-  CompositorFrame();
-  ~CompositorFrame();
-
-  CompositorFrameMetadata metadata;
-  scoped_ptr<DelegatedFrameData> delegated_frame_data;
-  scoped_ptr<GLFrameData> gl_frame_data;
-  scoped_ptr<SoftwareFrameData> software_frame_data;
-
-  void AssignTo(CompositorFrame* target);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CompositorFrame);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_COMPOSITOR_FRAME_H_
diff --git a/cc/output/compositor_frame_ack.cc b/cc/output/compositor_frame_ack.cc
deleted file mode 100644
index feb0bac..0000000
--- a/cc/output/compositor_frame_ack.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/compositor_frame_ack.h"
-
-namespace cc {
-
-CompositorFrameAck::CompositorFrameAck()
-    : last_software_frame_id(0) {}
-
-CompositorFrameAck::~CompositorFrameAck() {}
-
-}  // namespace cc
diff --git a/cc/output/compositor_frame_ack.h b/cc/output/compositor_frame_ack.h
deleted file mode 100644
index 4fedc27..0000000
--- a/cc/output/compositor_frame_ack.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_COMPOSITOR_FRAME_ACK_H_
-#define CC_OUTPUT_COMPOSITOR_FRAME_ACK_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/gl_frame_data.h"
-#include "cc/resources/returned_resource.h"
-
-namespace cc {
-
-class CompositorFrameAck {
- public:
-  CompositorFrameAck();
-  ~CompositorFrameAck();
-
-  ReturnedResourceArray resources;
-  scoped_ptr<GLFrameData> gl_frame_data;
-  unsigned last_software_frame_id;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CompositorFrameAck);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_COMPOSITOR_FRAME_ACK_H_
diff --git a/cc/output/compositor_frame_metadata.cc b/cc/output/compositor_frame_metadata.cc
deleted file mode 100644
index dad78a0..0000000
--- a/cc/output/compositor_frame_metadata.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "cc/output/compositor_frame_metadata.h"
-
-namespace cc {
-
-CompositorFrameMetadata::CompositorFrameMetadata()
-    : device_scale_factor(0.f),
-      page_scale_factor(0.f),
-      min_page_scale_factor(0.f),
-      max_page_scale_factor(0.f),
-      root_overflow_x_hidden(false),
-      root_overflow_y_hidden(false) {
-}
-
-CompositorFrameMetadata::~CompositorFrameMetadata() {
-}
-
-}  // namespace cc
diff --git a/cc/output/compositor_frame_metadata.h b/cc/output/compositor_frame_metadata.h
deleted file mode 100644
index 9f6df95..0000000
--- a/cc/output/compositor_frame_metadata.h
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CC_OUTPUT_COMPOSITOR_FRAME_METADATA_H_
-#define CC_OUTPUT_COMPOSITOR_FRAME_METADATA_H_
-
-#include <vector>
-
-#include "ui/events/latency_info.h"
-#include "ui/gfx/geometry/size_f.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-
-namespace cc {
-
-class CompositorFrameMetadata {
- public:
-  CompositorFrameMetadata();
-  ~CompositorFrameMetadata();
-
-  // The device scale factor used to generate this compositor frame.
-  float device_scale_factor;
-
-  // Scroll offset and scale of the root layer. This can be used for tasks
-  // like positioning windowed plugins.
-  gfx::Vector2dF root_scroll_offset;
-  float page_scale_factor;
-
-  // These limits can be used together with the scroll/scale fields above to
-  // determine if scrolling/scaling in a particular direction is possible.
-  gfx::SizeF scrollable_viewport_size;
-  gfx::SizeF root_layer_size;
-  float min_page_scale_factor;
-  float max_page_scale_factor;
-  bool root_overflow_x_hidden;
-  bool root_overflow_y_hidden;
-
-  // Used to position the Android location top bar and page content, whose
-  // precise position is computed by the renderer compositor.
-  gfx::Vector2dF location_bar_offset;
-  gfx::Vector2dF location_bar_content_translation;
-
-  std::vector<ui::LatencyInfo> latency_info;
-
-  // A set of SurfaceSequences that this frame satisfies (always in the same
-  // namespace as the current Surface).
-  std::vector<uint32_t> satisfies_sequences;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_COMPOSITOR_FRAME_METADATA_H_
diff --git a/cc/output/context_provider.cc b/cc/output/context_provider.cc
deleted file mode 100644
index 23a8e2c..0000000
--- a/cc/output/context_provider.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/context_provider.h"
-
-#include <limits>
-
-namespace cc {
-
-ContextProvider::Capabilities::Capabilities()
-    : max_transfer_buffer_usage_bytes(std::numeric_limits<size_t>::max()) {}
-
-}  // namespace cc
diff --git a/cc/output/context_provider.h b/cc/output/context_provider.h
deleted file mode 100644
index 1e6c19f..0000000
--- a/cc/output/context_provider.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CC_OUTPUT_CONTEXT_PROVIDER_H_
-#define CC_OUTPUT_CONTEXT_PROVIDER_H_
-
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "gpu/command_buffer/common/capabilities.h"
-
-class GrContext;
-
-namespace base {
-class Lock;
-}
-
-namespace gpu {
-class ContextSupport;
-namespace gles2 { class GLES2Interface; }
-}
-
-namespace cc {
-struct ManagedMemoryPolicy;
-
-class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> {
- public:
-  // Bind the 3d context to the current thread. This should be called before
-  // accessing the contexts. Calling it more than once should have no effect.
-  // Once this function has been called, the class should only be accessed
-  // from the same thread.
-  virtual bool BindToCurrentThread() = 0;
-  virtual void DetachFromThread() {}
-
-  virtual gpu::gles2::GLES2Interface* ContextGL() = 0;
-  virtual gpu::ContextSupport* ContextSupport() = 0;
-  virtual class GrContext* GrContext() = 0;
-
-  struct Capabilities {
-    gpu::Capabilities gpu;
-    size_t max_transfer_buffer_usage_bytes;
-
-    Capabilities();
-  };
-
-  // Sets up a lock so this context can be used from multiple threads.
-  virtual void SetupLock() = 0;
-
-  // Returns the lock that should be held if using this context from multiple
-  // threads.
-  virtual base::Lock* GetLock() = 0;
-
-  // Returns the capabilities of the currently bound 3d context.
-  virtual Capabilities ContextCapabilities() = 0;
-
-  // Checks if the context is currently known to be lost.
-  virtual bool IsContextLost() = 0;
-
-  // Ask the provider to check if the contexts are valid or lost. If they are,
-  // this should invalidate the provider so that it can be replaced with a new
-  // one.
-  virtual void VerifyContexts() = 0;
-
-  // Delete all cached gpu resources.
-  virtual void DeleteCachedResources() = 0;
-
-  // A method to be called from the main thread that should return true if
-  // the context inside the provider is no longer valid.
-  virtual bool DestroyedOnMainThread() = 0;
-
-  // Sets a callback to be called when the context is lost. This should be
-  // called from the same thread that the context is bound to. To avoid races,
-  // it should be called before BindToCurrentThread(), or VerifyContexts()
-  // should be called after setting the callback.
-  typedef base::Closure LostContextCallback;
-  virtual void SetLostContextCallback(
-      const LostContextCallback& lost_context_callback) = 0;
-
-  // Sets a callback to be called when the memory policy changes. This should be
-  // called from the same thread that the context is bound to.
-  typedef base::Callback<void(const ManagedMemoryPolicy& policy)>
-      MemoryPolicyChangedCallback;
-  virtual void SetMemoryPolicyChangedCallback(
-      const MemoryPolicyChangedCallback& memory_policy_changed_callback) = 0;
-
- protected:
-  friend class base::RefCountedThreadSafe<ContextProvider>;
-  virtual ~ContextProvider() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_CONTEXT_PROVIDER_H_
diff --git a/cc/output/copy_output_request.cc b/cc/output/copy_output_request.cc
deleted file mode 100644
index 53257bf..0000000
--- a/cc/output/copy_output_request.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/copy_output_request.h"
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/resources/texture_mailbox.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-// static
-scoped_ptr<CopyOutputRequest> CopyOutputRequest::CreateRelayRequest(
-    const CopyOutputRequest& original_request,
-    const CopyOutputRequestCallback& result_callback) {
-  scoped_ptr<CopyOutputRequest> relay = CreateRequest(result_callback);
-  relay->force_bitmap_result_ = original_request.force_bitmap_result_;
-  relay->has_area_ = original_request.has_area_;
-  relay->area_ = original_request.area_;
-  relay->has_texture_mailbox_ = original_request.has_texture_mailbox_;
-  relay->texture_mailbox_ = original_request.texture_mailbox_;
-  return relay.Pass();
-}
-
-CopyOutputRequest::CopyOutputRequest() {}
-
-CopyOutputRequest::CopyOutputRequest(
-    bool force_bitmap_result,
-    const CopyOutputRequestCallback& result_callback)
-    : force_bitmap_result_(force_bitmap_result),
-      has_area_(false),
-      has_texture_mailbox_(false),
-      result_callback_(result_callback) {
-  DCHECK(!result_callback_.is_null());
-  TRACE_EVENT_ASYNC_BEGIN0("cc", "CopyOutputRequest", this);
-}
-
-CopyOutputRequest::~CopyOutputRequest() {
-  if (!result_callback_.is_null())
-    SendResult(CopyOutputResult::CreateEmptyResult().Pass());
-}
-
-void CopyOutputRequest::SendResult(scoped_ptr<CopyOutputResult> result) {
-  bool success = !result->IsEmpty();
-  base::ResetAndReturn(&result_callback_).Run(result.Pass());
-  TRACE_EVENT_ASYNC_END1("cc", "CopyOutputRequest", this, "success", success);
-}
-
-void CopyOutputRequest::SendEmptyResult() {
-  SendResult(CopyOutputResult::CreateEmptyResult().Pass());
-}
-
-void CopyOutputRequest::SendBitmapResult(scoped_ptr<SkBitmap> bitmap) {
-  SendResult(CopyOutputResult::CreateBitmapResult(bitmap.Pass()).Pass());
-}
-
-void CopyOutputRequest::SendTextureResult(
-    const gfx::Size& size,
-    const TextureMailbox& texture_mailbox,
-    scoped_ptr<SingleReleaseCallback> release_callback) {
-  DCHECK(texture_mailbox.IsTexture());
-  SendResult(CopyOutputResult::CreateTextureResult(
-      size, texture_mailbox, release_callback.Pass()));
-}
-
-void CopyOutputRequest::SetTextureMailbox(
-    const TextureMailbox& texture_mailbox) {
-  DCHECK(!force_bitmap_result_);
-  DCHECK(texture_mailbox.IsTexture());
-  has_texture_mailbox_ = true;
-  texture_mailbox_ = texture_mailbox;
-}
-
-}  // namespace cc
diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h
deleted file mode 100644
index c2a737f..0000000
--- a/cc/output/copy_output_request.h
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_COPY_OUTPUT_REQUEST_H_
-#define CC_OUTPUT_COPY_OUTPUT_REQUEST_H_
-
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/single_release_callback.h"
-#include "cc/resources/texture_mailbox.h"
-#include "ui/gfx/geometry/rect.h"
-
-class SkBitmap;
-
-namespace cc {
-class CopyOutputResult;
-
-class CopyOutputRequest {
- public:
-  typedef base::Callback<void(scoped_ptr<CopyOutputResult> result)>
-      CopyOutputRequestCallback;
-
-  static scoped_ptr<CopyOutputRequest> CreateEmptyRequest() {
-    return make_scoped_ptr(new CopyOutputRequest);
-  }
-  static scoped_ptr<CopyOutputRequest> CreateRequest(
-      const CopyOutputRequestCallback& result_callback) {
-    return make_scoped_ptr(new CopyOutputRequest(false, result_callback));
-  }
-  static scoped_ptr<CopyOutputRequest> CreateBitmapRequest(
-      const CopyOutputRequestCallback& result_callback) {
-    return make_scoped_ptr(new CopyOutputRequest(true, result_callback));
-  }
-  static scoped_ptr<CopyOutputRequest> CreateRelayRequest(
-      const CopyOutputRequest& original_request,
-      const CopyOutputRequestCallback& result_callback);
-
-  ~CopyOutputRequest();
-
-  bool IsEmpty() const { return result_callback_.is_null(); }
-
-  bool force_bitmap_result() const { return force_bitmap_result_; }
-
-  // By default copy requests copy the entire layer's subtree output. If an
-  // area is given, then the intersection of this rect (in layer space) with
-  // the layer's subtree output will be returned.
-  void set_area(const gfx::Rect& area) {
-    has_area_ = true;
-    area_ = area;
-  }
-  bool has_area() const { return has_area_; }
-  gfx::Rect area() const { return area_; }
-
-  // By default copy requests create a new TextureMailbox to return contents
-  // in. This allows a client to provide a TextureMailbox, and the compositor
-  // will place the result inside the TextureMailbox.
-  void SetTextureMailbox(const TextureMailbox& texture_mailbox);
-  bool has_texture_mailbox() const { return has_texture_mailbox_; }
-  const TextureMailbox& texture_mailbox() const { return texture_mailbox_; }
-
-  void SendEmptyResult();
-  void SendBitmapResult(scoped_ptr<SkBitmap> bitmap);
-  void SendTextureResult(const gfx::Size& size,
-                         const TextureMailbox& texture_mailbox,
-                         scoped_ptr<SingleReleaseCallback> release_callback);
-
-  void SendResult(scoped_ptr<CopyOutputResult> result);
-
- private:
-  CopyOutputRequest();
-  CopyOutputRequest(bool force_bitmap_result,
-                    const CopyOutputRequestCallback& result_callback);
-
-  bool force_bitmap_result_;
-  bool has_area_;
-  bool has_texture_mailbox_;
-  gfx::Rect area_;
-  TextureMailbox texture_mailbox_;
-  CopyOutputRequestCallback result_callback_;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_COPY_OUTPUT_REQUEST_H_
diff --git a/cc/output/copy_output_result.cc b/cc/output/copy_output_result.cc
deleted file mode 100644
index 8dee046..0000000
--- a/cc/output/copy_output_result.cc
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/copy_output_result.h"
-
-#include "base/logging.h"
-#include "cc/resources/texture_mailbox.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-CopyOutputResult::CopyOutputResult() {}
-
-CopyOutputResult::CopyOutputResult(scoped_ptr<SkBitmap> bitmap)
-    : size_(bitmap->width(), bitmap->height()),
-      bitmap_(bitmap.Pass()) {
-  DCHECK(bitmap_);
-}
-
-CopyOutputResult::CopyOutputResult(
-    const gfx::Size& size,
-    const TextureMailbox& texture_mailbox,
-    scoped_ptr<SingleReleaseCallback> release_callback)
-    : size_(size),
-      texture_mailbox_(texture_mailbox),
-      release_callback_(release_callback.Pass()) {
-  DCHECK(texture_mailbox_.IsTexture());
-}
-
-CopyOutputResult::~CopyOutputResult() {
-  if (release_callback_)
-    release_callback_->Run(0, false);
-}
-
-scoped_ptr<SkBitmap> CopyOutputResult::TakeBitmap() {
-  return bitmap_.Pass();
-}
-
-void CopyOutputResult::TakeTexture(
-    TextureMailbox* texture_mailbox,
-    scoped_ptr<SingleReleaseCallback>* release_callback) {
-  *texture_mailbox = texture_mailbox_;
-  *release_callback = release_callback_.Pass();
-
-  texture_mailbox_ = TextureMailbox();
-}
-
-}  // namespace cc
diff --git a/cc/output/copy_output_result.h b/cc/output/copy_output_result.h
deleted file mode 100644
index 7d4a5bb..0000000
--- a/cc/output/copy_output_result.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_COPY_OUTPUT_RESULT_H_
-#define CC_OUTPUT_COPY_OUTPUT_RESULT_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/single_release_callback.h"
-#include "cc/resources/texture_mailbox.h"
-#include "ui/gfx/geometry/size.h"
-
-class SkBitmap;
-
-namespace cc {
-class TextureMailbox;
-
-class CopyOutputResult {
- public:
-  static scoped_ptr<CopyOutputResult> CreateEmptyResult() {
-    return make_scoped_ptr(new CopyOutputResult);
-  }
-  static scoped_ptr<CopyOutputResult> CreateBitmapResult(
-      scoped_ptr<SkBitmap> bitmap) {
-    return make_scoped_ptr(new CopyOutputResult(bitmap.Pass()));
-  }
-  static scoped_ptr<CopyOutputResult> CreateTextureResult(
-      const gfx::Size& size,
-      const TextureMailbox& texture_mailbox,
-      scoped_ptr<SingleReleaseCallback> release_callback) {
-    return make_scoped_ptr(
-        new CopyOutputResult(size, texture_mailbox, release_callback.Pass()));
-  }
-
-  ~CopyOutputResult();
-
-  bool IsEmpty() const { return !HasBitmap() && !HasTexture(); }
-  bool HasBitmap() const { return !!bitmap_; }
-  bool HasTexture() const { return texture_mailbox_.IsValid(); }
-
-  gfx::Size size() const { return size_; }
-  scoped_ptr<SkBitmap> TakeBitmap();
-  void TakeTexture(TextureMailbox* texture_mailbox,
-                   scoped_ptr<SingleReleaseCallback>* release_callback);
-
- private:
-  CopyOutputResult();
-  explicit CopyOutputResult(scoped_ptr<SkBitmap> bitmap);
-  explicit CopyOutputResult(const gfx::Size& size,
-                            const TextureMailbox& texture_mailbox,
-                            scoped_ptr<SingleReleaseCallback> release_callback);
-
-  gfx::Size size_;
-  scoped_ptr<SkBitmap> bitmap_;
-  TextureMailbox texture_mailbox_;
-  scoped_ptr<SingleReleaseCallback> release_callback_;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_COPY_OUTPUT_RESULT_H_
diff --git a/cc/output/delegated_frame_data.cc b/cc/output/delegated_frame_data.cc
deleted file mode 100644
index 94ff51d..0000000
--- a/cc/output/delegated_frame_data.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/delegated_frame_data.h"
-
-namespace cc {
-
-DelegatedFrameData::DelegatedFrameData() : device_scale_factor(1.0f) {
-}
-
-DelegatedFrameData::~DelegatedFrameData() {}
-
-}  // namespace cc
diff --git a/cc/output/delegated_frame_data.h b/cc/output/delegated_frame_data.h
deleted file mode 100644
index 2fe3d91..0000000
--- a/cc/output/delegated_frame_data.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_DELEGATED_FRAME_DATA_H_
-#define CC_OUTPUT_DELEGATED_FRAME_DATA_H_
-
-#include "cc/quads/render_pass.h"
-#include "cc/resources/transferable_resource.h"
-
-namespace cc {
-
-class DelegatedFrameData {
- public:
-  DelegatedFrameData();
-  ~DelegatedFrameData();
-
-  // The device scale factor used when generating this frame.
-  float device_scale_factor;
-
-  TransferableResourceArray resource_list;
-  RenderPassList render_pass_list;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DelegatedFrameData);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_DELEGATED_FRAME_DATA_H_
diff --git a/cc/output/delegating_renderer.cc b/cc/output/delegating_renderer.cc
deleted file mode 100644
index 0944ef4..0000000
--- a/cc/output/delegating_renderer.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/delegating_renderer.h"
-
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/trace_event/trace_event.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/output/context_provider.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass.h"
-#include "cc/resources/resource_provider.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-
-
-namespace cc {
-
-scoped_ptr<DelegatingRenderer> DelegatingRenderer::Create(
-    RendererClient* client,
-    const RendererSettings* settings,
-    OutputSurface* output_surface,
-    ResourceProvider* resource_provider) {
-  return make_scoped_ptr(new DelegatingRenderer(
-      client, settings, output_surface, resource_provider));
-}
-
-DelegatingRenderer::DelegatingRenderer(RendererClient* client,
-                                       const RendererSettings* settings,
-                                       OutputSurface* output_surface,
-                                       ResourceProvider* resource_provider)
-    : Renderer(client, settings),
-      output_surface_(output_surface),
-      resource_provider_(resource_provider) {
-  DCHECK(resource_provider_);
-
-  capabilities_.using_partial_swap = false;
-  capabilities_.max_texture_size = resource_provider_->max_texture_size();
-  capabilities_.best_texture_format = resource_provider_->best_texture_format();
-  capabilities_.allow_partial_texture_updates =
-      output_surface->capabilities().can_force_reclaim_resources;
-
-  if (!output_surface_->context_provider()) {
-    capabilities_.using_shared_memory_resources = true;
-  } else {
-    const ContextProvider::Capabilities& caps =
-        output_surface_->context_provider()->ContextCapabilities();
-
-    DCHECK(!caps.gpu.iosurface || caps.gpu.texture_rectangle);
-
-    capabilities_.using_egl_image = caps.gpu.egl_image_external;
-    capabilities_.using_image = caps.gpu.image;
-
-    capabilities_.allow_rasterize_on_demand = false;
-  }
-}
-
-DelegatingRenderer::~DelegatingRenderer() {}
-
-const RendererCapabilitiesImpl& DelegatingRenderer::Capabilities() const {
-  return capabilities_;
-}
-
-static ResourceProvider::ResourceId AppendToArray(
-    ResourceProvider::ResourceIdArray* array,
-    ResourceProvider::ResourceId id) {
-  array->push_back(id);
-  return id;
-}
-
-void DelegatingRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
-                                   float device_scale_factor,
-                                   const gfx::Rect& device_viewport_rect,
-                                   const gfx::Rect& device_clip_rect,
-                                   bool disable_picture_quad_image_filtering) {
-  TRACE_EVENT0("cc", "DelegatingRenderer::DrawFrame");
-
-  DCHECK(!delegated_frame_data_);
-
-  delegated_frame_data_ = make_scoped_ptr(new DelegatedFrameData);
-  DelegatedFrameData& out_data = *delegated_frame_data_;
-  out_data.device_scale_factor = device_scale_factor;
-  // Move the render passes and resources into the |out_frame|.
-  out_data.render_pass_list.swap(*render_passes_in_draw_order);
-
-  // Collect all resource ids in the render passes into a ResourceIdArray.
-  ResourceProvider::ResourceIdArray resources;
-  DrawQuad::ResourceIteratorCallback append_to_array =
-      base::Bind(&AppendToArray, &resources);
-  for (const auto& render_pass : out_data.render_pass_list) {
-    for (const auto& quad : render_pass->quad_list)
-      quad->IterateResources(append_to_array);
-  }
-  resource_provider_->PrepareSendToParent(resources, &out_data.resource_list);
-}
-
-void DelegatingRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
-  TRACE_EVENT0("cc,benchmark", "DelegatingRenderer::SwapBuffers");
-  CompositorFrame compositor_frame;
-  compositor_frame.metadata = metadata;
-  compositor_frame.delegated_frame_data = delegated_frame_data_.Pass();
-  output_surface_->SwapBuffers(&compositor_frame);
-}
-
-void DelegatingRenderer::ReceiveSwapBuffersAck(
-    const CompositorFrameAck& ack) {
-  resource_provider_->ReceiveReturnsFromParent(ack.resources);
-}
-
-void DelegatingRenderer::DidChangeVisibility() {
-  ContextProvider* context_provider = output_surface_->context_provider();
-  if (!visible()) {
-    TRACE_EVENT0("cc", "DelegatingRenderer::SetVisible dropping resources");
-    resource_provider_->ReleaseCachedData();
-    if (context_provider) {
-      context_provider->DeleteCachedResources();
-      context_provider->ContextGL()->Flush();
-    }
-  }
-  // We loop visibility to the GPU process, since that's what manages memory.
-  // That will allow it to feed us with memory allocations that we can act
-  // upon.
-  if (context_provider)
-    context_provider->ContextSupport()->SetSurfaceVisible(visible());
-}
-
-}  // namespace cc
diff --git a/cc/output/delegating_renderer.h b/cc/output/delegating_renderer.h
deleted file mode 100644
index f15638c..0000000
--- a/cc/output/delegating_renderer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_DELEGATING_RENDERER_H_
-#define CC_OUTPUT_DELEGATING_RENDERER_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/renderer.h"
-
-namespace cc {
-
-class OutputSurface;
-class ResourceProvider;
-
-class DelegatingRenderer : public Renderer {
- public:
-  static scoped_ptr<DelegatingRenderer> Create(
-      RendererClient* client,
-      const RendererSettings* settings,
-      OutputSurface* output_surface,
-      ResourceProvider* resource_provider);
-  ~DelegatingRenderer() override;
-
-  const RendererCapabilitiesImpl& Capabilities() const override;
-
-  void DrawFrame(RenderPassList* render_passes_in_draw_order,
-                 float device_scale_factor,
-                 const gfx::Rect& device_viewport_rect,
-                 const gfx::Rect& device_clip_rect,
-                 bool disable_picture_quad_image_filtering) override;
-
-  void Finish() override {}
-
-  void SwapBuffers(const CompositorFrameMetadata& metadata) override;
-  void ReceiveSwapBuffersAck(const CompositorFrameAck&) override;
-
- private:
-  DelegatingRenderer(RendererClient* client,
-                     const RendererSettings* settings,
-                     OutputSurface* output_surface,
-                     ResourceProvider* resource_provider);
-
-  void DidChangeVisibility() override;
-
-  OutputSurface* output_surface_;
-  ResourceProvider* resource_provider_;
-  RendererCapabilitiesImpl capabilities_;
-  scoped_ptr<DelegatedFrameData> delegated_frame_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(DelegatingRenderer);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_DELEGATING_RENDERER_H_
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
deleted file mode 100644
index 3238d2d..0000000
--- a/cc/output/delegating_renderer_unittest.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/delegating_renderer.h"
-
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/layer_tree_test.h"
-#include "cc/test/render_pass_test_common.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-class DelegatingRendererTest : public LayerTreeTest {
- public:
-  DelegatingRendererTest() : LayerTreeTest(), output_surface_(NULL) {}
-  ~DelegatingRendererTest() override {}
-
-  scoped_ptr<OutputSurface> CreateOutputSurface() override {
-    scoped_ptr<FakeOutputSurface> output_surface =
-        FakeOutputSurface::CreateDelegating3d();
-    output_surface_ = output_surface.get();
-    return output_surface.Pass();
-  }
-
- protected:
-  TestWebGraphicsContext3D* context3d_;
-  FakeOutputSurface* output_surface_;
-};
-
-class DelegatingRendererTestDraw : public DelegatingRendererTest {
- public:
-  void BeginTest() override {
-    layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.5f, 4.f);
-    PostSetNeedsCommitToMainThread();
-  }
-
-  void AfterTest() override {}
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame,
-                                   DrawResult draw_result) override {
-    EXPECT_EQ(0u, output_surface_->num_sent_frames());
-
-    const CompositorFrame& last_frame = output_surface_->last_sent_frame();
-    EXPECT_FALSE(last_frame.delegated_frame_data);
-    EXPECT_FALSE(last_frame.gl_frame_data);
-    EXPECT_EQ(0.f, last_frame.metadata.min_page_scale_factor);
-    EXPECT_EQ(0.f, last_frame.metadata.max_page_scale_factor);
-    return DRAW_SUCCESS;
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_EQ(0u, output_surface_->num_sent_frames());
-  }
-
-  void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
-    EXPECT_TRUE(result);
-    EXPECT_EQ(1u, output_surface_->num_sent_frames());
-
-    const CompositorFrame& last_frame = output_surface_->last_sent_frame();
-    DelegatedFrameData* last_frame_data = last_frame.delegated_frame_data.get();
-    ASSERT_TRUE(last_frame.delegated_frame_data);
-    EXPECT_FALSE(last_frame.gl_frame_data);
-    EXPECT_EQ(host_impl->DeviceViewport().ToString(),
-              last_frame_data->render_pass_list.back()->output_rect.ToString());
-    EXPECT_EQ(0.5f, last_frame.metadata.min_page_scale_factor);
-    EXPECT_EQ(4.f, last_frame.metadata.max_page_scale_factor);
-
-    EXPECT_EQ(
-        0u, last_frame.delegated_frame_data->resource_list.size());
-    EXPECT_EQ(1u, last_frame.delegated_frame_data->render_pass_list.size());
-
-    EndTest();
-  }
-};
-
-SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(DelegatingRendererTestDraw);
-
-class DelegatingRendererTestResources : public DelegatingRendererTest {
- public:
-  void BeginTest() override { PostSetNeedsCommitToMainThread(); }
-
-  void AfterTest() override {}
-
-  DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl,
-                                   LayerTreeHostImpl::FrameData* frame,
-                                   DrawResult draw_result) override {
-    frame->render_passes.clear();
-    frame->render_passes_by_id.clear();
-
-    TestRenderPass* child_pass = AddRenderPass(&frame->render_passes,
-                                               RenderPassId(2, 1),
-                                               gfx::Rect(3, 3, 10, 10),
-                                               gfx::Transform());
-    child_pass->AppendOneOfEveryQuadType(host_impl->resource_provider(),
-                                         RenderPassId(0, 0));
-
-    TestRenderPass* pass = AddRenderPass(&frame->render_passes,
-                                         RenderPassId(1, 1),
-                                         gfx::Rect(3, 3, 10, 10),
-                                         gfx::Transform());
-    pass->AppendOneOfEveryQuadType(
-        host_impl->resource_provider(), child_pass->id);
-    return draw_result;
-  }
-
-  void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override {
-    EXPECT_EQ(0u, output_surface_->num_sent_frames());
-  }
-
-  void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, bool result) override {
-    EXPECT_TRUE(result);
-    EXPECT_EQ(1u, output_surface_->num_sent_frames());
-
-    const CompositorFrame& last_frame = output_surface_->last_sent_frame();
-    ASSERT_TRUE(last_frame.delegated_frame_data);
-
-    EXPECT_EQ(2u, last_frame.delegated_frame_data->render_pass_list.size());
-    // Each render pass has 11 resources in it. And the root render pass has a
-    // mask resource used when drawing the child render pass, as well as its
-    // replica (it's added twice). The number 11 may change if
-    // AppendOneOfEveryQuadType() is updated, and the value here should be
-    // updated accordingly.
-    EXPECT_EQ(24u, last_frame.delegated_frame_data->resource_list.size());
-
-    EndTest();
-  }
-};
-
-SINGLE_AND_MULTI_THREAD_DELEGATING_RENDERER_TEST_F(
-    DelegatingRendererTestResources);
-
-}  // namespace cc
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
deleted file mode 100644
index df2b73a..0000000
--- a/cc/output/direct_renderer.cc
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/direct_renderer.h"
-
-#include <utility>
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/metrics/histogram.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/math_util.h"
-#include "cc/output/bsp_tree.h"
-#include "cc/output/bsp_walk_action.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/quads/draw_quad.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
-
-static gfx::Transform OrthoProjectionMatrix(float left,
-                                            float right,
-                                            float bottom,
-                                            float top) {
-  // Use the standard formula to map the clipping frustum to the cube from
-  // [-1, -1, -1] to [1, 1, 1].
-  float delta_x = right - left;
-  float delta_y = top - bottom;
-  gfx::Transform proj;
-  if (!delta_x || !delta_y)
-    return proj;
-  proj.matrix().set(0, 0, 2.0f / delta_x);
-  proj.matrix().set(0, 3, -(right + left) / delta_x);
-  proj.matrix().set(1, 1, 2.0f / delta_y);
-  proj.matrix().set(1, 3, -(top + bottom) / delta_y);
-
-  // Z component of vertices is always set to zero as we don't use the depth
-  // buffer while drawing.
-  proj.matrix().set(2, 2, 0);
-
-  return proj;
-}
-
-static gfx::Transform window_matrix(int x, int y, int width, int height) {
-  gfx::Transform canvas;
-
-  // Map to window position and scale up to pixel coordinates.
-  canvas.Translate3d(x, y, 0);
-  canvas.Scale3d(width, height, 0);
-
-  // Map from ([-1, -1] to [1, 1]) -> ([0, 0] to [1, 1])
-  canvas.Translate3d(0.5, 0.5, 0.5);
-  canvas.Scale3d(0.5, 0.5, 0.5);
-
-  return canvas;
-}
-
-namespace cc {
-
-DirectRenderer::DrawingFrame::DrawingFrame()
-    : root_render_pass(NULL), current_render_pass(NULL), current_texture(NULL) {
-}
-
-DirectRenderer::DrawingFrame::~DrawingFrame() {}
-
-//
-// static
-gfx::RectF DirectRenderer::QuadVertexRect() {
-  return gfx::RectF(-0.5f, -0.5f, 1.f, 1.f);
-}
-
-// static
-void DirectRenderer::QuadRectTransform(gfx::Transform* quad_rect_transform,
-                                       const gfx::Transform& quad_transform,
-                                       const gfx::RectF& quad_rect) {
-  *quad_rect_transform = quad_transform;
-  quad_rect_transform->Translate(0.5 * quad_rect.width() + quad_rect.x(),
-                                 0.5 * quad_rect.height() + quad_rect.y());
-  quad_rect_transform->Scale(quad_rect.width(), quad_rect.height());
-}
-
-void DirectRenderer::InitializeViewport(DrawingFrame* frame,
-                                        const gfx::Rect& draw_rect,
-                                        const gfx::Rect& viewport_rect,
-                                        const gfx::Size& surface_size) {
-  DCHECK_GE(viewport_rect.x(), 0);
-  DCHECK_GE(viewport_rect.y(), 0);
-  DCHECK_LE(viewport_rect.right(), surface_size.width());
-  DCHECK_LE(viewport_rect.bottom(), surface_size.height());
-  bool flip_y = FlippedFramebuffer(frame);
-  if (flip_y) {
-    frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(),
-                                                     draw_rect.right(),
-                                                     draw_rect.bottom(),
-                                                     draw_rect.y());
-  } else {
-    frame->projection_matrix = OrthoProjectionMatrix(draw_rect.x(),
-                                                     draw_rect.right(),
-                                                     draw_rect.y(),
-                                                     draw_rect.bottom());
-  }
-
-  gfx::Rect window_rect = viewport_rect;
-  if (flip_y)
-    window_rect.set_y(surface_size.height() - viewport_rect.bottom());
-  frame->window_matrix = window_matrix(window_rect.x(),
-                                       window_rect.y(),
-                                       window_rect.width(),
-                                       window_rect.height());
-  SetDrawViewport(window_rect);
-
-  current_draw_rect_ = draw_rect;
-  current_viewport_rect_ = viewport_rect;
-  current_surface_size_ = surface_size;
-}
-
-gfx::Rect DirectRenderer::MoveFromDrawToWindowSpace(
-    const DrawingFrame* frame,
-    const gfx::Rect& draw_rect) const {
-  gfx::Rect window_rect = draw_rect;
-  window_rect -= current_draw_rect_.OffsetFromOrigin();
-  window_rect += current_viewport_rect_.OffsetFromOrigin();
-  if (FlippedFramebuffer(frame))
-    window_rect.set_y(current_surface_size_.height() - window_rect.bottom());
-  return window_rect;
-}
-
-DirectRenderer::DirectRenderer(RendererClient* client,
-                               const RendererSettings* settings,
-                               OutputSurface* output_surface,
-                               ResourceProvider* resource_provider)
-    : Renderer(client, settings),
-      output_surface_(output_surface),
-      resource_provider_(resource_provider),
-      overlay_processor_(
-          new OverlayProcessor(output_surface, resource_provider)) {
-  overlay_processor_->Initialize();
-}
-
-DirectRenderer::~DirectRenderer() {}
-
-void DirectRenderer::SetEnlargePassTextureAmountForTesting(
-    const gfx::Vector2d& amount) {
-  enlarge_pass_texture_amount_ = amount;
-}
-
-void DirectRenderer::DecideRenderPassAllocationsForFrame(
-    const RenderPassList& render_passes_in_draw_order) {
-  if (!resource_provider_)
-    return;
-
-  base::hash_map<RenderPassId, gfx::Size> render_passes_in_frame;
-  for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i)
-    render_passes_in_frame.insert(std::pair<RenderPassId, gfx::Size>(
-        render_passes_in_draw_order[i]->id,
-        RenderPassTextureSize(render_passes_in_draw_order[i])));
-
-  std::vector<RenderPassId> passes_to_delete;
-  base::ScopedPtrHashMap<RenderPassId, scoped_ptr<ScopedResource>>::const_iterator
-      pass_iter;
-  for (pass_iter = render_pass_textures_.begin();
-       pass_iter != render_pass_textures_.end();
-       ++pass_iter) {
-    base::hash_map<RenderPassId, gfx::Size>::const_iterator it =
-        render_passes_in_frame.find(pass_iter->first);
-    if (it == render_passes_in_frame.end()) {
-      passes_to_delete.push_back(pass_iter->first);
-      continue;
-    }
-
-    gfx::Size required_size = it->second;
-    ScopedResource* texture = pass_iter->second;
-    DCHECK(texture);
-
-    bool size_appropriate = texture->size().width() >= required_size.width() &&
-                            texture->size().height() >= required_size.height();
-    if (texture->id() && !size_appropriate)
-      texture->Free();
-  }
-
-  // Delete RenderPass textures from the previous frame that will not be used
-  // again.
-  for (size_t i = 0; i < passes_to_delete.size(); ++i)
-    render_pass_textures_.erase(passes_to_delete[i]);
-
-  for (size_t i = 0; i < render_passes_in_draw_order.size(); ++i) {
-    if (!render_pass_textures_.contains(render_passes_in_draw_order[i]->id)) {
-      scoped_ptr<ScopedResource> texture =
-          ScopedResource::Create(resource_provider_);
-      render_pass_textures_.set(render_passes_in_draw_order[i]->id,
-                              texture.Pass());
-    }
-  }
-}
-
-void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order,
-                               float device_scale_factor,
-                               const gfx::Rect& device_viewport_rect,
-                               const gfx::Rect& device_clip_rect,
-                               bool disable_picture_quad_image_filtering) {
-  TRACE_EVENT0("cc", "DirectRenderer::DrawFrame");
-  UMA_HISTOGRAM_COUNTS("Renderer4.renderPassCount",
-                       render_passes_in_draw_order->size());
-
-  const RenderPass* root_render_pass = render_passes_in_draw_order->back();
-  DCHECK(root_render_pass);
-
-  DrawingFrame frame;
-  frame.render_passes_in_draw_order = render_passes_in_draw_order;
-  frame.root_render_pass = root_render_pass;
-  frame.root_damage_rect = Capabilities().using_partial_swap
-                               ? root_render_pass->damage_rect
-                               : root_render_pass->output_rect;
-  frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_rect.size()));
-  frame.device_viewport_rect = device_viewport_rect;
-  frame.device_clip_rect = device_clip_rect;
-  frame.disable_picture_quad_image_filtering =
-      disable_picture_quad_image_filtering;
-
-  overlay_processor_->ProcessForOverlays(render_passes_in_draw_order,
-                                         &frame.overlay_list);
-
-  EnsureBackbuffer();
-
-  // Only reshape when we know we are going to draw. Otherwise, the reshape
-  // can leave the window at the wrong size if we never draw and the proper
-  // viewport size is never set.
-  output_surface_->Reshape(device_viewport_rect.size(), device_scale_factor);
-
-  BeginDrawingFrame(&frame);
-  for (size_t i = 0; i < render_passes_in_draw_order->size(); ++i) {
-    RenderPass* pass = render_passes_in_draw_order->at(i);
-    DrawRenderPass(&frame, pass);
-
-    for (ScopedPtrVector<CopyOutputRequest>::iterator it =
-             pass->copy_requests.begin();
-         it != pass->copy_requests.end();
-         ++it) {
-      if (it != pass->copy_requests.begin()) {
-        // Doing a readback is destructive of our state on Mac, so make sure
-        // we restore the state between readbacks. http://crbug.com/99393.
-        UseRenderPass(&frame, pass);
-      }
-      CopyCurrentRenderPassToBitmap(&frame, pass->copy_requests.take(it));
-    }
-  }
-  FinishDrawingFrame(&frame);
-
-  render_passes_in_draw_order->clear();
-}
-
-gfx::Rect DirectRenderer::ComputeScissorRectForRenderPass(
-    const DrawingFrame* frame) {
-  gfx::Rect render_pass_scissor = frame->current_render_pass->output_rect;
-
-  if (frame->root_damage_rect == frame->root_render_pass->output_rect ||
-      !frame->current_render_pass->copy_requests.empty())
-    return render_pass_scissor;
-
-  gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
-  if (frame->current_render_pass->transform_to_root_target.GetInverse(
-          &inverse_transform)) {
-    // Only intersect inverse-projected damage if the transform is invertible.
-    gfx::Rect damage_rect_in_render_pass_space =
-        MathUtil::ProjectEnclosingClippedRect(inverse_transform,
-                                              frame->root_damage_rect);
-    render_pass_scissor.Intersect(damage_rect_in_render_pass_space);
-  }
-
-  return render_pass_scissor;
-}
-
-bool DirectRenderer::NeedDeviceClip(const DrawingFrame* frame) const {
-  if (frame->current_render_pass != frame->root_render_pass)
-    return false;
-
-  return !frame->device_clip_rect.Contains(frame->device_viewport_rect);
-}
-
-gfx::Rect DirectRenderer::DeviceClipRectInDrawSpace(
-    const DrawingFrame* frame) const {
-  gfx::Rect device_clip_rect = frame->device_clip_rect;
-  device_clip_rect -= current_viewport_rect_.OffsetFromOrigin();
-  device_clip_rect += current_draw_rect_.OffsetFromOrigin();
-  return device_clip_rect;
-}
-
-gfx::Rect DirectRenderer::DeviceViewportRectInDrawSpace(
-    const DrawingFrame* frame) const {
-  gfx::Rect device_viewport_rect = frame->device_viewport_rect;
-  device_viewport_rect -= current_viewport_rect_.OffsetFromOrigin();
-  device_viewport_rect += current_draw_rect_.OffsetFromOrigin();
-  return device_viewport_rect;
-}
-
-gfx::Rect DirectRenderer::OutputSurfaceRectInDrawSpace(
-    const DrawingFrame* frame) const {
-  if (frame->current_render_pass == frame->root_render_pass) {
-    gfx::Rect output_surface_rect(output_surface_->SurfaceSize());
-    output_surface_rect -= current_viewport_rect_.OffsetFromOrigin();
-    output_surface_rect += current_draw_rect_.OffsetFromOrigin();
-    return output_surface_rect;
-  } else {
-    return frame->current_render_pass->output_rect;
-  }
-}
-
-bool DirectRenderer::ShouldSkipQuad(const DrawQuad& quad,
-                                    const gfx::Rect& render_pass_scissor) {
-  if (render_pass_scissor.IsEmpty())
-    return true;
-
-  if (quad.isClipped()) {
-    gfx::Rect r = quad.clipRect();
-    r.Intersect(render_pass_scissor);
-    return r.IsEmpty();
-  }
-
-  return false;
-}
-
-void DirectRenderer::SetScissorStateForQuad(
-    const DrawingFrame* frame,
-    const DrawQuad& quad,
-    const gfx::Rect& render_pass_scissor,
-    bool use_render_pass_scissor) {
-  if (use_render_pass_scissor) {
-    gfx::Rect quad_scissor_rect = render_pass_scissor;
-    if (quad.isClipped())
-      quad_scissor_rect.Intersect(quad.clipRect());
-    SetScissorTestRectInDrawSpace(frame, quad_scissor_rect);
-    return;
-  } else if (quad.isClipped()) {
-    SetScissorTestRectInDrawSpace(frame, quad.clipRect());
-    return;
-  }
-
-  EnsureScissorTestDisabled();
-}
-
-void DirectRenderer::SetScissorTestRectInDrawSpace(
-    const DrawingFrame* frame,
-    const gfx::Rect& draw_space_rect) {
-  gfx::Rect window_space_rect =
-      MoveFromDrawToWindowSpace(frame, draw_space_rect);
-  SetScissorTestRect(window_space_rect);
-}
-
-void DirectRenderer::FinishDrawingQuadList() {}
-
-void DirectRenderer::DoDrawPolygon(const DrawPolygon& poly,
-                                   DrawingFrame* frame,
-                                   const gfx::Rect& render_pass_scissor,
-                                   bool use_render_pass_scissor) {
-  SetScissorStateForQuad(frame, *poly.original_ref(), render_pass_scissor,
-                         use_render_pass_scissor);
-
-  // If the poly has not been split, then it is just a normal DrawQuad,
-  // and we should save any extra processing that would have to be done.
-  if (!poly.is_split()) {
-    DoDrawQuad(frame, poly.original_ref(), NULL);
-    return;
-  }
-
-  std::vector<gfx::QuadF> quads;
-  poly.ToQuads2D(&quads);
-  for (size_t i = 0; i < quads.size(); ++i) {
-    DoDrawQuad(frame, poly.original_ref(), &quads[i]);
-  }
-}
-
-void DirectRenderer::FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list,
-                                   DrawingFrame* frame,
-                                   const gfx::Rect& render_pass_scissor,
-                                   bool use_render_pass_scissor) {
-  if (poly_list->empty()) {
-    return;
-  }
-
-  BspTree bsp_tree(poly_list);
-  BspWalkActionDrawPolygon action_handler(this, frame, render_pass_scissor,
-                                          use_render_pass_scissor);
-  bsp_tree.TraverseWithActionHandler(&action_handler);
-  DCHECK(poly_list->empty());
-}
-
-void DirectRenderer::DrawRenderPass(DrawingFrame* frame,
-                                    const RenderPass* render_pass) {
-  TRACE_EVENT0("cc", "DirectRenderer::DrawRenderPass");
-  if (!UseRenderPass(frame, render_pass))
-    return;
-
-  const gfx::Rect surface_rect_in_draw_space =
-      OutputSurfaceRectInDrawSpace(frame);
-  gfx::Rect render_pass_scissor_in_draw_space = surface_rect_in_draw_space;
-
-  if (frame->current_render_pass == frame->root_render_pass) {
-    render_pass_scissor_in_draw_space.Intersect(
-        DeviceViewportRectInDrawSpace(frame));
-  }
-
-  if (Capabilities().using_partial_swap) {
-    render_pass_scissor_in_draw_space.Intersect(
-        ComputeScissorRectForRenderPass(frame));
-  }
-
-  if (NeedDeviceClip(frame)) {
-    render_pass_scissor_in_draw_space.Intersect(
-        DeviceClipRectInDrawSpace(frame));
-  }
-
-  bool render_pass_is_clipped =
-      !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space);
-  bool is_root_render_pass =
-      frame->current_render_pass == frame->root_render_pass;
-  bool has_external_stencil_test =
-      is_root_render_pass && output_surface_->HasExternalStencilTest();
-  bool should_clear_surface =
-      !has_external_stencil_test &&
-      (!is_root_render_pass || settings_->should_clear_root_render_pass);
-
-  // If |has_external_stencil_test| we can't discard or clear. Make sure we
-  // don't need to.
-  DCHECK_IMPLIES(has_external_stencil_test,
-                 !frame->current_render_pass->has_transparent_background);
-
-  SurfaceInitializationMode mode;
-  if (should_clear_surface && render_pass_is_clipped) {
-    mode = SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR;
-  } else if (should_clear_surface) {
-    mode = SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR;
-  } else {
-    mode = SURFACE_INITIALIZATION_MODE_PRESERVE;
-  }
-
-  PrepareSurfaceForPass(
-      frame, mode,
-      MoveFromDrawToWindowSpace(frame, render_pass_scissor_in_draw_space));
-
-  const QuadList& quad_list = render_pass->quad_list;
-  ScopedPtrDeque<DrawPolygon> poly_list;
-
-  int next_polygon_id = 0;
-  int last_sorting_context_id = 0;
-  for (auto it = quad_list.BackToFrontBegin(); it != quad_list.BackToFrontEnd();
-       ++it) {
-    const DrawQuad& quad = **it;
-    gfx::QuadF send_quad(quad.visible_rect);
-
-    if (render_pass_is_clipped &&
-        ShouldSkipQuad(quad, render_pass_scissor_in_draw_space)) {
-      continue;
-    }
-
-    if (last_sorting_context_id != quad.shared_quad_state->sorting_context_id) {
-      last_sorting_context_id = quad.shared_quad_state->sorting_context_id;
-      FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space,
-                    render_pass_is_clipped);
-    }
-
-    // This layer is in a 3D sorting context so we add it to the list of
-    // polygons to go into the BSP tree.
-    if (quad.shared_quad_state->sorting_context_id != 0) {
-      scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon(
-          *it, quad.visible_rect, quad.quadTransform(), next_polygon_id++));
-      if (new_polygon->points().size() > 2u) {
-        poly_list.push_back(new_polygon.Pass());
-      }
-      continue;
-    }
-
-    // We are not in a 3d sorting context, so we should draw the quad normally.
-    SetScissorStateForQuad(frame, quad, render_pass_scissor_in_draw_space,
-                           render_pass_is_clipped);
-
-    DoDrawQuad(frame, &quad, nullptr);
-  }
-  FlushPolygons(&poly_list, frame, render_pass_scissor_in_draw_space,
-                render_pass_is_clipped);
-  FinishDrawingQuadList();
-}
-
-bool DirectRenderer::UseRenderPass(DrawingFrame* frame,
-                                   const RenderPass* render_pass) {
-  frame->current_render_pass = render_pass;
-  frame->current_texture = NULL;
-
-  if (render_pass == frame->root_render_pass) {
-    BindFramebufferToOutputSurface(frame);
-    InitializeViewport(frame,
-                       render_pass->output_rect,
-                       frame->device_viewport_rect,
-                       output_surface_->SurfaceSize());
-    return true;
-  }
-
-  ScopedResource* texture = render_pass_textures_.get(render_pass->id);
-  DCHECK(texture);
-
-  gfx::Size size = RenderPassTextureSize(render_pass);
-  size.Enlarge(enlarge_pass_texture_amount_.x(),
-               enlarge_pass_texture_amount_.y());
-  if (!texture->id())
-    texture->Allocate(
-        size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, RGBA_8888);
-  DCHECK(texture->id());
-
-  if (BindFramebufferToTexture(frame, texture, render_pass->output_rect)) {
-    InitializeViewport(frame, render_pass->output_rect,
-                       gfx::Rect(render_pass->output_rect.size()),
-                       render_pass->output_rect.size());
-    return true;
-  }
-
-  return false;
-}
-
-bool DirectRenderer::HasAllocatedResourcesForTesting(RenderPassId id) const {
-  ScopedResource* texture = render_pass_textures_.get(id);
-  return texture && texture->id();
-}
-
-// static
-gfx::Size DirectRenderer::RenderPassTextureSize(const RenderPass* render_pass) {
-  return render_pass->output_rect.size();
-}
-
-}  // namespace cc
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
deleted file mode 100644
index 3a8d175..0000000
--- a/cc/output/direct_renderer.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_DIRECT_RENDERER_H_
-#define CC_OUTPUT_DIRECT_RENDERER_H_
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/output/overlay_processor.h"
-#include "cc/output/renderer.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/resources/scoped_resource.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-namespace cc {
-
-class DrawPolygon;
-class ResourceProvider;
-
-// This is the base class for code shared between the GL and software
-// renderer implementations.  "Direct" refers to the fact that it does not
-// delegate rendering to another compositor.
-class DirectRenderer : public Renderer {
- public:
-  ~DirectRenderer() override;
-
-  void DecideRenderPassAllocationsForFrame(
-      const RenderPassList& render_passes_in_draw_order) override;
-  bool HasAllocatedResourcesForTesting(RenderPassId id) const override;
-  void DrawFrame(RenderPassList* render_passes_in_draw_order,
-                 float device_scale_factor,
-                 const gfx::Rect& device_viewport_rect,
-                 const gfx::Rect& device_clip_rect,
-                 bool disable_picture_quad_image_filtering) override;
-
-  struct DrawingFrame {
-    DrawingFrame();
-    ~DrawingFrame();
-
-    const RenderPassList* render_passes_in_draw_order;
-    const RenderPass* root_render_pass;
-    const RenderPass* current_render_pass;
-    const ScopedResource* current_texture;
-
-    gfx::Rect root_damage_rect;
-    gfx::Rect device_viewport_rect;
-    gfx::Rect device_clip_rect;
-
-    gfx::Transform projection_matrix;
-    gfx::Transform window_matrix;
-
-    bool disable_picture_quad_image_filtering;
-
-    OverlayCandidateList overlay_list;
-  };
-
-  void SetEnlargePassTextureAmountForTesting(const gfx::Vector2d& amount);
-  void DoDrawPolygon(const DrawPolygon& poly,
-                     DrawingFrame* frame,
-                     const gfx::Rect& render_pass_scissor,
-                     bool use_render_pass_scissor);
-
- protected:
-  enum SurfaceInitializationMode {
-    SURFACE_INITIALIZATION_MODE_PRESERVE,
-    SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR,
-    SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR,
-  };
-
-  DirectRenderer(RendererClient* client,
-                 const RendererSettings* settings,
-                 OutputSurface* output_surface,
-                 ResourceProvider* resource_provider);
-
-  static gfx::RectF QuadVertexRect();
-  static void QuadRectTransform(gfx::Transform* quad_rect_transform,
-                                const gfx::Transform& quad_transform,
-                                const gfx::RectF& quad_rect);
-  void InitializeViewport(DrawingFrame* frame,
-                          const gfx::Rect& draw_rect,
-                          const gfx::Rect& viewport_rect,
-                          const gfx::Size& surface_size);
-  gfx::Rect MoveFromDrawToWindowSpace(const DrawingFrame* frame,
-                                      const gfx::Rect& draw_rect) const;
-
-  bool NeedDeviceClip(const DrawingFrame* frame) const;
-  gfx::Rect DeviceClipRectInDrawSpace(const DrawingFrame* frame) const;
-  gfx::Rect DeviceViewportRectInDrawSpace(const DrawingFrame* frame) const;
-  gfx::Rect OutputSurfaceRectInDrawSpace(const DrawingFrame* frame) const;
-  static gfx::Rect ComputeScissorRectForRenderPass(const DrawingFrame* frame);
-  void SetScissorStateForQuad(const DrawingFrame* frame,
-                              const DrawQuad& quad,
-                              const gfx::Rect& render_pass_scissor,
-                              bool use_render_pass_scissor);
-  bool ShouldSkipQuad(const DrawQuad& quad,
-                      const gfx::Rect& render_pass_scissor);
-  void SetScissorTestRectInDrawSpace(const DrawingFrame* frame,
-                                     const gfx::Rect& draw_space_rect);
-
-  static gfx::Size RenderPassTextureSize(const RenderPass* render_pass);
-
-  void FlushPolygons(ScopedPtrDeque<DrawPolygon>* poly_list,
-                     DrawingFrame* frame,
-                     const gfx::Rect& render_pass_scissor,
-                     bool use_render_pass_scissor);
-  void DrawRenderPass(DrawingFrame* frame, const RenderPass* render_pass);
-  bool UseRenderPass(DrawingFrame* frame, const RenderPass* render_pass);
-
-  virtual void BindFramebufferToOutputSurface(DrawingFrame* frame) = 0;
-  virtual bool BindFramebufferToTexture(DrawingFrame* frame,
-                                        const ScopedResource* resource,
-                                        const gfx::Rect& target_rect) = 0;
-  virtual void SetDrawViewport(const gfx::Rect& window_space_viewport) = 0;
-  virtual void SetScissorTestRect(const gfx::Rect& scissor_rect) = 0;
-  virtual void PrepareSurfaceForPass(
-      DrawingFrame* frame,
-      SurfaceInitializationMode initialization_mode,
-      const gfx::Rect& render_pass_scissor) = 0;
-  // clip_region is a (possibly null) pointer to a quad in the same
-  // space as the quad. When non-null only the area of the quad that overlaps
-  // with clip_region will be drawn.
-  virtual void DoDrawQuad(DrawingFrame* frame,
-                          const DrawQuad* quad,
-                          const gfx::QuadF* clip_region) = 0;
-  virtual void BeginDrawingFrame(DrawingFrame* frame) = 0;
-  virtual void FinishDrawingFrame(DrawingFrame* frame) = 0;
-  virtual void FinishDrawingQuadList();
-  virtual bool FlippedFramebuffer(const DrawingFrame* frame) const = 0;
-  virtual void EnsureScissorTestEnabled() = 0;
-  virtual void EnsureScissorTestDisabled() = 0;
-  virtual void DiscardBackbuffer() {}
-  virtual void EnsureBackbuffer() {}
-
-  virtual void CopyCurrentRenderPassToBitmap(
-      DrawingFrame* frame,
-      scoped_ptr<CopyOutputRequest> request) = 0;
-
-  base::ScopedPtrHashMap<RenderPassId, scoped_ptr<ScopedResource>> render_pass_textures_;
-  OutputSurface* output_surface_;
-  ResourceProvider* resource_provider_;
-  scoped_ptr<OverlayProcessor> overlay_processor_;
-
-  // For use in coordinate conversion, this stores the output rect, viewport
-  // rect (= unflipped version of glViewport rect), and the size of target
-  // framebuffer. During a draw, this stores the values for the current render
-  // pass; in between draws, they retain the values for the root render pass of
-  // the last draw.
-  gfx::Rect current_draw_rect_;
-  gfx::Rect current_viewport_rect_;
-  gfx::Size current_surface_size_;
-
- private:
-  gfx::Vector2d enlarge_pass_texture_amount_;
-
-  DISALLOW_COPY_AND_ASSIGN(DirectRenderer);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_DIRECT_RENDERER_H_
diff --git a/cc/output/dynamic_geometry_binding.cc b/cc/output/dynamic_geometry_binding.cc
deleted file mode 100644
index 9e25892..0000000
--- a/cc/output/dynamic_geometry_binding.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-#include "cc/output/dynamic_geometry_binding.h"
-
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace cc {
-
-DynamicGeometryBinding::DynamicGeometryBinding(gpu::gles2::GLES2Interface* gl)
-    : gl_(gl), quad_vertices_vbo_(0), quad_elements_vbo_(0) {
-  GeometryBindingQuad quads[1];
-  GeometryBindingQuadIndex quad_indices[1];
-
-  static_assert(sizeof(GeometryBindingQuad) == 24 * sizeof(float),
-                "struct Quad should be densely packed");
-  static_assert(sizeof(GeometryBindingQuadIndex) == 6 * sizeof(uint16_t),
-                "struct QuadIndex should be densely packed");
-
-  GLC(gl_, gl_->GenBuffers(1, &quad_vertices_vbo_));
-  GLC(gl_, gl_->GenBuffers(1, &quad_elements_vbo_));
-
-  GLC(gl_, gl_->BindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
-  GLC(gl_, gl_->BufferData(GL_ARRAY_BUFFER, sizeof(GeometryBindingQuad) * 1,
-                           quads, GL_DYNAMIC_DRAW));
-
-  GLC(gl_, gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));
-  GLC(gl_, gl_->BufferData(GL_ELEMENT_ARRAY_BUFFER,
-                           sizeof(GeometryBindingQuadIndex) * 1, &quad_indices,
-                           GL_DYNAMIC_DRAW));
-}
-
-void DynamicGeometryBinding::InitializeCustomQuad(const gfx::QuadF& quad) {
-  float uv[] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
-  InitializeCustomQuadWithUVs(quad, uv);
-}
-
-void DynamicGeometryBinding::InitializeCustomQuadWithUVs(const gfx::QuadF& quad,
-                                                         const float uv[8]) {
-  GeometryBindingVertex v0 = {
-      {quad.p1().x(), quad.p1().y(), 0.0f}, {uv[0], uv[1]}, 0.0f};
-  GeometryBindingVertex v1 = {
-      {quad.p2().x(), quad.p2().y(), 0.0f}, {uv[2], uv[3]}, 1.0f};
-  GeometryBindingVertex v2 = {
-      {quad.p3().x(), quad.p3().y(), 0.0f}, {uv[4], uv[5]}, 2.0f};
-  GeometryBindingVertex v3 = {
-      {quad.p4().x(), quad.p4().y(), 0.0f}, {uv[6], uv[7]}, 3.0f};
-
-  GeometryBindingQuad local_quad = {v0, v1, v2, v3};
-  GeometryBindingQuadIndex quad_index(
-      static_cast<uint16>(0), static_cast<uint16>(1), static_cast<uint16>(2),
-      static_cast<uint16>(3), static_cast<uint16>(0), static_cast<uint16>(2));
-
-  GLC(gl_, gl_->BufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GeometryBindingQuad),
-                              &local_quad));
-  GLC(gl_, gl_->BufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0,
-                              sizeof(GeometryBindingQuadIndex), &quad_index));
-}
-
-void DynamicGeometryBinding::PrepareForDraw() {
-  SetupGLContext(gl_, quad_elements_vbo_, quad_vertices_vbo_);
-}
-
-}  // namespace cc
diff --git a/cc/output/dynamic_geometry_binding.h b/cc/output/dynamic_geometry_binding.h
deleted file mode 100644
index 4e4ea3d..0000000
--- a/cc/output/dynamic_geometry_binding.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#ifndef CC_OUTPUT_DYNAMIC_GEOMETRY_BINDING_H_
-#define CC_OUTPUT_DYNAMIC_GEOMETRY_BINDING_H_
-
-#include "cc/output/geometry_binding.h"
-
-namespace cc {
-
-class DynamicGeometryBinding {
- public:
-  explicit DynamicGeometryBinding(gpu::gles2::GLES2Interface* gl);
-  void PrepareForDraw();
-  void InitializeCustomQuad(const gfx::QuadF& quad);
-  void InitializeCustomQuadWithUVs(const gfx::QuadF& quad, const float uv[8]);
-
- private:
-  gpu::gles2::GLES2Interface* gl_;
-
-  GLuint quad_vertices_vbo_;
-  GLuint quad_elements_vbo_;
-
-  DISALLOW_COPY_AND_ASSIGN(DynamicGeometryBinding);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_DYNAMIC_GEOMETRY_BINDING_H_
diff --git a/cc/output/filter_operation.cc b/cc/output/filter_operation.cc
deleted file mode 100644
index 1579e55..0000000
--- a/cc/output/filter_operation.cc
+++ /dev/null
@@ -1,318 +0,0 @@
-// Copyright 2013 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.
-
-#include <algorithm>
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "cc/output/filter_operation.h"
-#include "ui/gfx/animation/tween.h"
-
-namespace cc {
-
-bool FilterOperation::operator==(const FilterOperation& other) const {
-  if (type_ != other.type_)
-    return false;
-  if (type_ == COLOR_MATRIX)
-    return !memcmp(matrix_, other.matrix_, sizeof(matrix_));
-  if (type_ == DROP_SHADOW) {
-    return amount_ == other.amount_ &&
-           drop_shadow_offset_ == other.drop_shadow_offset_ &&
-           drop_shadow_color_ == other.drop_shadow_color_;
-  }
-  if (type_ == REFERENCE)
-    return image_filter_.get() == other.image_filter_.get();
-  if (type_ == ALPHA_THRESHOLD) {
-    return region_ == other.region_ &&
-        amount_ == other.amount_ &&
-        outer_threshold_ == other.outer_threshold_;
-  }
-  return amount_ == other.amount_;
-}
-
-FilterOperation::FilterOperation(FilterType type, float amount)
-    : type_(type),
-      amount_(amount),
-      outer_threshold_(0),
-      drop_shadow_offset_(0, 0),
-      drop_shadow_color_(0),
-      zoom_inset_(0) {
-  DCHECK_NE(type_, DROP_SHADOW);
-  DCHECK_NE(type_, COLOR_MATRIX);
-  DCHECK_NE(type_, REFERENCE);
-  memset(matrix_, 0, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(FilterType type,
-                                 const gfx::Point& offset,
-                                 float stdDeviation,
-                                 SkColor color)
-    : type_(type),
-      amount_(stdDeviation),
-      outer_threshold_(0),
-      drop_shadow_offset_(offset),
-      drop_shadow_color_(color),
-      zoom_inset_(0) {
-  DCHECK_EQ(type_, DROP_SHADOW);
-  memset(matrix_, 0, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(FilterType type, SkScalar matrix[20])
-    : type_(type),
-      amount_(0),
-      outer_threshold_(0),
-      drop_shadow_offset_(0, 0),
-      drop_shadow_color_(0),
-      zoom_inset_(0) {
-  DCHECK_EQ(type_, COLOR_MATRIX);
-  memcpy(matrix_, matrix, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(FilterType type, float amount, int inset)
-    : type_(type),
-      amount_(amount),
-      outer_threshold_(0),
-      drop_shadow_offset_(0, 0),
-      drop_shadow_color_(0),
-      zoom_inset_(inset) {
-  DCHECK_EQ(type_, ZOOM);
-  memset(matrix_, 0, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(
-    FilterType type,
-    const skia::RefPtr<SkImageFilter>& image_filter)
-    : type_(type),
-      amount_(0),
-      outer_threshold_(0),
-      drop_shadow_offset_(0, 0),
-      drop_shadow_color_(0),
-      image_filter_(image_filter),
-      zoom_inset_(0) {
-  DCHECK_EQ(type_, REFERENCE);
-  memset(matrix_, 0, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(FilterType type,
-                                 const SkRegion& region,
-                                 float inner_threshold,
-                                 float outer_threshold)
-    : type_(type),
-      amount_(inner_threshold),
-      outer_threshold_(outer_threshold),
-      drop_shadow_offset_(0, 0),
-      drop_shadow_color_(0),
-      zoom_inset_(0),
-      region_(region) {
-  DCHECK_EQ(type_, ALPHA_THRESHOLD);
-  memset(matrix_, 0, sizeof(matrix_));
-}
-
-FilterOperation::FilterOperation(const FilterOperation& other)
-    : type_(other.type_),
-      amount_(other.amount_),
-      outer_threshold_(other.outer_threshold_),
-      drop_shadow_offset_(other.drop_shadow_offset_),
-      drop_shadow_color_(other.drop_shadow_color_),
-      image_filter_(other.image_filter_),
-      zoom_inset_(other.zoom_inset_),
-      region_(other.region_) {
-  memcpy(matrix_, other.matrix_, sizeof(matrix_));
-}
-
-FilterOperation::~FilterOperation() {
-}
-
-static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
-  switch (type) {
-    case FilterOperation::GRAYSCALE:
-      return FilterOperation::CreateGrayscaleFilter(0.f);
-    case FilterOperation::SEPIA:
-      return FilterOperation::CreateSepiaFilter(0.f);
-    case FilterOperation::SATURATE:
-      return FilterOperation::CreateSaturateFilter(1.f);
-    case FilterOperation::HUE_ROTATE:
-      return FilterOperation::CreateHueRotateFilter(0.f);
-    case FilterOperation::INVERT:
-      return FilterOperation::CreateInvertFilter(0.f);
-    case FilterOperation::BRIGHTNESS:
-      return FilterOperation::CreateBrightnessFilter(1.f);
-    case FilterOperation::CONTRAST:
-      return FilterOperation::CreateContrastFilter(1.f);
-    case FilterOperation::OPACITY:
-      return FilterOperation::CreateOpacityFilter(1.f);
-    case FilterOperation::BLUR:
-      return FilterOperation::CreateBlurFilter(0.f);
-    case FilterOperation::DROP_SHADOW:
-      return FilterOperation::CreateDropShadowFilter(
-          gfx::Point(0, 0), 0.f, SK_ColorTRANSPARENT);
-    case FilterOperation::COLOR_MATRIX: {
-      SkScalar matrix[20];
-      memset(matrix, 0, 20 * sizeof(SkScalar));
-      matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
-      return FilterOperation::CreateColorMatrixFilter(matrix);
-    }
-    case FilterOperation::ZOOM:
-      return FilterOperation::CreateZoomFilter(1.f, 0);
-    case FilterOperation::SATURATING_BRIGHTNESS:
-      return FilterOperation::CreateSaturatingBrightnessFilter(0.f);
-    case FilterOperation::REFERENCE:
-      return FilterOperation::CreateReferenceFilter(
-          skia::RefPtr<SkImageFilter>());
-    case FilterOperation::ALPHA_THRESHOLD:
-      return FilterOperation::CreateAlphaThresholdFilter(SkRegion(), 1.f, 0.f);
-  }
-  NOTREACHED();
-  return FilterOperation::CreateEmptyFilter();
-}
-
-static float ClampAmountForFilterType(float amount,
-                                      FilterOperation::FilterType type) {
-  switch (type) {
-    case FilterOperation::GRAYSCALE:
-    case FilterOperation::SEPIA:
-    case FilterOperation::INVERT:
-    case FilterOperation::OPACITY:
-    case FilterOperation::ALPHA_THRESHOLD:
-      return MathUtil::ClampToRange(amount, 0.f, 1.f);
-    case FilterOperation::SATURATE:
-    case FilterOperation::BRIGHTNESS:
-    case FilterOperation::CONTRAST:
-    case FilterOperation::BLUR:
-    case FilterOperation::DROP_SHADOW:
-      return std::max(amount, 0.f);
-    case FilterOperation::ZOOM:
-      return std::max(amount, 1.f);
-    case FilterOperation::HUE_ROTATE:
-    case FilterOperation::SATURATING_BRIGHTNESS:
-      return amount;
-    case FilterOperation::COLOR_MATRIX:
-    case FilterOperation::REFERENCE:
-      NOTREACHED();
-      return amount;
-  }
-  NOTREACHED();
-  return amount;
-}
-
-// static
-FilterOperation FilterOperation::Blend(const FilterOperation* from,
-                                       const FilterOperation* to,
-                                       double progress) {
-  FilterOperation blended_filter = FilterOperation::CreateEmptyFilter();
-
-  if (!from && !to)
-    return blended_filter;
-
-  const FilterOperation& from_op = from ? *from : CreateNoOpFilter(to->type());
-  const FilterOperation& to_op = to ? *to : CreateNoOpFilter(from->type());
-
-  if (from_op.type() != to_op.type())
-    return blended_filter;
-
-  DCHECK(to_op.type() != FilterOperation::COLOR_MATRIX);
-  blended_filter.set_type(to_op.type());
-
-  if (to_op.type() == FilterOperation::REFERENCE) {
-    if (progress > 0.5)
-      blended_filter.set_image_filter(to_op.image_filter());
-    else
-      blended_filter.set_image_filter(from_op.image_filter());
-    return blended_filter;
-  }
-
-  blended_filter.set_amount(ClampAmountForFilterType(
-      gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
-      to_op.type()));
-
-  if (to_op.type() == FilterOperation::DROP_SHADOW) {
-    gfx::Point blended_offset(
-        gfx::Tween::LinearIntValueBetween(progress,
-                                          from_op.drop_shadow_offset().x(),
-                                          to_op.drop_shadow_offset().x()),
-        gfx::Tween::LinearIntValueBetween(progress,
-                                          from_op.drop_shadow_offset().y(),
-                                          to_op.drop_shadow_offset().y()));
-    blended_filter.set_drop_shadow_offset(blended_offset);
-    blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
-        progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
-  } else if (to_op.type() == FilterOperation::ZOOM) {
-    blended_filter.set_zoom_inset(
-        std::max(gfx::Tween::LinearIntValueBetween(
-                     from_op.zoom_inset(), to_op.zoom_inset(), progress),
-                 0));
-  } else if (to_op.type() == FilterOperation::ALPHA_THRESHOLD) {
-    blended_filter.set_outer_threshold(ClampAmountForFilterType(
-            gfx::Tween::FloatValueBetween(progress,
-                                          from_op.outer_threshold(),
-                                          to_op.outer_threshold()),
-            to_op.type()));
-    blended_filter.set_region(to_op.region());
-  }
-
-  return blended_filter;
-}
-
-void FilterOperation::AsValueInto(base::trace_event::TracedValue* value) const {
-  value->SetInteger("type", type_);
-  switch (type_) {
-    case FilterOperation::GRAYSCALE:
-    case FilterOperation::SEPIA:
-    case FilterOperation::SATURATE:
-    case FilterOperation::HUE_ROTATE:
-    case FilterOperation::INVERT:
-    case FilterOperation::BRIGHTNESS:
-    case FilterOperation::CONTRAST:
-    case FilterOperation::OPACITY:
-    case FilterOperation::BLUR:
-    case FilterOperation::SATURATING_BRIGHTNESS:
-      value->SetDouble("amount", amount_);
-      break;
-    case FilterOperation::DROP_SHADOW:
-      value->SetDouble("std_deviation", amount_);
-      MathUtil::AddToTracedValue("offset", drop_shadow_offset_, value);
-      value->SetInteger("color", drop_shadow_color_);
-      break;
-    case FilterOperation::COLOR_MATRIX: {
-      value->BeginArray("matrix");
-      for (size_t i = 0; i < arraysize(matrix_); ++i)
-        value->AppendDouble(matrix_[i]);
-      value->EndArray();
-      break;
-    }
-    case FilterOperation::ZOOM:
-      value->SetDouble("amount", amount_);
-      value->SetDouble("inset", zoom_inset_);
-      break;
-    case FilterOperation::REFERENCE: {
-      int count_inputs = 0;
-      bool can_filter_image_gpu = false;
-      if (image_filter_) {
-        count_inputs = image_filter_->countInputs();
-        can_filter_image_gpu = image_filter_->canFilterImageGPU();
-      }
-      value->SetBoolean("is_null", !image_filter_);
-      value->SetInteger("count_inputs", count_inputs);
-      value->SetBoolean("can_filter_image_gpu", can_filter_image_gpu);
-      break;
-    }
-    case FilterOperation::ALPHA_THRESHOLD: {
-        value->SetDouble("inner_threshold", amount_);
-        value->SetDouble("outer_threshold", outer_threshold_);
-        scoped_ptr<base::ListValue> region_value(new base::ListValue());
-        value->BeginArray("region");
-        for (SkRegion::Iterator it(region_); !it.done(); it.next()) {
-          value->AppendInteger(it.rect().x());
-          value->AppendInteger(it.rect().y());
-          value->AppendInteger(it.rect().width());
-          value->AppendInteger(it.rect().height());
-        }
-        value->EndArray();
-      }
-      break;
-  }
-}
-
-}  // namespace cc
diff --git a/cc/output/filter_operation.h b/cc/output/filter_operation.h
deleted file mode 100644
index 8330f06..0000000
--- a/cc/output/filter_operation.h
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_FILTER_OPERATION_H_
-#define CC_OUTPUT_FILTER_OPERATION_H_
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/skia/include/core/SkScalar.h"
-#include "ui/gfx/geometry/point.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class Value;
-}
-
-namespace cc {
-
-class FilterOperation {
- public:
-  enum FilterType {
-    GRAYSCALE,
-    SEPIA,
-    SATURATE,
-    HUE_ROTATE,
-    INVERT,
-    BRIGHTNESS,
-    CONTRAST,
-    OPACITY,
-    BLUR,
-    DROP_SHADOW,
-    COLOR_MATRIX,
-    ZOOM,
-    REFERENCE,
-    SATURATING_BRIGHTNESS,  // Not used in CSS/SVG.
-    ALPHA_THRESHOLD,  // Not used in CSS/SVG.
-    FILTER_TYPE_LAST = ALPHA_THRESHOLD
-  };
-
-  FilterOperation(const FilterOperation& other);
-
-  ~FilterOperation();
-
-  FilterType type() const { return type_; }
-
-  float amount() const {
-    DCHECK_NE(type_, COLOR_MATRIX);
-    DCHECK_NE(type_, REFERENCE);
-    return amount_;
-  }
-
-  float outer_threshold() const {
-    DCHECK_EQ(type_, ALPHA_THRESHOLD);
-    return outer_threshold_;
-  }
-
-  gfx::Point drop_shadow_offset() const {
-    DCHECK_EQ(type_, DROP_SHADOW);
-    return drop_shadow_offset_;
-  }
-
-  SkColor drop_shadow_color() const {
-    DCHECK_EQ(type_, DROP_SHADOW);
-    return drop_shadow_color_;
-  }
-
-  skia::RefPtr<SkImageFilter> image_filter() const {
-    DCHECK_EQ(type_, REFERENCE);
-    return image_filter_;
-  }
-
-  const SkScalar* matrix() const {
-    DCHECK_EQ(type_, COLOR_MATRIX);
-    return matrix_;
-  }
-
-  int zoom_inset() const {
-    DCHECK_EQ(type_, ZOOM);
-    return zoom_inset_;
-  }
-
-  const SkRegion& region() const {
-    DCHECK_EQ(type_, ALPHA_THRESHOLD);
-    return region_;
-  }
-
-  static FilterOperation CreateGrayscaleFilter(float amount) {
-    return FilterOperation(GRAYSCALE, amount);
-  }
-
-  static FilterOperation CreateSepiaFilter(float amount) {
-    return FilterOperation(SEPIA, amount);
-  }
-
-  static FilterOperation CreateSaturateFilter(float amount) {
-    return FilterOperation(SATURATE, amount);
-  }
-
-  static FilterOperation CreateHueRotateFilter(float amount) {
-    return FilterOperation(HUE_ROTATE, amount);
-  }
-
-  static FilterOperation CreateInvertFilter(float amount) {
-    return FilterOperation(INVERT, amount);
-  }
-
-  static FilterOperation CreateBrightnessFilter(float amount) {
-    return FilterOperation(BRIGHTNESS, amount);
-  }
-
-  static FilterOperation CreateContrastFilter(float amount) {
-    return FilterOperation(CONTRAST, amount);
-  }
-
-  static FilterOperation CreateOpacityFilter(float amount) {
-    return FilterOperation(OPACITY, amount);
-  }
-
-  static FilterOperation CreateBlurFilter(float amount) {
-    return FilterOperation(BLUR, amount);
-  }
-
-  static FilterOperation CreateDropShadowFilter(const gfx::Point& offset,
-                                                float std_deviation,
-                                                SkColor color) {
-    return FilterOperation(DROP_SHADOW, offset, std_deviation, color);
-  }
-
-  static FilterOperation CreateColorMatrixFilter(SkScalar matrix[20]) {
-    return FilterOperation(COLOR_MATRIX, matrix);
-  }
-
-  static FilterOperation CreateZoomFilter(float amount, int inset) {
-    return FilterOperation(ZOOM, amount, inset);
-  }
-
-  static FilterOperation CreateReferenceFilter(
-      const skia::RefPtr<SkImageFilter>& image_filter) {
-    return FilterOperation(REFERENCE, image_filter);
-  }
-
-  static FilterOperation CreateSaturatingBrightnessFilter(float amount) {
-    return FilterOperation(SATURATING_BRIGHTNESS, amount);
-  }
-
-  static FilterOperation CreateAlphaThresholdFilter(const SkRegion& region,
-                                                    float inner_threshold,
-                                                    float outer_threshold) {
-    return FilterOperation(ALPHA_THRESHOLD, region,
-                           inner_threshold, outer_threshold);
-  }
-
-  bool operator==(const FilterOperation& other) const;
-
-  bool operator!=(const FilterOperation& other) const {
-    return !(*this == other);
-  }
-
-  // Methods for restoring a FilterOperation.
-  static FilterOperation CreateEmptyFilter() {
-    return FilterOperation(GRAYSCALE, 0.f);
-  }
-
-  void set_type(FilterType type) { type_ = type; }
-
-  void set_amount(float amount) {
-    DCHECK_NE(type_, COLOR_MATRIX);
-    DCHECK_NE(type_, REFERENCE);
-    amount_ = amount;
-  }
-
-  void set_outer_threshold(float outer_threshold) {
-    DCHECK_EQ(type_, ALPHA_THRESHOLD);
-    outer_threshold_ = outer_threshold;
-  }
-
-  void set_drop_shadow_offset(const gfx::Point& offset) {
-    DCHECK_EQ(type_, DROP_SHADOW);
-    drop_shadow_offset_ = offset;
-  }
-
-  void set_drop_shadow_color(SkColor color) {
-    DCHECK_EQ(type_, DROP_SHADOW);
-    drop_shadow_color_ = color;
-  }
-
-  void set_image_filter(const skia::RefPtr<SkImageFilter>& image_filter) {
-    DCHECK_EQ(type_, REFERENCE);
-    image_filter_ = image_filter;
-  }
-
-  void set_matrix(const SkScalar matrix[20]) {
-    DCHECK_EQ(type_, COLOR_MATRIX);
-    for (unsigned i = 0; i < 20; ++i)
-      matrix_[i] = matrix[i];
-  }
-
-  void set_zoom_inset(int inset) {
-    DCHECK_EQ(type_, ZOOM);
-    zoom_inset_ = inset;
-  }
-
-  void set_region(const SkRegion& region) {
-    DCHECK_EQ(type_, ALPHA_THRESHOLD);
-    region_ = region;
-  }
-
-  // Given two filters of the same type, returns a filter operation created by
-  // linearly interpolating a |progress| fraction from |from| to |to|. If either
-  // |from| or |to| (but not both) is null, it is treated as a no-op filter of
-  // the same type as the other given filter. If both |from| and |to| are null,
-  // or if |from| and |to| are non-null but of different types, returns a
-  // no-op filter.
-  static FilterOperation Blend(const FilterOperation* from,
-                               const FilterOperation* to,
-                               double progress);
-
-  void AsValueInto(base::trace_event::TracedValue* value) const;
-
- private:
-  FilterOperation(FilterType type, float amount);
-
-  FilterOperation(FilterType type,
-                  const gfx::Point& offset,
-                  float stdDeviation,
-                  SkColor color);
-
-  FilterOperation(FilterType, SkScalar matrix[20]);
-
-  FilterOperation(FilterType type, float amount, int inset);
-
-  FilterOperation(FilterType type,
-                  const skia::RefPtr<SkImageFilter>& image_filter);
-
-  FilterOperation(FilterType type,
-                  const SkRegion& region,
-                  float inner_threshold,
-                  float outer_threshold);
-
-  FilterType type_;
-  float amount_;
-  float outer_threshold_;
-  gfx::Point drop_shadow_offset_;
-  SkColor drop_shadow_color_;
-  skia::RefPtr<SkImageFilter> image_filter_;
-  SkScalar matrix_[20];
-  int zoom_inset_;
-  SkRegion region_;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_FILTER_OPERATION_H_
diff --git a/cc/output/filter_operations.cc b/cc/output/filter_operations.cc
deleted file mode 100644
index 92423de..0000000
--- a/cc/output/filter_operations.cc
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/filter_operations.h"
-
-#include <cmath>
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/output/filter_operation.h"
-
-namespace cc {
-
-FilterOperations::FilterOperations() {}
-
-FilterOperations::FilterOperations(const FilterOperations& other)
-    : operations_(other.operations_) {}
-
-FilterOperations::~FilterOperations() {}
-
-FilterOperations& FilterOperations::operator=(const FilterOperations& other) {
-  operations_ = other.operations_;
-  return *this;
-}
-
-bool FilterOperations::operator==(const FilterOperations& other) const {
-  if (other.size() != size())
-    return false;
-  for (size_t i = 0; i < size(); ++i) {
-    if (other.at(i) != at(i))
-      return false;
-  }
-  return true;
-}
-
-void FilterOperations::Append(const FilterOperation& filter) {
-  operations_.push_back(filter);
-}
-
-void FilterOperations::Clear() {
-  operations_.clear();
-}
-
-bool FilterOperations::IsEmpty() const {
-  return operations_.empty();
-}
-
-static int SpreadForStdDeviation(float std_deviation) {
-  // https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#feGaussianBlurElement
-  // provides this approximation for evaluating a gaussian blur by a triple box
-  // filter.
-  float d = floorf(std_deviation * 3.f * sqrt(8.f * atan(1.f)) / 4.f + 0.5f);
-  return static_cast<int>(ceilf(d * 3.f / 2.f));
-}
-
-void FilterOperations::GetOutsets(int* top,
-                                  int* right,
-                                  int* bottom,
-                                  int* left) const {
-  *top = *right = *bottom = *left = 0;
-  for (size_t i = 0; i < operations_.size(); ++i) {
-    const FilterOperation& op = operations_[i];
-    // TODO(ajuma): Add support for reference filters once SkImageFilter
-    // reports its outsets.
-    DCHECK(op.type() != FilterOperation::REFERENCE);
-    if (op.type() == FilterOperation::BLUR ||
-        op.type() == FilterOperation::DROP_SHADOW) {
-      int spread = SpreadForStdDeviation(op.amount());
-      if (op.type() == FilterOperation::BLUR) {
-        *top += spread;
-        *right += spread;
-        *bottom += spread;
-        *left += spread;
-      } else {
-        *top += spread - op.drop_shadow_offset().y();
-        *right += spread + op.drop_shadow_offset().x();
-        *bottom += spread + op.drop_shadow_offset().y();
-        *left += spread - op.drop_shadow_offset().x();
-      }
-    }
-  }
-}
-
-bool FilterOperations::HasFilterThatMovesPixels() const {
-  for (size_t i = 0; i < operations_.size(); ++i) {
-    const FilterOperation& op = operations_[i];
-    // TODO(ajuma): Once SkImageFilter reports its outsets, use those here to
-    // determine whether a reference filter really moves pixels.
-    switch (op.type()) {
-      case FilterOperation::BLUR:
-      case FilterOperation::DROP_SHADOW:
-      case FilterOperation::ZOOM:
-      case FilterOperation::REFERENCE:
-        return true;
-      case FilterOperation::OPACITY:
-      case FilterOperation::COLOR_MATRIX:
-      case FilterOperation::GRAYSCALE:
-      case FilterOperation::SEPIA:
-      case FilterOperation::SATURATE:
-      case FilterOperation::HUE_ROTATE:
-      case FilterOperation::INVERT:
-      case FilterOperation::BRIGHTNESS:
-      case FilterOperation::CONTRAST:
-      case FilterOperation::SATURATING_BRIGHTNESS:
-      case FilterOperation::ALPHA_THRESHOLD:
-        break;
-    }
-  }
-  return false;
-}
-
-bool FilterOperations::HasFilterThatAffectsOpacity() const {
-  for (size_t i = 0; i < operations_.size(); ++i) {
-    const FilterOperation& op = operations_[i];
-    // TODO(ajuma): Make this smarter for reference filters. Once SkImageFilter
-    // can report affectsOpacity(), call that.
-    switch (op.type()) {
-      case FilterOperation::OPACITY:
-      case FilterOperation::BLUR:
-      case FilterOperation::DROP_SHADOW:
-      case FilterOperation::ZOOM:
-      case FilterOperation::REFERENCE:
-      case FilterOperation::ALPHA_THRESHOLD:
-        return true;
-      case FilterOperation::COLOR_MATRIX: {
-        const SkScalar* matrix = op.matrix();
-        if (matrix[15] ||
-            matrix[16] ||
-            matrix[17] ||
-            matrix[18] != 1 ||
-            matrix[19])
-          return true;
-        break;
-      }
-      case FilterOperation::GRAYSCALE:
-      case FilterOperation::SEPIA:
-      case FilterOperation::SATURATE:
-      case FilterOperation::HUE_ROTATE:
-      case FilterOperation::INVERT:
-      case FilterOperation::BRIGHTNESS:
-      case FilterOperation::CONTRAST:
-      case FilterOperation::SATURATING_BRIGHTNESS:
-        break;
-    }
-  }
-  return false;
-}
-
-bool FilterOperations::HasReferenceFilter() const {
-  for (size_t i = 0; i < operations_.size(); ++i) {
-    if (operations_[i].type() == FilterOperation::REFERENCE)
-      return true;
-  }
-  return false;
-}
-
-FilterOperations FilterOperations::Blend(const FilterOperations& from,
-                                         double progress) const {
-  if (HasReferenceFilter() || from.HasReferenceFilter())
-    return *this;
-
-  bool from_is_longer = from.size() > size();
-
-  size_t shorter_size, longer_size;
-  if (size() == from.size()) {
-    shorter_size = longer_size = size();
-  } else if  (from_is_longer) {
-    longer_size = from.size();
-    shorter_size = size();
-  } else {
-    longer_size = size();
-    shorter_size = from.size();
-  }
-
-  for (size_t i = 0; i < shorter_size; i++) {
-    if (from.at(i).type() != at(i).type())
-      return *this;
-  }
-
-  FilterOperations blended_filters;
-  for (size_t i = 0; i < shorter_size; i++) {
-    blended_filters.Append(
-        FilterOperation::Blend(&from.at(i), &at(i), progress));
-  }
-
-  if (from_is_longer) {
-    for (size_t i = shorter_size; i < longer_size; i++) {
-      blended_filters.Append(
-          FilterOperation::Blend(&from.at(i), NULL, progress));
-    }
-  } else {
-    for (size_t i = shorter_size; i < longer_size; i++)
-      blended_filters.Append(FilterOperation::Blend(NULL, &at(i), progress));
-  }
-
-  return blended_filters;
-}
-
-void FilterOperations::AsValueInto(
-    base::trace_event::TracedValue* value) const {
-  for (size_t i = 0; i < operations_.size(); ++i) {
-    value->BeginDictionary();
-    operations_[i].AsValueInto(value);
-    value->EndDictionary();
-  }
-}
-
-}  // namespace cc
diff --git a/cc/output/filter_operations.h b/cc/output/filter_operations.h
deleted file mode 100644
index 55147d1..0000000
--- a/cc/output/filter_operations.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_FILTER_OPERATIONS_H_
-#define CC_OUTPUT_FILTER_OPERATIONS_H_
-
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/filter_operation.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class Value;
-}
-
-namespace cc {
-
-// An ordered list of filter operations.
-class FilterOperations {
- public:
-  FilterOperations();
-
-  FilterOperations(const FilterOperations& other);
-
-  ~FilterOperations();
-
-  FilterOperations& operator=(const FilterOperations& other);
-
-  bool operator==(const FilterOperations& other) const;
-
-  bool operator!=(const FilterOperations& other) const {
-    return !(*this == other);
-  }
-
-  void Append(const FilterOperation& filter);
-
-  // Removes all filter operations.
-  void Clear();
-
-  bool IsEmpty() const;
-
-  void GetOutsets(int* top, int* right, int* bottom, int* left) const;
-  bool HasFilterThatMovesPixels() const;
-  bool HasFilterThatAffectsOpacity() const;
-  bool HasReferenceFilter() const;
-
-  size_t size() const {
-    return operations_.size();
-  }
-
-  const FilterOperation& at(size_t index) const {
-    DCHECK_LT(index, size());
-    return operations_[index];
-  }
-
-  // If |from| is of the same size as this, where in each position, the filter
-  // in |from| is of the same type as the filter in this, and if this doesn't
-  // contain any reference filters, returns a FilterOperations formed by
-  // linearly interpolating at each position a |progress| fraction of the way
-  // from the filter in |from| to the filter in this. If |from| and this are of
-  // different lengths, they are treated as having the same length by padding
-  // the shorter sequence with no-op filters of the same type as the filters in
-  // the corresponding positions in the longer sequence. If either sequence has
-  // a reference filter or if there is a type mismatch at some position, returns
-  // a copy of this.
-  FilterOperations Blend(const FilterOperations& from, double progress) const;
-
-  void AsValueInto(base::trace_event::TracedValue* value) const;
-
- private:
-  std::vector<FilterOperation> operations_;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_FILTER_OPERATIONS_H_
diff --git a/cc/output/filter_operations_unittest.cc b/cc/output/filter_operations_unittest.cc
deleted file mode 100644
index d6ae6ab..0000000
--- a/cc/output/filter_operations_unittest.cc
+++ /dev/null
@@ -1,703 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/filter_operations.h"
-#include "skia/ext/refptr.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/effects/SkBlurImageFilter.h"
-#include "ui/gfx/geometry/point.h"
-
-namespace cc {
-namespace {
-
-TEST(FilterOperationsTest, GetOutsetsBlur) {
-  FilterOperations ops;
-  ops.Append(FilterOperation::CreateBlurFilter(20));
-  int top, right, bottom, left;
-  top = right = bottom = left = 0;
-  ops.GetOutsets(&top, &right, &bottom, &left);
-  EXPECT_EQ(57, top);
-  EXPECT_EQ(57, right);
-  EXPECT_EQ(57, bottom);
-  EXPECT_EQ(57, left);
-}
-
-TEST(FilterOperationsTest, GetOutsetsDropShadow) {
-  FilterOperations ops;
-  ops.Append(FilterOperation::CreateDropShadowFilter(gfx::Point(3, 8), 20, 0));
-  int top, right, bottom, left;
-  top = right = bottom = left = 0;
-  ops.GetOutsets(&top, &right, &bottom, &left);
-  EXPECT_EQ(49, top);
-  EXPECT_EQ(60, right);
-  EXPECT_EQ(65, bottom);
-  EXPECT_EQ(54, left);
-}
-
-#define SAVE_RESTORE_AMOUNT(filter_name, filter_type, a)                  \
-  {                                                                       \
-    FilterOperation op = FilterOperation::Create##filter_name##Filter(a); \
-    EXPECT_EQ(FilterOperation::filter_type, op.type());                   \
-    EXPECT_EQ(a, op.amount());                                            \
-                                                                          \
-    FilterOperation op2 = FilterOperation::CreateEmptyFilter();           \
-    op2.set_type(FilterOperation::filter_type);                           \
-                                                                          \
-    EXPECT_NE(a, op2.amount());                                           \
-                                                                          \
-    op2.set_amount(a);                                                    \
-                                                                          \
-    EXPECT_EQ(FilterOperation::filter_type, op2.type());                  \
-    EXPECT_EQ(a, op2.amount());                                           \
-  }
-
-#define SAVE_RESTORE_OFFSET_AMOUNT_COLOR(filter_name, filter_type, a, b, c) \
-  {                                                                         \
-    FilterOperation op =                                                    \
-        FilterOperation::Create##filter_name##Filter(a, b, c);              \
-    EXPECT_EQ(FilterOperation::filter_type, op.type());                     \
-    EXPECT_EQ(a, op.drop_shadow_offset());                                  \
-    EXPECT_EQ(b, op.amount());                                              \
-    EXPECT_EQ(c, op.drop_shadow_color());                                   \
-                                                                            \
-    FilterOperation op2 = FilterOperation::CreateEmptyFilter();             \
-    op2.set_type(FilterOperation::filter_type);                             \
-                                                                            \
-    EXPECT_NE(a, op2.drop_shadow_offset());                                 \
-    EXPECT_NE(b, op2.amount());                                             \
-    EXPECT_NE(c, op2.drop_shadow_color());                                  \
-                                                                            \
-    op2.set_drop_shadow_offset(a);                                          \
-    op2.set_amount(b);                                                      \
-    op2.set_drop_shadow_color(c);                                           \
-                                                                            \
-    EXPECT_EQ(FilterOperation::filter_type, op2.type());                    \
-    EXPECT_EQ(a, op2.drop_shadow_offset());                                 \
-    EXPECT_EQ(b, op2.amount());                                             \
-    EXPECT_EQ(c, op2.drop_shadow_color());                                  \
-  }
-
-#define SAVE_RESTORE_MATRIX(filter_name, filter_type, a)                  \
-  {                                                                       \
-    FilterOperation op = FilterOperation::Create##filter_name##Filter(a); \
-    EXPECT_EQ(FilterOperation::filter_type, op.type());                   \
-    for (size_t i = 0; i < 20; ++i)                                       \
-      EXPECT_EQ(a[i], op.matrix()[i]);                                    \
-                                                                          \
-    FilterOperation op2 = FilterOperation::CreateEmptyFilter();           \
-    op2.set_type(FilterOperation::filter_type);                           \
-                                                                          \
-    for (size_t i = 0; i < 20; ++i)                                       \
-      EXPECT_NE(a[i], op2.matrix()[i]);                                   \
-                                                                          \
-    op2.set_matrix(a);                                                    \
-                                                                          \
-    EXPECT_EQ(FilterOperation::filter_type, op2.type());                  \
-    for (size_t i = 0; i < 20; ++i)                                       \
-      EXPECT_EQ(a[i], op.matrix()[i]);                                    \
-  }
-
-#define SAVE_RESTORE_AMOUNT_INSET(filter_name, filter_type, a, b)            \
-  {                                                                          \
-    FilterOperation op = FilterOperation::Create##filter_name##Filter(a, b); \
-    EXPECT_EQ(FilterOperation::filter_type, op.type());                      \
-    EXPECT_EQ(a, op.amount());                                               \
-    EXPECT_EQ(b, op.zoom_inset());                                           \
-                                                                             \
-    FilterOperation op2 = FilterOperation::CreateEmptyFilter();              \
-    op2.set_type(FilterOperation::filter_type);                              \
-                                                                             \
-    EXPECT_NE(a, op2.amount());                                              \
-    EXPECT_NE(b, op2.zoom_inset());                                          \
-                                                                             \
-    op2.set_amount(a);                                                       \
-    op2.set_zoom_inset(b);                                                   \
-                                                                             \
-    EXPECT_EQ(FilterOperation::filter_type, op2.type());                     \
-    EXPECT_EQ(a, op2.amount());                                              \
-    EXPECT_EQ(b, op2.zoom_inset());                                          \
-  }
-
-TEST(FilterOperationsTest, SaveAndRestore) {
-  SAVE_RESTORE_AMOUNT(Grayscale, GRAYSCALE, 0.6f);
-  SAVE_RESTORE_AMOUNT(Sepia, SEPIA, 0.6f);
-  SAVE_RESTORE_AMOUNT(Saturate, SATURATE, 0.6f);
-  SAVE_RESTORE_AMOUNT(HueRotate, HUE_ROTATE, 0.6f);
-  SAVE_RESTORE_AMOUNT(Invert, INVERT, 0.6f);
-  SAVE_RESTORE_AMOUNT(Brightness, BRIGHTNESS, 0.6f);
-  SAVE_RESTORE_AMOUNT(Contrast, CONTRAST, 0.6f);
-  SAVE_RESTORE_AMOUNT(Opacity, OPACITY, 0.6f);
-  SAVE_RESTORE_AMOUNT(Blur, BLUR, 0.6f);
-  SAVE_RESTORE_AMOUNT(SaturatingBrightness, SATURATING_BRIGHTNESS, 0.6f);
-  SAVE_RESTORE_OFFSET_AMOUNT_COLOR(
-      DropShadow, DROP_SHADOW, gfx::Point(3, 4), 0.4f, 0xffffff00);
-
-  SkScalar matrix[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-                         17, 18, 19, 20};
-  SAVE_RESTORE_MATRIX(ColorMatrix, COLOR_MATRIX, matrix);
-
-  SAVE_RESTORE_AMOUNT_INSET(Zoom, ZOOM, 0.5f, 32);
-}
-
-TEST(FilterOperationsTest, BlendGrayscaleFilters) {
-  FilterOperation from = FilterOperation::CreateGrayscaleFilter(0.25f);
-  FilterOperation to = FilterOperation::CreateGrayscaleFilter(0.75f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateGrayscaleFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateGrayscaleFilter(0.625f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.8);
-  expected = FilterOperation::CreateGrayscaleFilter(1.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendGrayscaleWithNull) {
-  FilterOperation filter = FilterOperation::CreateGrayscaleFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateGrayscaleFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateGrayscaleFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSepiaFilters) {
-  FilterOperation from = FilterOperation::CreateSepiaFilter(0.25f);
-  FilterOperation to = FilterOperation::CreateSepiaFilter(0.75f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateSepiaFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateSepiaFilter(0.625f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.8);
-  expected = FilterOperation::CreateSepiaFilter(1.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSepiaWithNull) {
-  FilterOperation filter = FilterOperation::CreateSepiaFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateSepiaFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateSepiaFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSaturateFilters) {
-  FilterOperation from = FilterOperation::CreateSaturateFilter(0.25f);
-  FilterOperation to = FilterOperation::CreateSaturateFilter(0.75f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateSaturateFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateSaturateFilter(0.625f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 2.0);
-  expected = FilterOperation::CreateSaturateFilter(1.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSaturateWithNull) {
-  FilterOperation filter = FilterOperation::CreateSaturateFilter(0.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateSaturateFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateSaturateFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendHueRotateFilters) {
-  FilterOperation from = FilterOperation::CreateHueRotateFilter(3.f);
-  FilterOperation to = FilterOperation::CreateHueRotateFilter(7.f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateHueRotateFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateHueRotateFilter(6.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateHueRotateFilter(9.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendHueRotateWithNull) {
-  FilterOperation filter = FilterOperation::CreateHueRotateFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateHueRotateFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateHueRotateFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendInvertFilters) {
-  FilterOperation from = FilterOperation::CreateInvertFilter(0.25f);
-  FilterOperation to = FilterOperation::CreateInvertFilter(0.75f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateInvertFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateInvertFilter(0.625f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.8);
-  expected = FilterOperation::CreateInvertFilter(1.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendInvertWithNull) {
-  FilterOperation filter = FilterOperation::CreateInvertFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateInvertFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateInvertFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendBrightnessFilters) {
-  FilterOperation from = FilterOperation::CreateBrightnessFilter(3.f);
-  FilterOperation to = FilterOperation::CreateBrightnessFilter(7.f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
-  FilterOperation expected = FilterOperation::CreateBrightnessFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateBrightnessFilter(6.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateBrightnessFilter(9.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendBrightnessWithNull) {
-  FilterOperation filter = FilterOperation::CreateBrightnessFilter(0.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateBrightnessFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateBrightnessFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendContrastFilters) {
-  FilterOperation from = FilterOperation::CreateContrastFilter(3.f);
-  FilterOperation to = FilterOperation::CreateContrastFilter(7.f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
-  FilterOperation expected = FilterOperation::CreateContrastFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateContrastFilter(6.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateContrastFilter(9.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendContrastWithNull) {
-  FilterOperation filter = FilterOperation::CreateContrastFilter(0.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateContrastFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateContrastFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendOpacityFilters) {
-  FilterOperation from = FilterOperation::CreateOpacityFilter(0.25f);
-  FilterOperation to = FilterOperation::CreateOpacityFilter(0.75f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateOpacityFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateOpacityFilter(0.625f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.8);
-  expected = FilterOperation::CreateOpacityFilter(1.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendOpacityWithNull) {
-  FilterOperation filter = FilterOperation::CreateOpacityFilter(0.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateOpacityFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateOpacityFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendBlurFilters) {
-  FilterOperation from = FilterOperation::CreateBlurFilter(3.f);
-  FilterOperation to = FilterOperation::CreateBlurFilter(7.f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.9);
-  FilterOperation expected = FilterOperation::CreateBlurFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateBlurFilter(6.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateBlurFilter(9.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendBlurWithNull) {
-  FilterOperation filter = FilterOperation::CreateBlurFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateBlurFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateBlurFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendDropShadowFilters) {
-  FilterOperation from = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(0, 0), 2.f, SkColorSetARGB(15, 34, 68, 136));
-  FilterOperation to = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(3, 5), 6.f, SkColorSetARGB(51, 30, 60, 120));
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(-2, -4), 0.f, SkColorSetARGB(0, 0, 0, 0));
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.25);
-  expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(1, 1), 3.f, SkColorSetARGB(24, 32, 64, 128));
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(2, 4), 5.f, SkColorSetARGB(42, 30, 61, 121));
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(5, 8), 8.f, SkColorSetARGB(69, 30, 59, 118));
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendDropShadowWithNull) {
-  FilterOperation filter = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(4, 4), 4.f, SkColorSetARGB(255, 40, 0, 0));
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(3, 3), 3.f, SkColorSetARGB(191, 40, 0, 0));
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateDropShadowFilter(
-      gfx::Point(1, 1), 1.f, SkColorSetARGB(64, 40, 0, 0));
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendZoomFilters) {
-  FilterOperation from = FilterOperation::CreateZoomFilter(2.f, 3);
-  FilterOperation to = FilterOperation::CreateZoomFilter(6.f, 0);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected = FilterOperation::CreateZoomFilter(1.f, 5);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateZoomFilter(5.f, 1);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateZoomFilter(8.f, 0);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendZoomWithNull) {
-  FilterOperation filter = FilterOperation::CreateZoomFilter(2.f, 1);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected = FilterOperation::CreateZoomFilter(1.75f, 1);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateZoomFilter(1.25f, 0);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSaturatingBrightnessFilters) {
-  FilterOperation from = FilterOperation::CreateSaturatingBrightnessFilter(3.f);
-  FilterOperation to = FilterOperation::CreateSaturatingBrightnessFilter(7.f);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  FilterOperation expected =
-      FilterOperation::CreateSaturatingBrightnessFilter(0.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.75);
-  expected = FilterOperation::CreateSaturatingBrightnessFilter(6.f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  expected = FilterOperation::CreateSaturatingBrightnessFilter(9.f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendSaturatingBrightnessWithNull) {
-  FilterOperation filter =
-      FilterOperation::CreateSaturatingBrightnessFilter(1.f);
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  FilterOperation expected =
-      FilterOperation::CreateSaturatingBrightnessFilter(0.75f);
-  EXPECT_EQ(expected, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  expected = FilterOperation::CreateSaturatingBrightnessFilter(0.25f);
-  EXPECT_EQ(expected, blended);
-}
-
-TEST(FilterOperationsTest, BlendReferenceFilters) {
-  skia::RefPtr<SkImageFilter> from_filter =
-      skia::AdoptRef(SkBlurImageFilter::Create(1.f, 1.f));
-  skia::RefPtr<SkImageFilter> to_filter =
-      skia::AdoptRef(SkBlurImageFilter::Create(2.f, 2.f));
-  FilterOperation from = FilterOperation::CreateReferenceFilter(from_filter);
-  FilterOperation to = FilterOperation::CreateReferenceFilter(to_filter);
-
-  FilterOperation blended = FilterOperation::Blend(&from, &to, -0.75);
-  EXPECT_EQ(from, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.5);
-  EXPECT_EQ(from, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 0.6);
-  EXPECT_EQ(to, blended);
-
-  blended = FilterOperation::Blend(&from, &to, 1.5);
-  EXPECT_EQ(to, blended);
-}
-
-TEST(FilterOperationsTest, BlendReferenceWithNull) {
-  skia::RefPtr<SkImageFilter> image_filter =
-      skia::AdoptRef(SkBlurImageFilter::Create(1.f, 1.f));
-  FilterOperation filter = FilterOperation::CreateReferenceFilter(image_filter);
-  FilterOperation null_filter =
-      FilterOperation::CreateReferenceFilter(skia::RefPtr<SkImageFilter>());
-
-  FilterOperation blended = FilterOperation::Blend(&filter, NULL, 0.25);
-  EXPECT_EQ(filter, blended);
-  blended = FilterOperation::Blend(&filter, NULL, 0.75);
-  EXPECT_EQ(null_filter, blended);
-
-  blended = FilterOperation::Blend(NULL, &filter, 0.25);
-  EXPECT_EQ(null_filter, blended);
-  blended = FilterOperation::Blend(NULL, &filter, 0.75);
-  EXPECT_EQ(filter, blended);
-}
-
-// Tests blending non-empty sequences that have the same length and matching
-// operations.
-TEST(FilterOperationsTest, BlendMatchingSequences) {
-  FilterOperations from;
-  FilterOperations to;
-
-  from.Append(FilterOperation::CreateBlurFilter(0.f));
-  to.Append(FilterOperation::CreateBlurFilter(2.f));
-
-  from.Append(FilterOperation::CreateSaturateFilter(4.f));
-  to.Append(FilterOperation::CreateSaturateFilter(0.f));
-
-  from.Append(FilterOperation::CreateZoomFilter(2.0f, 1));
-  to.Append(FilterOperation::CreateZoomFilter(10.f, 9));
-
-  FilterOperations blended = to.Blend(from, -0.75);
-  FilterOperations expected;
-  expected.Append(FilterOperation::CreateBlurFilter(0.f));
-  expected.Append(FilterOperation::CreateSaturateFilter(7.f));
-  expected.Append(FilterOperation::CreateZoomFilter(1.f, 0));
-  EXPECT_EQ(blended, expected);
-
-  blended = to.Blend(from, 0.75);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateBlurFilter(1.5f));
-  expected.Append(FilterOperation::CreateSaturateFilter(1.f));
-  expected.Append(FilterOperation::CreateZoomFilter(8.f, 7));
-  EXPECT_EQ(blended, expected);
-
-  blended = to.Blend(from, 1.5);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateBlurFilter(3.f));
-  expected.Append(FilterOperation::CreateSaturateFilter(0.f));
-  expected.Append(FilterOperation::CreateZoomFilter(14.f, 13));
-  EXPECT_EQ(blended, expected);
-}
-
-TEST(FilterOperationsTest, BlendEmptyAndNonEmptySequences) {
-  FilterOperations empty;
-  FilterOperations filters;
-
-  filters.Append(FilterOperation::CreateGrayscaleFilter(0.75f));
-  filters.Append(FilterOperation::CreateBrightnessFilter(2.f));
-  filters.Append(FilterOperation::CreateHueRotateFilter(10.0f));
-
-  FilterOperations blended = empty.Blend(filters, -0.75);
-  FilterOperations expected;
-  expected.Append(FilterOperation::CreateGrayscaleFilter(1.f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(2.75f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(17.5f));
-  EXPECT_EQ(blended, expected);
-
-  blended = empty.Blend(filters, 0.75);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateGrayscaleFilter(0.1875f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(1.25f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(2.5f));
-  EXPECT_EQ(blended, expected);
-
-  blended = empty.Blend(filters, 1.5);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateGrayscaleFilter(0.f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(0.5f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(-5.f));
-  EXPECT_EQ(blended, expected);
-
-  blended = filters.Blend(empty, -0.75);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateGrayscaleFilter(0.f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(0.25f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(-7.5f));
-  EXPECT_EQ(blended, expected);
-
-  blended = filters.Blend(empty, 0.75);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateGrayscaleFilter(0.5625f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(1.75f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(7.5f));
-  EXPECT_EQ(blended, expected);
-
-  blended = filters.Blend(empty, 1.5);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateGrayscaleFilter(1.f));
-  expected.Append(FilterOperation::CreateBrightnessFilter(2.5f));
-  expected.Append(FilterOperation::CreateHueRotateFilter(15.f));
-  EXPECT_EQ(blended, expected);
-}
-
-TEST(FilterOperationsTest, BlendEmptySequences) {
-  FilterOperations empty;
-
-  FilterOperations blended = empty.Blend(empty, -0.75);
-  EXPECT_EQ(blended, empty);
-
-  blended = empty.Blend(empty, 0.75);
-  EXPECT_EQ(blended, empty);
-
-  blended = empty.Blend(empty, 1.5);
-  EXPECT_EQ(blended, empty);
-}
-
-// Tests blending non-empty sequences that have non-matching operations.
-TEST(FilterOperationsTest, BlendNonMatchingSequences) {
-  FilterOperations from;
-  FilterOperations to;
-
-  from.Append(FilterOperation::CreateSaturateFilter(3.f));
-  from.Append(FilterOperation::CreateBlurFilter(2.f));
-  to.Append(FilterOperation::CreateSaturateFilter(4.f));
-  to.Append(FilterOperation::CreateHueRotateFilter(0.5f));
-
-  FilterOperations blended = to.Blend(from, -0.75);
-  EXPECT_EQ(to, blended);
-  blended = to.Blend(from, 0.75);
-  EXPECT_EQ(to, blended);
-  blended = to.Blend(from, 1.5);
-  EXPECT_EQ(to, blended);
-}
-
-// Tests blending non-empty sequences of different sizes.
-TEST(FilterOperationsTest, BlendRaggedSequences) {
-  FilterOperations from;
-  FilterOperations to;
-
-  from.Append(FilterOperation::CreateSaturateFilter(3.f));
-  from.Append(FilterOperation::CreateBlurFilter(2.f));
-  to.Append(FilterOperation::CreateSaturateFilter(4.f));
-
-  FilterOperations blended = to.Blend(from, -0.75);
-  FilterOperations expected;
-  expected.Append(FilterOperation::CreateSaturateFilter(2.25f));
-  expected.Append(FilterOperation::CreateBlurFilter(3.5f));
-  EXPECT_EQ(expected, blended);
-
-  blended = to.Blend(from, 0.75);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateSaturateFilter(3.75f));
-  expected.Append(FilterOperation::CreateBlurFilter(0.5f));
-  EXPECT_EQ(expected, blended);
-
-  blended = to.Blend(from, 1.5);
-  expected.Clear();
-  expected.Append(FilterOperation::CreateSaturateFilter(4.5f));
-  expected.Append(FilterOperation::CreateBlurFilter(0.f));
-  EXPECT_EQ(expected, blended);
-
-  from.Append(FilterOperation::CreateOpacityFilter(1.f));
-  to.Append(FilterOperation::CreateOpacityFilter(1.f));
-  blended = to.Blend(from, -0.75);
-  EXPECT_EQ(to, blended);
-  blended = to.Blend(from, 0.75);
-  EXPECT_EQ(to, blended);
-  blended = to.Blend(from, 1.5);
-  EXPECT_EQ(to, blended);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/geometry_binding.cc b/cc/output/geometry_binding.cc
deleted file mode 100644
index 88a37de..0000000
--- a/cc/output/geometry_binding.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/output/geometry_binding.h"
-
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace cc {
-
-void SetupGLContext(gpu::gles2::GLES2Interface* gl,
-                    GLuint quad_elements_vbo,
-                    GLuint quad_vertices_vbo) {
-  GLC(gl, gl->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo));
-
-  GLC(gl, gl->BindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo));
-  // OpenGL defines the last parameter to VertexAttribPointer as type
-  // "const GLvoid*" even though it is actually an offset into the buffer
-  // object's data store and not a pointer to the client's address space.
-  const void* offsets[3] = {
-      0,
-      reinterpret_cast<const void*>(3 * sizeof(float)),
-      reinterpret_cast<const void*>(5 * sizeof(float)),
-  };
-
-  GLC(gl,
-      gl->VertexAttribPointer(GeometryBinding::PositionAttribLocation(), 3,
-                              GL_FLOAT, false, 6 * sizeof(float), offsets[0]));
-  GLC(gl,
-      gl->VertexAttribPointer(GeometryBinding::TexCoordAttribLocation(), 2,
-                              GL_FLOAT, false, 6 * sizeof(float), offsets[1]));
-  GLC(gl,
-      gl->VertexAttribPointer(GeometryBinding::TriangleIndexAttribLocation(), 1,
-                              GL_FLOAT, false, 6 * sizeof(float), offsets[2]));
-  GLC(gl,
-      gl->EnableVertexAttribArray(GeometryBinding::PositionAttribLocation()));
-  GLC(gl,
-      gl->EnableVertexAttribArray(GeometryBinding::TexCoordAttribLocation()));
-  GLC(gl, gl->EnableVertexAttribArray(
-              GeometryBinding::TriangleIndexAttribLocation()));
-}
-
-GeometryBindingQuad::GeometryBindingQuad() {
-  v0 = {{0, 0, 0}, {0, 0}, 0};
-  v1 = {{0, 0, 0}, {0, 0}, 0};
-  v2 = {{0, 0, 0}, {0, 0}, 0};
-  v3 = {{0, 0, 0}, {0, 0}, 0};
-}
-
-GeometryBindingQuad::GeometryBindingQuad(const GeometryBindingVertex& vert0,
-                                         const GeometryBindingVertex& vert1,
-                                         const GeometryBindingVertex& vert2,
-                                         const GeometryBindingVertex& vert3) {
-  v0 = vert0;
-  v1 = vert1;
-  v2 = vert2;
-  v3 = vert3;
-}
-
-GeometryBindingQuadIndex::GeometryBindingQuadIndex() {
-  memset(data, 0x0, sizeof(data));
-}
-
-GeometryBindingQuadIndex::GeometryBindingQuadIndex(uint16 index0,
-                                                   uint16 index1,
-                                                   uint16 index2,
-                                                   uint16 index3,
-                                                   uint16 index4,
-                                                   uint16 index5) {
-  data[0] = index0;
-  data[1] = index1;
-  data[2] = index2;
-  data[3] = index3;
-  data[4] = index4;
-  data[5] = index5;
-}
-
-}  // namespace cc
diff --git a/cc/output/geometry_binding.h b/cc/output/geometry_binding.h
deleted file mode 100644
index ae68687..0000000
--- a/cc/output/geometry_binding.h
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_OUTPUT_GEOMETRY_BINDING_H_
-#define CC_OUTPUT_GEOMETRY_BINDING_H_
-
-#include "base/basictypes.h"
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace gfx {
-class QuadF;
-class Quad;
-class QuadIndex;
-class PointF;
-}
-
-namespace cc {
-
-struct GeometryBindingVertex {
-  float a_position[3];
-  float a_texCoord[2];
-  // Index of the vertex, divide by 4 to have the matrix for this quad.
-  float a_index;
-};
-
-struct GeometryBindingQuad {
-  GeometryBindingQuad();
-  GeometryBindingQuad(const GeometryBindingVertex& vert0,
-                      const GeometryBindingVertex& vert1,
-                      const GeometryBindingVertex& vert2,
-                      const GeometryBindingVertex& vert3);
-  GeometryBindingVertex v0, v1, v2, v3;
-};
-
-struct GeometryBindingQuadIndex {
-  GeometryBindingQuadIndex();
-  GeometryBindingQuadIndex(uint16 index0,
-                           uint16 index1,
-                           uint16 index2,
-                           uint16 index3,
-                           uint16 index4,
-                           uint16 index5);
-
-  uint16 data[6];
-};
-
-class DrawQuad;
-class DrawPolygon;
-
-struct GeometryBinding {
-  // All layer shaders share the same attribute locations for the vertex
-  // positions and texture coordinates. This allows switching shaders without
-  // rebinding attribute arrays.
-  static int PositionAttribLocation() { return 0; }
-  static int TexCoordAttribLocation() { return 1; }
-  static int TriangleIndexAttribLocation() { return 2; }
-};
-
-void SetupGLContext(gpu::gles2::GLES2Interface* gl,
-                    GLuint quad_elements_vbo,
-                    GLuint quad_vertices_vbo);
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_GEOMETRY_BINDING_H_
diff --git a/cc/output/gl_frame_data.cc b/cc/output/gl_frame_data.cc
deleted file mode 100644
index aa6cfbc..0000000
--- a/cc/output/gl_frame_data.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/gl_frame_data.h"
-
-namespace cc {
-
-GLFrameData::GLFrameData() : sync_point(0) {}
-
-GLFrameData::~GLFrameData() {}
-
-}  // namespace cc
diff --git a/cc/output/gl_frame_data.h b/cc/output/gl_frame_data.h
deleted file mode 100644
index 50f1c64..0000000
--- a/cc/output/gl_frame_data.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_GL_FRAME_DATA_H_
-#define CC_OUTPUT_GL_FRAME_DATA_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class GLFrameData {
- public:
-  GLFrameData();
-  ~GLFrameData();
-
-  gpu::Mailbox mailbox;
-  uint32 sync_point;
-  gfx::Size size;
-  gfx::Rect sub_buffer_rect;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_GL_FRAME_DATA_H_
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
deleted file mode 100644
index fe11f9d..0000000
--- a/cc/output/gl_renderer.cc
+++ /dev/null
@@ -1,3332 +0,0 @@
-// Copyright 2010 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.
-
-#include "cc/output/gl_renderer.h"
-
-#include <algorithm>
-#include <limits>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "build/build_config.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/math_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/context_provider.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/dynamic_geometry_binding.h"
-#include "cc/output/gl_frame_data.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/render_surface_filters.h"
-#include "cc/output/static_geometry_binding.h"
-#include "cc/quads/draw_polygon.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/resources/layer_quad.h"
-#include "cc/resources/scoped_resource.h"
-#include "cc/resources/texture_mailbox_deleter.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/common/gpu_memory_allocation.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkColorFilter.h"
-#include "third_party/skia/include/core/SkImage.h"
-#include "third_party/skia/include/core/SkSurface.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/GrTexture.h"
-#include "third_party/skia/include/gpu/SkGrTexturePixelRef.h"
-#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
-#include "ui/gfx/geometry/quad_f.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-namespace {
-
-bool NeedsIOSurfaceReadbackWorkaround() {
-#if defined(OS_MACOSX)
-  // This isn't strictly required in DumpRenderTree-mode when Mesa is used,
-  // but it doesn't seem to hurt.
-  return true;
-#else
-  return false;
-#endif
-}
-
-Float4 UVTransform(const TextureDrawQuad* quad) {
-  gfx::PointF uv0 = quad->uv_top_left;
-  gfx::PointF uv1 = quad->uv_bottom_right;
-  Float4 xform = {{uv0.x(), uv0.y(), uv1.x() - uv0.x(), uv1.y() - uv0.y()}};
-  if (quad->flipped) {
-    xform.data[1] = 1.0f - xform.data[1];
-    xform.data[3] = -xform.data[3];
-  }
-  return xform;
-}
-
-Float4 PremultipliedColor(SkColor color) {
-  const float factor = 1.0f / 255.0f;
-  const float alpha = SkColorGetA(color) * factor;
-
-  Float4 result = {
-      {SkColorGetR(color) * factor * alpha, SkColorGetG(color) * factor * alpha,
-       SkColorGetB(color) * factor * alpha, alpha}};
-  return result;
-}
-
-SamplerType SamplerTypeFromTextureTarget(GLenum target) {
-  switch (target) {
-    case GL_TEXTURE_2D:
-      return SAMPLER_TYPE_2D;
-    case GL_TEXTURE_RECTANGLE_ARB:
-      return SAMPLER_TYPE_2D_RECT;
-    case GL_TEXTURE_EXTERNAL_OES:
-      return SAMPLER_TYPE_EXTERNAL_OES;
-    default:
-      NOTREACHED();
-      return SAMPLER_TYPE_2D;
-  }
-}
-
-BlendMode BlendModeFromSkXfermode(SkXfermode::Mode mode) {
-  switch (mode) {
-    case SkXfermode::kSrcOver_Mode:
-      return BLEND_MODE_NORMAL;
-    case SkXfermode::kScreen_Mode:
-      return BLEND_MODE_SCREEN;
-    case SkXfermode::kOverlay_Mode:
-      return BLEND_MODE_OVERLAY;
-    case SkXfermode::kDarken_Mode:
-      return BLEND_MODE_DARKEN;
-    case SkXfermode::kLighten_Mode:
-      return BLEND_MODE_LIGHTEN;
-    case SkXfermode::kColorDodge_Mode:
-      return BLEND_MODE_COLOR_DODGE;
-    case SkXfermode::kColorBurn_Mode:
-      return BLEND_MODE_COLOR_BURN;
-    case SkXfermode::kHardLight_Mode:
-      return BLEND_MODE_HARD_LIGHT;
-    case SkXfermode::kSoftLight_Mode:
-      return BLEND_MODE_SOFT_LIGHT;
-    case SkXfermode::kDifference_Mode:
-      return BLEND_MODE_DIFFERENCE;
-    case SkXfermode::kExclusion_Mode:
-      return BLEND_MODE_EXCLUSION;
-    case SkXfermode::kMultiply_Mode:
-      return BLEND_MODE_MULTIPLY;
-    case SkXfermode::kHue_Mode:
-      return BLEND_MODE_HUE;
-    case SkXfermode::kSaturation_Mode:
-      return BLEND_MODE_SATURATION;
-    case SkXfermode::kColor_Mode:
-      return BLEND_MODE_COLOR;
-    case SkXfermode::kLuminosity_Mode:
-      return BLEND_MODE_LUMINOSITY;
-    default:
-      NOTREACHED();
-      return BLEND_MODE_NONE;
-  }
-}
-
-// Smallest unit that impact anti-aliasing output. We use this to
-// determine when anti-aliasing is unnecessary.
-const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
-
-// Block or crash if the number of pending sync queries reach this high as
-// something is seriously wrong on the service side if this happens.
-const size_t kMaxPendingSyncQueries = 16;
-
-}  // anonymous namespace
-
-static GLint GetActiveTextureUnit(GLES2Interface* gl) {
-  GLint active_unit = 0;
-  gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
-  return active_unit;
-}
-
-struct GLRenderer::PendingAsyncReadPixels {
-  PendingAsyncReadPixels() : buffer(0) {}
-
-  scoped_ptr<CopyOutputRequest> copy_request;
-  base::CancelableClosure finished_read_pixels_callback;
-  unsigned buffer;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels);
-};
-
-class GLRenderer::SyncQuery {
- public:
-  explicit SyncQuery(gpu::gles2::GLES2Interface* gl)
-      : gl_(gl), query_id_(0u), is_pending_(false), weak_ptr_factory_(this) {
-    gl_->GenQueriesEXT(1, &query_id_);
-  }
-  virtual ~SyncQuery() { gl_->DeleteQueriesEXT(1, &query_id_); }
-
-  scoped_refptr<ResourceProvider::Fence> Begin() {
-    DCHECK(!IsPending());
-    // Invalidate weak pointer held by old fence.
-    weak_ptr_factory_.InvalidateWeakPtrs();
-    // Note: In case the set of drawing commands issued before End() do not
-    // depend on the query, defer BeginQueryEXT call until Set() is called and
-    // query is required.
-    return make_scoped_refptr<ResourceProvider::Fence>(
-        new Fence(weak_ptr_factory_.GetWeakPtr()));
-  }
-
-  void Set() {
-    if (is_pending_)
-      return;
-
-    // Note: BeginQueryEXT on GL_COMMANDS_COMPLETED_CHROMIUM is effectively a
-    // noop relative to GL, so it doesn't matter where it happens but we still
-    // make sure to issue this command when Set() is called (prior to issuing
-    // any drawing commands that depend on query), in case some future extension
-    // can take advantage of this.
-    gl_->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM, query_id_);
-    is_pending_ = true;
-  }
-
-  void End() {
-    if (!is_pending_)
-      return;
-
-    gl_->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
-  }
-
-  bool IsPending() {
-    if (!is_pending_)
-      return false;
-
-    unsigned result_available = 1;
-    gl_->GetQueryObjectuivEXT(
-        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &result_available);
-    is_pending_ = !result_available;
-    return is_pending_;
-  }
-
-  void Wait() {
-    if (!is_pending_)
-      return;
-
-    unsigned result = 0;
-    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &result);
-    is_pending_ = false;
-  }
-
- private:
-  class Fence : public ResourceProvider::Fence {
-   public:
-    explicit Fence(base::WeakPtr<GLRenderer::SyncQuery> query)
-        : query_(query) {}
-
-    // Overridden from ResourceProvider::Fence:
-    void Set() override {
-      DCHECK(query_);
-      query_->Set();
-    }
-    bool HasPassed() override { return !query_ || !query_->IsPending(); }
-    void Wait() override {
-      if (query_)
-        query_->Wait();
-    }
-
-   private:
-    ~Fence() override {}
-
-    base::WeakPtr<SyncQuery> query_;
-
-    DISALLOW_COPY_AND_ASSIGN(Fence);
-  };
-
-  gpu::gles2::GLES2Interface* gl_;
-  unsigned query_id_;
-  bool is_pending_;
-  base::WeakPtrFactory<SyncQuery> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SyncQuery);
-};
-
-scoped_ptr<GLRenderer> GLRenderer::Create(
-    RendererClient* client,
-    const RendererSettings* settings,
-    OutputSurface* output_surface,
-    ResourceProvider* resource_provider,
-    TextureMailboxDeleter* texture_mailbox_deleter,
-    int highp_threshold_min) {
-  return make_scoped_ptr(new GLRenderer(client,
-                                        settings,
-                                        output_surface,
-                                        resource_provider,
-                                        texture_mailbox_deleter,
-                                        highp_threshold_min));
-}
-
-GLRenderer::GLRenderer(RendererClient* client,
-                       const RendererSettings* settings,
-                       OutputSurface* output_surface,
-                       ResourceProvider* resource_provider,
-                       TextureMailboxDeleter* texture_mailbox_deleter,
-                       int highp_threshold_min)
-    : DirectRenderer(client, settings, output_surface, resource_provider),
-      offscreen_framebuffer_id_(0),
-      shared_geometry_quad_(QuadVertexRect()),
-      gl_(output_surface->context_provider()->ContextGL()),
-      context_support_(output_surface->context_provider()->ContextSupport()),
-      texture_mailbox_deleter_(texture_mailbox_deleter),
-      is_backbuffer_discarded_(false),
-      is_scissor_enabled_(false),
-      scissor_rect_needs_reset_(true),
-      stencil_shadow_(false),
-      blend_shadow_(false),
-      highp_threshold_min_(highp_threshold_min),
-      highp_threshold_cache_(0),
-      use_sync_query_(false),
-      on_demand_tile_raster_resource_id_(0),
-      bound_geometry_(NO_BINDING) {
-  DCHECK(gl_);
-  DCHECK(context_support_);
-
-  ContextProvider::Capabilities context_caps =
-      output_surface_->context_provider()->ContextCapabilities();
-
-  capabilities_.using_partial_swap =
-      settings_->partial_swap_enabled && context_caps.gpu.post_sub_buffer;
-
-  DCHECK(!context_caps.gpu.iosurface || context_caps.gpu.texture_rectangle);
-
-  capabilities_.using_egl_image = context_caps.gpu.egl_image_external;
-
-  capabilities_.max_texture_size = resource_provider_->max_texture_size();
-  capabilities_.best_texture_format = resource_provider_->best_texture_format();
-
-  // The updater can access textures while the GLRenderer is using them.
-  capabilities_.allow_partial_texture_updates = true;
-
-  capabilities_.using_image = context_caps.gpu.image;
-
-  capabilities_.using_discard_framebuffer =
-      context_caps.gpu.discard_framebuffer;
-
-  capabilities_.allow_rasterize_on_demand = true;
-
-  use_sync_query_ = context_caps.gpu.sync_query;
-  use_blend_equation_advanced_ = context_caps.gpu.blend_equation_advanced;
-  use_blend_equation_advanced_coherent_ =
-      context_caps.gpu.blend_equation_advanced_coherent;
-
-  InitializeSharedObjects();
-}
-
-GLRenderer::~GLRenderer() {
-  while (!pending_async_read_pixels_.empty()) {
-    PendingAsyncReadPixels* pending_read = pending_async_read_pixels_.back();
-    pending_read->finished_read_pixels_callback.Cancel();
-    pending_async_read_pixels_.pop_back();
-  }
-
-  in_use_overlay_resources_.clear();
-
-  CleanupSharedObjects();
-}
-
-const RendererCapabilitiesImpl& GLRenderer::Capabilities() const {
-  return capabilities_;
-}
-
-void GLRenderer::DebugGLCall(GLES2Interface* gl,
-                             const char* command,
-                             const char* file,
-                             int line) {
-  GLuint error = gl->GetError();
-  if (error != GL_NO_ERROR)
-    LOG(ERROR) << "GL command failed: File: " << file << "\n\tLine " << line
-               << "\n\tcommand: " << command << ", error "
-               << static_cast<int>(error) << "\n";
-}
-
-void GLRenderer::DidChangeVisibility() {
-  EnforceMemoryPolicy();
-
-  context_support_->SetSurfaceVisible(visible());
-}
-
-void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); }
-
-void GLRenderer::DiscardPixels() {
-  if (!capabilities_.using_discard_framebuffer)
-    return;
-  bool using_default_framebuffer =
-      !current_framebuffer_lock_ &&
-      output_surface_->capabilities().uses_default_gl_framebuffer;
-  GLenum attachments[] = {static_cast<GLenum>(
-      using_default_framebuffer ? GL_COLOR_EXT : GL_COLOR_ATTACHMENT0_EXT)};
-  gl_->DiscardFramebufferEXT(
-      GL_FRAMEBUFFER, arraysize(attachments), attachments);
-}
-
-void GLRenderer::PrepareSurfaceForPass(
-    DrawingFrame* frame,
-    SurfaceInitializationMode initialization_mode,
-    const gfx::Rect& render_pass_scissor) {
-  switch (initialization_mode) {
-    case SURFACE_INITIALIZATION_MODE_PRESERVE:
-      EnsureScissorTestDisabled();
-      return;
-    case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR:
-      EnsureScissorTestDisabled();
-      DiscardPixels();
-      ClearFramebuffer(frame);
-      break;
-    case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR:
-      SetScissorTestRect(render_pass_scissor);
-      ClearFramebuffer(frame);
-      break;
-  }
-}
-
-void GLRenderer::ClearFramebuffer(DrawingFrame* frame) {
-  // On DEBUG builds, opaque render passes are cleared to blue to easily see
-  // regions that were not drawn on the screen.
-  if (frame->current_render_pass->has_transparent_background)
-    GLC(gl_, gl_->ClearColor(0, 0, 0, 0));
-  else
-    GLC(gl_, gl_->ClearColor(0, 0, 1, 1));
-
-  bool always_clear = false;
-#ifndef NDEBUG
-  always_clear = true;
-#endif
-  if (always_clear || frame->current_render_pass->has_transparent_background) {
-    GLbitfield clear_bits = GL_COLOR_BUFFER_BIT;
-    if (always_clear)
-      clear_bits |= GL_STENCIL_BUFFER_BIT;
-    gl_->Clear(clear_bits);
-  }
-}
-
-static ResourceProvider::ResourceId WaitOnResourceSyncPoints(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id) {
-  resource_provider->WaitSyncPointIfNeeded(resource_id);
-  return resource_id;
-}
-
-void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) {
-  TRACE_EVENT0("cc", "GLRenderer::BeginDrawingFrame");
-
-  scoped_refptr<ResourceProvider::Fence> read_lock_fence;
-  if (use_sync_query_) {
-    // Block until oldest sync query has passed if the number of pending queries
-    // ever reach kMaxPendingSyncQueries.
-    if (pending_sync_queries_.size() >= kMaxPendingSyncQueries) {
-      LOG(ERROR) << "Reached limit of pending sync queries.";
-
-      pending_sync_queries_.front()->Wait();
-      DCHECK(!pending_sync_queries_.front()->IsPending());
-    }
-
-    while (!pending_sync_queries_.empty()) {
-      if (pending_sync_queries_.front()->IsPending())
-        break;
-
-      available_sync_queries_.push_back(pending_sync_queries_.take_front());
-    }
-
-    current_sync_query_ = available_sync_queries_.empty()
-                              ? make_scoped_ptr(new SyncQuery(gl_))
-                              : available_sync_queries_.take_front();
-
-    read_lock_fence = current_sync_query_->Begin();
-  } else {
-    read_lock_fence =
-        make_scoped_refptr(new ResourceProvider::SynchronousFence(gl_));
-  }
-  resource_provider_->SetReadLockFence(read_lock_fence.get());
-
-  // Insert WaitSyncPointCHROMIUM on quad resources prior to drawing the frame,
-  // so that drawing can proceed without GL context switching interruptions.
-  DrawQuad::ResourceIteratorCallback wait_on_resource_syncpoints_callback =
-      base::Bind(&WaitOnResourceSyncPoints, resource_provider_);
-
-  for (const auto& pass : *frame->render_passes_in_draw_order) {
-    for (const auto& quad : pass->quad_list)
-      quad->IterateResources(wait_on_resource_syncpoints_callback);
-  }
-
-  // TODO(enne): Do we need to reinitialize all of this state per frame?
-  ReinitializeGLState();
-}
-
-void GLRenderer::DoNoOp() {
-  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
-  GLC(gl_, gl_->Flush());
-}
-
-void GLRenderer::DoDrawQuad(DrawingFrame* frame,
-                            const DrawQuad* quad,
-                            const gfx::QuadF* clip_region) {
-  DCHECK(quad->rect.Contains(quad->visible_rect));
-  if (quad->material != DrawQuad::TEXTURE_CONTENT) {
-    FlushTextureQuadCache(SHARED_BINDING);
-  }
-
-  switch (quad->material) {
-    case DrawQuad::INVALID:
-    case DrawQuad::UNUSED_SPACE_FOR_PICTURE_CONTENT:
-      NOTREACHED();
-      break;
-    case DrawQuad::CHECKERBOARD:
-      DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad),
-                           clip_region);
-      break;
-    case DrawQuad::DEBUG_BORDER:
-      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::IO_SURFACE_CONTENT:
-      DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad),
-                        clip_region);
-      break;
-    case DrawQuad::RENDER_PASS:
-      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad),
-                         clip_region);
-      break;
-    case DrawQuad::SOLID_COLOR:
-      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad),
-                         clip_region);
-      break;
-    case DrawQuad::STREAM_VIDEO_CONTENT:
-      DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad),
-                          clip_region);
-      break;
-    case DrawQuad::SURFACE_CONTENT:
-      // Surface content should be fully resolved to other quad types before
-      // reaching a direct renderer.
-      NOTREACHED();
-      break;
-    case DrawQuad::TEXTURE_CONTENT:
-      EnqueueTextureQuad(frame, TextureDrawQuad::MaterialCast(quad),
-                         clip_region);
-      break;
-    case DrawQuad::TILED_CONTENT:
-      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad), clip_region);
-      break;
-    case DrawQuad::YUV_VIDEO_CONTENT:
-      DrawYUVVideoQuad(frame, YUVVideoDrawQuad::MaterialCast(quad),
-                       clip_region);
-      break;
-  }
-}
-
-void GLRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
-                                      const CheckerboardDrawQuad* quad,
-                                      const gfx::QuadF* clip_region) {
-  // TODO(enne) For now since checkerboards shouldn't be part of a 3D
-  // context, clipping regions aren't supported so we skip drawing them
-  // if this becomes the case.
-  if (clip_region) {
-    return;
-  }
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  const TileCheckerboardProgram* program = GetTileCheckerboardProgram();
-  DCHECK(program && (program->initialized() || IsContextLost()));
-  SetUseProgram(program->program());
-
-  SkColor color = quad->color;
-  GLC(gl_,
-      gl_->Uniform4f(program->fragment_shader().color_location(),
-                     SkColorGetR(color) * (1.0f / 255.0f),
-                     SkColorGetG(color) * (1.0f / 255.0f),
-                     SkColorGetB(color) * (1.0f / 255.0f),
-                     1));
-
-  const int kCheckerboardWidth = 16;
-  float frequency = 1.0f / kCheckerboardWidth;
-
-  gfx::Rect tile_rect = quad->rect;
-  float tex_offset_x =
-      static_cast<int>(tile_rect.x() / quad->scale) % kCheckerboardWidth;
-  float tex_offset_y =
-      static_cast<int>(tile_rect.y() / quad->scale) % kCheckerboardWidth;
-  float tex_scale_x = tile_rect.width() / quad->scale;
-  float tex_scale_y = tile_rect.height() / quad->scale;
-  GLC(gl_,
-      gl_->Uniform4f(program->fragment_shader().tex_transform_location(),
-                     tex_offset_x,
-                     tex_offset_y,
-                     tex_scale_x,
-                     tex_scale_y));
-
-  GLC(gl_,
-      gl_->Uniform1f(program->fragment_shader().frequency_location(),
-                     frequency));
-
-  SetShaderOpacity(quad->opacity(),
-                   program->fragment_shader().alpha_location());
-  DrawQuadGeometry(frame,
-                   quad->quadTransform(),
-                   quad->rect,
-                   program->vertex_shader().matrix_location());
-}
-
-// This function does not handle 3D sorting right now, since the debug border
-// quads are just drawn as their original quads and not in split pieces. This
-// results in some debug border quads drawing over foreground quads.
-void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
-                                     const DebugBorderDrawQuad* quad) {
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  static float gl_matrix[16];
-  const DebugBorderProgram* program = GetDebugBorderProgram();
-  DCHECK(program && (program->initialized() || IsContextLost()));
-  SetUseProgram(program->program());
-
-  // Use the full quad_rect for debug quads to not move the edges based on
-  // partial swaps.
-  gfx::Rect layer_rect = quad->rect;
-  gfx::Transform render_matrix;
-  QuadRectTransform(&render_matrix, quad->quadTransform(), layer_rect);
-  GLRenderer::ToGLMatrix(&gl_matrix[0],
-                         frame->projection_matrix * render_matrix);
-  GLC(gl_,
-      gl_->UniformMatrix4fv(
-          program->vertex_shader().matrix_location(), 1, false, &gl_matrix[0]));
-
-  SkColor color = quad->color;
-  float alpha = SkColorGetA(color) * (1.0f / 255.0f);
-
-  GLC(gl_,
-      gl_->Uniform4f(program->fragment_shader().color_location(),
-                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
-                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
-                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
-                     alpha));
-
-  GLC(gl_, gl_->LineWidth(quad->width));
-
-  // The indices for the line are stored in the same array as the triangle
-  // indices.
-  GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0));
-}
-
-bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
-  return use_blend_equation_advanced_ ||
-         blend_mode == SkXfermode::kScreen_Mode ||
-         blend_mode == SkXfermode::kSrcOver_Mode;
-}
-
-void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
-  DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode));
-
-  // Any modes set here must be reset in RestoreBlendFuncToDefault
-  if (use_blend_equation_advanced_) {
-    GLenum equation = GL_FUNC_ADD;
-
-    switch (blend_mode) {
-      case SkXfermode::kScreen_Mode:
-        equation = GL_SCREEN_KHR;
-        break;
-      case SkXfermode::kOverlay_Mode:
-        equation = GL_OVERLAY_KHR;
-        break;
-      case SkXfermode::kDarken_Mode:
-        equation = GL_DARKEN_KHR;
-        break;
-      case SkXfermode::kLighten_Mode:
-        equation = GL_LIGHTEN_KHR;
-        break;
-      case SkXfermode::kColorDodge_Mode:
-        equation = GL_COLORDODGE_KHR;
-        break;
-      case SkXfermode::kColorBurn_Mode:
-        equation = GL_COLORBURN_KHR;
-        break;
-      case SkXfermode::kHardLight_Mode:
-        equation = GL_HARDLIGHT_KHR;
-        break;
-      case SkXfermode::kSoftLight_Mode:
-        equation = GL_SOFTLIGHT_KHR;
-        break;
-      case SkXfermode::kDifference_Mode:
-        equation = GL_DIFFERENCE_KHR;
-        break;
-      case SkXfermode::kExclusion_Mode:
-        equation = GL_EXCLUSION_KHR;
-        break;
-      case SkXfermode::kMultiply_Mode:
-        equation = GL_MULTIPLY_KHR;
-        break;
-      case SkXfermode::kHue_Mode:
-        equation = GL_HSL_HUE_KHR;
-        break;
-      case SkXfermode::kSaturation_Mode:
-        equation = GL_HSL_SATURATION_KHR;
-        break;
-      case SkXfermode::kColor_Mode:
-        equation = GL_HSL_COLOR_KHR;
-        break;
-      case SkXfermode::kLuminosity_Mode:
-        equation = GL_HSL_LUMINOSITY_KHR;
-        break;
-      default:
-        return;
-    }
-
-    GLC(gl_, gl_->BlendEquation(equation));
-  } else {
-    if (blend_mode == SkXfermode::kScreen_Mode) {
-      GLC(gl_, gl_->BlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE));
-    }
-  }
-}
-
-void GLRenderer::RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode) {
-  if (blend_mode == SkXfermode::kSrcOver_Mode)
-    return;
-
-  if (use_blend_equation_advanced_) {
-    GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD));
-  } else {
-    GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
-  }
-}
-
-// This takes a gfx::Rect and a clip region quad in the same space,
-// and returns a quad with the same proportions in the space -0.5->0.5.
-bool GetScaledRegion(const gfx::Rect& rect,
-                     const gfx::QuadF* clip,
-                     gfx::QuadF* scaled_region) {
-  if (!clip)
-    return false;
-
-  gfx::PointF p1(((clip->p1().x() - rect.x()) / rect.width()) - 0.5f,
-                 ((clip->p1().y() - rect.y()) / rect.height()) - 0.5f);
-  gfx::PointF p2(((clip->p2().x() - rect.x()) / rect.width()) - 0.5f,
-                 ((clip->p2().y() - rect.y()) / rect.height()) - 0.5f);
-  gfx::PointF p3(((clip->p3().x() - rect.x()) / rect.width()) - 0.5f,
-                 ((clip->p3().y() - rect.y()) / rect.height()) - 0.5f);
-  gfx::PointF p4(((clip->p4().x() - rect.x()) / rect.width()) - 0.5f,
-                 ((clip->p4().y() - rect.y()) / rect.height()) - 0.5f);
-  *scaled_region = gfx::QuadF(p1, p2, p3, p4);
-  return true;
-}
-
-// This takes a gfx::Rect and a clip region quad in the same space,
-// and returns the proportional uv's in the space 0->1.
-bool GetScaledUVs(const gfx::Rect& rect, const gfx::QuadF* clip, float uvs[8]) {
-  if (!clip)
-    return false;
-
-  uvs[0] = ((clip->p1().x() - rect.x()) / rect.width());
-  uvs[1] = ((clip->p1().y() - rect.y()) / rect.height());
-  uvs[2] = ((clip->p2().x() - rect.x()) / rect.width());
-  uvs[3] = ((clip->p2().y() - rect.y()) / rect.height());
-  uvs[4] = ((clip->p3().x() - rect.x()) / rect.width());
-  uvs[5] = ((clip->p3().y() - rect.y()) / rect.height());
-  uvs[6] = ((clip->p4().x() - rect.x()) / rect.width());
-  uvs[7] = ((clip->p4().y() - rect.y()) / rect.height());
-  return true;
-}
-
-gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
-    DrawingFrame* frame,
-    const RenderPassDrawQuad* quad,
-    const gfx::Transform& contents_device_transform,
-    const gfx::QuadF* clip_region,
-    bool use_aa) {
-  gfx::QuadF scaled_region;
-  if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) {
-    scaled_region = SharedGeometryQuad().BoundingBox();
-  }
-
-  gfx::Rect backdrop_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect(
-      contents_device_transform, scaled_region.BoundingBox()));
-
-  if (!backdrop_rect.IsEmpty() && use_aa) {
-    const int kOutsetForAntialiasing = 1;
-    backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing);
-  }
-
-  backdrop_rect.Intersect(MoveFromDrawToWindowSpace(
-      frame, frame->current_render_pass->output_rect));
-  return backdrop_rect;
-}
-
-scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture(
-    const gfx::Rect& bounding_rect) {
-  scoped_ptr<ScopedResource> device_background_texture =
-      ScopedResource::Create(resource_provider_);
-  // CopyTexImage2D fails when called on a texture having immutable storage.
-  device_background_texture->Allocate(
-      bounding_rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888);
-  {
-    ResourceProvider::ScopedWriteLockGL lock(resource_provider_,
-                                             device_background_texture->id());
-    GetFramebufferTexture(
-        lock.texture_id(), device_background_texture->format(), bounding_rect);
-  }
-  return device_background_texture.Pass();
-}
-
-void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
-                                    const RenderPassDrawQuad* quad,
-                                    const gfx::QuadF* clip_region) {
-  ScopedResource* contents_texture =
-      render_pass_textures_.get(quad->render_pass_id);
-  if (!contents_texture || !contents_texture->id())
-    return;
-
-  gfx::Transform quad_rect_matrix;
-  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
-  gfx::Transform contents_device_transform =
-      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
-  contents_device_transform.FlattenTo2d();
-
-  // Can only draw surface if device matrix is invertible.
-  if (!contents_device_transform.IsInvertible())
-    return;
-
-  gfx::QuadF surface_quad = SharedGeometryQuad();
-  float edge[24];
-  bool use_aa = settings_->allow_antialiasing &&
-                ShouldAntialiasQuad(contents_device_transform, quad,
-                                    settings_->force_antialiasing);
-
-  SetupQuadForClippingAndAntialiasing(contents_device_transform, quad, use_aa,
-                                      clip_region, &surface_quad, edge);
-  SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode;
-  bool use_shaders_for_blending =
-      !CanApplyBlendModeUsingBlendFunc(blend_mode) ||
-      settings_->force_blending_with_shaders;
-
-  scoped_ptr<ScopedResource> background_texture;
-  skia::RefPtr<SkImage> background_image;
-  gfx::Rect background_rect;
-  if (use_shaders_for_blending) {
-    // Compute a bounding box around the pixels that will be visible through
-    // the quad.
-    background_rect = GetBackdropBoundingBoxForRenderPassQuad(
-        frame, quad, contents_device_transform, clip_region, use_aa);
-
-    if (!background_rect.IsEmpty()) {
-      // The pixels from the filtered background should completely replace the
-      // current pixel values.
-      if (blend_enabled())
-        SetBlendEnabled(false);
-
-      // Read the pixels in the bounding box into a buffer R.
-      // This function allocates a texture, which should contribute to the
-      // amount of memory used by render surfaces:
-      // LayerTreeHost::CalculateMemoryForRenderSurfaces.
-      background_texture = GetBackdropTexture(background_rect);
-    }
-
-    if (!background_texture) {
-      // Something went wrong with reading the backdrop.
-      DCHECK(!background_image);
-      use_shaders_for_blending = false;
-    } else if (background_image) {
-      // Reset original background texture if there is not any mask
-      if (!quad->mask_resource_id)
-        background_texture.reset();
-    }
-  }
-  // Need original background texture for mask?
-  bool mask_for_background =
-      background_texture &&    // Have original background texture
-      background_image &&      // Have filtered background texture
-      quad->mask_resource_id;  // Have mask texture
-  SetBlendEnabled(
-      !use_shaders_for_blending &&
-      (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
-
-  // TODO(senorblanco): Cache this value so that we don't have to do it for both
-  // the surface and its replica.  Apply filters to the contents texture.
-  skia::RefPtr<SkImage> filter_image;
-  SkScalar color_matrix[20];
-  bool use_color_matrix = false;
-  DCHECK(quad->filters.IsEmpty());
-
-  scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
-  unsigned mask_texture_id = 0;
-  SamplerType mask_sampler = SAMPLER_TYPE_NA;
-  if (quad->mask_resource_id) {
-    mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL(
-        resource_provider_, quad->mask_resource_id, GL_TEXTURE1, GL_LINEAR));
-    mask_texture_id = mask_resource_lock->texture_id();
-    mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target());
-  }
-
-  scoped_ptr<ResourceProvider::ScopedSamplerGL> contents_resource_lock;
-  if (filter_image) {
-    GrTexture* texture = filter_image->getTexture();
-    DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
-    gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
-  } else {
-    contents_resource_lock =
-        make_scoped_ptr(new ResourceProvider::ScopedSamplerGL(
-            resource_provider_, contents_texture->id(), GL_LINEAR));
-    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              contents_resource_lock->target());
-  }
-
-  if (!use_shaders_for_blending) {
-    if (!use_blend_equation_advanced_coherent_ && use_blend_equation_advanced_)
-      GLC(gl_, gl_->BlendBarrierKHR());
-
-    ApplyBlendModeUsingBlendFunc(blend_mode);
-  }
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_,
-      &highp_threshold_cache_,
-      highp_threshold_min_,
-      quad->shared_quad_state->visible_content_rect.bottom_right());
-
-  ShaderLocations locations;
-
-  DCHECK_EQ(background_texture || background_image, use_shaders_for_blending);
-  BlendMode shader_blend_mode = use_shaders_for_blending
-                                    ? BlendModeFromSkXfermode(blend_mode)
-                                    : BLEND_MODE_NONE;
-
-  if (use_aa && mask_texture_id && !use_color_matrix) {
-    const RenderPassMaskProgramAA* program = GetRenderPassMaskProgramAA(
-        tex_coord_precision, mask_sampler,
-        shader_blend_mode, mask_for_background);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (!use_aa && mask_texture_id && !use_color_matrix) {
-    const RenderPassMaskProgram* program = GetRenderPassMaskProgram(
-        tex_coord_precision, mask_sampler,
-        shader_blend_mode, mask_for_background);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (use_aa && !mask_texture_id && !use_color_matrix) {
-    const RenderPassProgramAA* program =
-        GetRenderPassProgramAA(tex_coord_precision, shader_blend_mode);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (use_aa && mask_texture_id && use_color_matrix) {
-    const RenderPassMaskColorMatrixProgramAA* program =
-        GetRenderPassMaskColorMatrixProgramAA(
-            tex_coord_precision, mask_sampler,
-            shader_blend_mode, mask_for_background);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (use_aa && !mask_texture_id && use_color_matrix) {
-    const RenderPassColorMatrixProgramAA* program =
-        GetRenderPassColorMatrixProgramAA(tex_coord_precision,
-                                          shader_blend_mode);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (!use_aa && mask_texture_id && use_color_matrix) {
-    const RenderPassMaskColorMatrixProgram* program =
-        GetRenderPassMaskColorMatrixProgram(
-            tex_coord_precision, mask_sampler,
-            shader_blend_mode, mask_for_background);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else if (!use_aa && !mask_texture_id && use_color_matrix) {
-    const RenderPassColorMatrixProgram* program =
-        GetRenderPassColorMatrixProgram(tex_coord_precision, shader_blend_mode);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  } else {
-    const RenderPassProgram* program =
-        GetRenderPassProgram(tex_coord_precision, shader_blend_mode);
-    SetUseProgram(program->program());
-    program->vertex_shader().FillLocations(&locations);
-    program->fragment_shader().FillLocations(&locations);
-    GLC(gl_, gl_->Uniform1i(locations.sampler, 0));
-  }
-  float tex_scale_x =
-      quad->rect.width() / static_cast<float>(contents_texture->size().width());
-  float tex_scale_y = quad->rect.height() /
-                      static_cast<float>(contents_texture->size().height());
-  DCHECK_LE(tex_scale_x, 1.0f);
-  DCHECK_LE(tex_scale_y, 1.0f);
-
-  DCHECK(locations.tex_transform != -1 || IsContextLost());
-  // Flip the content vertically in the shader, as the RenderPass input
-  // texture is already oriented the same way as the framebuffer, but the
-  // projection transform does a flip.
-  GLC(gl_,
-      gl_->Uniform4f(locations.tex_transform,
-                     0.0f,
-                     tex_scale_y,
-                     tex_scale_x,
-                     -tex_scale_y));
-
-  GLint last_texture_unit = 0;
-  if (locations.mask_sampler != -1) {
-    DCHECK_NE(locations.mask_tex_coord_scale, 1);
-    DCHECK_NE(locations.mask_tex_coord_offset, 1);
-    GLC(gl_, gl_->Uniform1i(locations.mask_sampler, 1));
-
-    gfx::RectF mask_uv_rect = quad->MaskUVRect();
-    if (mask_sampler != SAMPLER_TYPE_2D) {
-      mask_uv_rect.Scale(quad->mask_texture_size.width(),
-                         quad->mask_texture_size.height());
-    }
-
-    // Mask textures are oriented vertically flipped relative to the framebuffer
-    // and the RenderPass contents texture, so we flip the tex coords from the
-    // RenderPass texture to find the mask texture coords.
-    GLC(gl_,
-        gl_->Uniform2f(locations.mask_tex_coord_offset,
-                       mask_uv_rect.x(),
-                       mask_uv_rect.bottom()));
-    GLC(gl_,
-        gl_->Uniform2f(locations.mask_tex_coord_scale,
-                       mask_uv_rect.width() / tex_scale_x,
-                       -mask_uv_rect.height() / tex_scale_y));
-
-    last_texture_unit = 1;
-  }
-
-  if (locations.edge != -1)
-    GLC(gl_, gl_->Uniform3fv(locations.edge, 8, edge));
-
-  if (locations.viewport != -1) {
-    float viewport[4] = {static_cast<float>(viewport_.x()),
-                         static_cast<float>(viewport_.y()),
-                         static_cast<float>(viewport_.width()),
-                         static_cast<float>(viewport_.height()), };
-    GLC(gl_, gl_->Uniform4fv(locations.viewport, 1, viewport));
-  }
-
-  if (locations.color_matrix != -1) {
-    float matrix[16];
-    for (int i = 0; i < 4; ++i) {
-      for (int j = 0; j < 4; ++j)
-        matrix[i * 4 + j] = SkScalarToFloat(color_matrix[j * 5 + i]);
-    }
-    GLC(gl_,
-        gl_->UniformMatrix4fv(locations.color_matrix, 1, false, matrix));
-  }
-  static const float kScale = 1.0f / 255.0f;
-  if (locations.color_offset != -1) {
-    float offset[4];
-    for (int i = 0; i < 4; ++i)
-      offset[i] = SkScalarToFloat(color_matrix[i * 5 + 4]) * kScale;
-
-    GLC(gl_, gl_->Uniform4fv(locations.color_offset, 1, offset));
-  }
-
-  scoped_ptr<ResourceProvider::ScopedSamplerGL> shader_background_sampler_lock;
-  if (locations.backdrop != -1) {
-    DCHECK(background_texture || background_image);
-    DCHECK_NE(locations.backdrop, 0);
-    DCHECK_NE(locations.backdrop_rect, 0);
-
-    GLC(gl_, gl_->Uniform1i(locations.backdrop, ++last_texture_unit));
-
-    GLC(gl_,
-        gl_->Uniform4f(locations.backdrop_rect,
-                       background_rect.x(),
-                       background_rect.y(),
-                       background_rect.width(),
-                       background_rect.height()));
-
-    if (background_image) {
-      GrTexture* texture = background_image->getTexture();
-      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0 + last_texture_unit));
-      gl_->BindTexture(GL_TEXTURE_2D, texture->getTextureHandle());
-      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
-      if (mask_for_background)
-        GLC(gl_, gl_->Uniform1i(locations.original_backdrop,
-                                ++last_texture_unit));
-    }
-    if (background_texture) {
-      shader_background_sampler_lock = make_scoped_ptr(
-          new ResourceProvider::ScopedSamplerGL(resource_provider_,
-                                                background_texture->id(),
-                                                GL_TEXTURE0 + last_texture_unit,
-                                                GL_LINEAR));
-      DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-                shader_background_sampler_lock->target());
-    }
-  }
-
-  SetShaderOpacity(quad->opacity(), locations.alpha);
-  SetShaderQuadF(surface_quad, locations.quad);
-  DrawQuadGeometry(
-      frame, quad->quadTransform(), quad->rect, locations.matrix);
-
-  // Flush the compositor context before the filter bitmap goes out of
-  // scope, so the draw gets processed before the filter texture gets deleted.
-  if (filter_image)
-    GLC(gl_, gl_->Flush());
-
-  if (!use_shaders_for_blending)
-    RestoreBlendFuncToDefault(blend_mode);
-}
-
-struct SolidColorProgramUniforms {
-  unsigned program;
-  unsigned matrix_location;
-  unsigned viewport_location;
-  unsigned quad_location;
-  unsigned edge_location;
-  unsigned color_location;
-};
-
-template <class T>
-static void SolidColorUniformLocation(T program,
-                                      SolidColorProgramUniforms* uniforms) {
-  uniforms->program = program->program();
-  uniforms->matrix_location = program->vertex_shader().matrix_location();
-  uniforms->viewport_location = program->vertex_shader().viewport_location();
-  uniforms->quad_location = program->vertex_shader().quad_location();
-  uniforms->edge_location = program->vertex_shader().edge_location();
-  uniforms->color_location = program->fragment_shader().color_location();
-}
-
-namespace {
-// These functions determine if a quad, clipped by a clip_region contains
-// the entire {top|bottom|left|right} edge.
-bool is_top(const gfx::QuadF* clip_region, const DrawQuad* quad) {
-  if (!quad->IsTopEdge())
-    return false;
-  if (!clip_region)
-    return true;
-
-  return std::abs(clip_region->p1().y()) < kAntiAliasingEpsilon &&
-         std::abs(clip_region->p2().y()) < kAntiAliasingEpsilon;
-}
-
-bool is_bottom(const gfx::QuadF* clip_region, const DrawQuad* quad) {
-  if (!quad->IsBottomEdge())
-    return false;
-  if (!clip_region)
-    return true;
-
-  return std::abs(clip_region->p3().y() -
-                  quad->shared_quad_state->content_bounds.height()) <
-             kAntiAliasingEpsilon &&
-         std::abs(clip_region->p4().y() -
-                  quad->shared_quad_state->content_bounds.height()) <
-             kAntiAliasingEpsilon;
-}
-
-bool is_left(const gfx::QuadF* clip_region, const DrawQuad* quad) {
-  if (!quad->IsLeftEdge())
-    return false;
-  if (!clip_region)
-    return true;
-
-  return std::abs(clip_region->p1().x()) < kAntiAliasingEpsilon &&
-         std::abs(clip_region->p4().x()) < kAntiAliasingEpsilon;
-}
-
-bool is_right(const gfx::QuadF* clip_region, const DrawQuad* quad) {
-  if (!quad->IsRightEdge())
-    return false;
-  if (!clip_region)
-    return true;
-
-  return std::abs(clip_region->p2().x() -
-                  quad->shared_quad_state->content_bounds.width()) <
-             kAntiAliasingEpsilon &&
-         std::abs(clip_region->p3().x() -
-                  quad->shared_quad_state->content_bounds.width()) <
-             kAntiAliasingEpsilon;
-}
-}  // anonymous namespace
-
-static gfx::QuadF GetDeviceQuadWithAntialiasingOnExteriorEdges(
-    const LayerQuad& device_layer_edges,
-    const gfx::Transform& device_transform,
-    const gfx::QuadF* clip_region,
-    const DrawQuad* quad) {
-  gfx::RectF tile_rect = quad->visible_rect;
-  gfx::QuadF tile_quad(tile_rect);
-
-  if (clip_region) {
-    if (quad->material != DrawQuad::RENDER_PASS) {
-      tile_quad = *clip_region;
-    } else {
-      GetScaledRegion(quad->rect, clip_region, &tile_quad);
-    }
-  }
-
-  gfx::PointF bottom_right = tile_quad.p3();
-  gfx::PointF bottom_left = tile_quad.p4();
-  gfx::PointF top_left = tile_quad.p1();
-  gfx::PointF top_right = tile_quad.p2();
-  bool clipped = false;
-
-  // Map points to device space. We ignore |clipped|, since the result of
-  // |MapPoint()| still produces a valid point to draw the quad with. When
-  // clipped, the point will be outside of the viewport. See crbug.com/416367.
-  bottom_right = MathUtil::MapPoint(device_transform, bottom_right, &clipped);
-  bottom_left = MathUtil::MapPoint(device_transform, bottom_left, &clipped);
-  top_left = MathUtil::MapPoint(device_transform, top_left, &clipped);
-  top_right = MathUtil::MapPoint(device_transform, top_right, &clipped);
-
-  LayerQuad::Edge bottom_edge(bottom_right, bottom_left);
-  LayerQuad::Edge left_edge(bottom_left, top_left);
-  LayerQuad::Edge top_edge(top_left, top_right);
-  LayerQuad::Edge right_edge(top_right, bottom_right);
-
-  // Only apply anti-aliasing to edges not clipped by culling or scissoring.
-  // If an edge is degenerate we do not want to replace it with a "proper" edge
-  // as that will cause the quad to possibly expand is strange ways.
-  if (!top_edge.degenerate() && is_top(clip_region, quad) &&
-      tile_rect.y() == quad->rect.y()) {
-    top_edge = device_layer_edges.top();
-  }
-  if (!left_edge.degenerate() && is_left(clip_region, quad) &&
-      tile_rect.x() == quad->rect.x()) {
-    left_edge = device_layer_edges.left();
-  }
-  if (!right_edge.degenerate() && is_right(clip_region, quad) &&
-      tile_rect.right() == quad->rect.right()) {
-    right_edge = device_layer_edges.right();
-  }
-  if (!bottom_edge.degenerate() && is_bottom(clip_region, quad) &&
-      tile_rect.bottom() == quad->rect.bottom()) {
-    bottom_edge = device_layer_edges.bottom();
-  }
-
-  float sign = tile_quad.IsCounterClockwise() ? -1 : 1;
-  bottom_edge.scale(sign);
-  left_edge.scale(sign);
-  top_edge.scale(sign);
-  right_edge.scale(sign);
-
-  // Create device space quad.
-  return LayerQuad(left_edge, top_edge, right_edge, bottom_edge).ToQuadF();
-}
-
-float GetTotalQuadError(const gfx::QuadF* clipped_quad,
-                        const gfx::QuadF* ideal_rect) {
-  return (clipped_quad->p1() - ideal_rect->p1()).LengthSquared() +
-         (clipped_quad->p2() - ideal_rect->p2()).LengthSquared() +
-         (clipped_quad->p3() - ideal_rect->p3()).LengthSquared() +
-         (clipped_quad->p4() - ideal_rect->p4()).LengthSquared();
-}
-
-// Attempt to rotate the clipped quad until it lines up the most
-// correctly. This is necessary because we check the edges of this
-// quad against the expected left/right/top/bottom for anti-aliasing.
-void AlignQuadToBoundingBox(gfx::QuadF* clipped_quad) {
-  gfx::QuadF bounding_quad = gfx::QuadF(clipped_quad->BoundingBox());
-  gfx::QuadF best_rotation = *clipped_quad;
-  float least_error_amount = GetTotalQuadError(clipped_quad, &bounding_quad);
-  for (size_t i = 1; i < 4; ++i) {
-    clipped_quad->Realign(1);
-    float new_error = GetTotalQuadError(clipped_quad, &bounding_quad);
-    if (new_error < least_error_amount) {
-      least_error_amount = new_error;
-      best_rotation = *clipped_quad;
-    }
-  }
-  *clipped_quad = best_rotation;
-}
-
-// static
-bool GLRenderer::ShouldAntialiasQuad(const gfx::Transform& device_transform,
-                                     const DrawQuad* quad,
-                                     bool force_antialiasing) {
-  bool is_render_pass_quad = (quad->material == DrawQuad::RENDER_PASS);
-  // For render pass quads, |device_transform| already contains quad's rect.
-  // TODO(rosca@adobe.com): remove branching on is_render_pass_quad
-  // crbug.com/429702
-  if (!is_render_pass_quad && !quad->IsEdge())
-    return false;
-  gfx::RectF content_rect =
-      is_render_pass_quad ? QuadVertexRect() : quad->visibleContentRect();
-
-  bool clipped = false;
-  gfx::QuadF device_layer_quad =
-      MathUtil::MapQuad(device_transform, gfx::QuadF(content_rect), &clipped);
-
-  if (device_layer_quad.BoundingBox().IsEmpty())
-    return false;
-
-  bool is_axis_aligned_in_target = device_layer_quad.IsRectilinear();
-  bool is_nearest_rect_within_epsilon =
-      is_axis_aligned_in_target &&
-      gfx::IsNearestRectWithinDistance(device_layer_quad.BoundingBox(),
-                                       kAntiAliasingEpsilon);
-  // AAing clipped quads is not supported by the code yet.
-  bool use_aa = !clipped && !is_nearest_rect_within_epsilon;
-  return use_aa || force_antialiasing;
-}
-
-// static
-void GLRenderer::SetupQuadForClippingAndAntialiasing(
-    const gfx::Transform& device_transform,
-    const DrawQuad* quad,
-    bool use_aa,
-    const gfx::QuadF* clip_region,
-    gfx::QuadF* local_quad,
-    float edge[24]) {
-  bool is_render_pass_quad = (quad->material == DrawQuad::RENDER_PASS);
-  gfx::QuadF rotated_clip;
-  const gfx::QuadF* local_clip_region = clip_region;
-  if (local_clip_region) {
-    rotated_clip = *clip_region;
-    AlignQuadToBoundingBox(&rotated_clip);
-    local_clip_region = &rotated_clip;
-  }
-
-  gfx::QuadF content_rect = is_render_pass_quad
-                                ? gfx::QuadF(QuadVertexRect())
-                                : gfx::QuadF(quad->visibleContentRect());
-  if (!use_aa) {
-    if (local_clip_region) {
-      if (!is_render_pass_quad) {
-        content_rect = *local_clip_region;
-      } else {
-        GetScaledRegion(quad->rect, local_clip_region, &content_rect);
-      }
-      *local_quad = content_rect;
-    }
-    return;
-  }
-  bool clipped = false;
-  gfx::QuadF device_layer_quad =
-      MathUtil::MapQuad(device_transform, content_rect, &clipped);
-
-  LayerQuad device_layer_bounds(gfx::QuadF(device_layer_quad.BoundingBox()));
-  device_layer_bounds.InflateAntiAliasingDistance();
-
-  LayerQuad device_layer_edges(device_layer_quad);
-  device_layer_edges.InflateAntiAliasingDistance();
-
-  device_layer_edges.ToFloatArray(edge);
-  device_layer_bounds.ToFloatArray(&edge[12]);
-
-  // If we have a clip region then we are split, and therefore
-  // by necessity, at least one of our edges is not an external
-  // one.
-  bool is_full_rect = quad->visible_rect == quad->rect;
-
-  bool region_contains_all_outside_edges =
-      is_full_rect &&
-      (is_top(local_clip_region, quad) && is_left(local_clip_region, quad) &&
-       is_bottom(local_clip_region, quad) && is_right(local_clip_region, quad));
-
-  bool use_aa_on_all_four_edges =
-      !local_clip_region &&
-      (is_render_pass_quad || region_contains_all_outside_edges);
-
-  gfx::QuadF device_quad =
-      use_aa_on_all_four_edges
-          ? device_layer_edges.ToQuadF()
-          : GetDeviceQuadWithAntialiasingOnExteriorEdges(
-                device_layer_edges, device_transform, local_clip_region, quad);
-
-  // Map device space quad to local space. device_transform has no 3d
-  // component since it was flattened, so we don't need to project.  We should
-  // have already checked that the transform was uninvertible above.
-  gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
-  bool did_invert = device_transform.GetInverse(&inverse_device_transform);
-  DCHECK(did_invert);
-  *local_quad =
-      MathUtil::MapQuad(inverse_device_transform, device_quad, &clipped);
-  // We should not DCHECK(!clipped) here, because anti-aliasing inflation may
-  // cause device_quad to become clipped. To our knowledge this scenario does
-  // not need to be handled differently than the unclipped case.
-}
-
-void GLRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
-                                    const SolidColorDrawQuad* quad,
-                                    const gfx::QuadF* clip_region) {
-  gfx::Rect tile_rect = quad->visible_rect;
-
-  SkColor color = quad->color;
-  float opacity = quad->opacity();
-  float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
-
-  // Early out if alpha is small enough that quad doesn't contribute to output.
-  if (alpha < std::numeric_limits<float>::epsilon() &&
-      quad->ShouldDrawWithBlending())
-    return;
-
-  gfx::Transform device_transform =
-      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
-  device_transform.FlattenTo2d();
-  if (!device_transform.IsInvertible())
-    return;
-
-  bool force_aa = false;
-  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
-  float edge[24];
-  bool use_aa = settings_->allow_antialiasing &&
-                !quad->force_anti_aliasing_off &&
-                ShouldAntialiasQuad(device_transform, quad, force_aa);
-  SetupQuadForClippingAndAntialiasing(device_transform, quad, use_aa,
-                                      clip_region, &local_quad, edge);
-
-  SolidColorProgramUniforms uniforms;
-  if (use_aa) {
-    SolidColorUniformLocation(GetSolidColorProgramAA(), &uniforms);
-  } else {
-    SolidColorUniformLocation(GetSolidColorProgram(), &uniforms);
-  }
-  SetUseProgram(uniforms.program);
-
-  GLC(gl_,
-      gl_->Uniform4f(uniforms.color_location,
-                     (SkColorGetR(color) * (1.0f / 255.0f)) * alpha,
-                     (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
-                     (SkColorGetB(color) * (1.0f / 255.0f)) * alpha,
-                     alpha));
-  if (use_aa) {
-    float viewport[4] = {static_cast<float>(viewport_.x()),
-                         static_cast<float>(viewport_.y()),
-                         static_cast<float>(viewport_.width()),
-                         static_cast<float>(viewport_.height()), };
-    GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
-    GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
-  }
-
-  // Enable blending when the quad properties require it or if we decided
-  // to use antialiasing.
-  SetBlendEnabled(quad->ShouldDrawWithBlending() || use_aa);
-
-  // Normalize to tile_rect.
-  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
-
-  SetShaderQuadF(local_quad, uniforms.quad_location);
-
-  // The transform and vertex data are used to figure out the extents that the
-  // un-antialiased quad should have and which vertex this is and the float
-  // quad passed in via uniform is the actual geometry that gets used to draw
-  // it. This is why this centered rect is used and not the original quad_rect.
-  gfx::RectF centered_rect(
-      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
-      tile_rect.size());
-  DrawQuadGeometry(
-      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
-}
-
-struct TileProgramUniforms {
-  unsigned program;
-  unsigned matrix_location;
-  unsigned viewport_location;
-  unsigned quad_location;
-  unsigned edge_location;
-  unsigned vertex_tex_transform_location;
-  unsigned sampler_location;
-  unsigned fragment_tex_transform_location;
-  unsigned alpha_location;
-};
-
-template <class T>
-static void TileUniformLocation(T program, TileProgramUniforms* uniforms) {
-  uniforms->program = program->program();
-  uniforms->matrix_location = program->vertex_shader().matrix_location();
-  uniforms->viewport_location = program->vertex_shader().viewport_location();
-  uniforms->quad_location = program->vertex_shader().quad_location();
-  uniforms->edge_location = program->vertex_shader().edge_location();
-  uniforms->vertex_tex_transform_location =
-      program->vertex_shader().vertex_tex_transform_location();
-
-  uniforms->sampler_location = program->fragment_shader().sampler_location();
-  uniforms->alpha_location = program->fragment_shader().alpha_location();
-  uniforms->fragment_tex_transform_location =
-      program->fragment_shader().fragment_tex_transform_location();
-}
-
-void GLRenderer::DrawTileQuad(const DrawingFrame* frame,
-                              const TileDrawQuad* quad,
-                              const gfx::QuadF* clip_region) {
-  DrawContentQuad(frame, quad, quad->resource_id, clip_region);
-}
-
-void GLRenderer::DrawContentQuad(const DrawingFrame* frame,
-                                 const ContentDrawQuadBase* quad,
-                                 ResourceProvider::ResourceId resource_id,
-                                 const gfx::QuadF* clip_region) {
-  gfx::Transform device_transform =
-      frame->window_matrix * frame->projection_matrix * quad->quadTransform();
-  device_transform.FlattenTo2d();
-
-  bool use_aa = settings_->allow_antialiasing &&
-                ShouldAntialiasQuad(device_transform, quad, false);
-
-  // TODO(timav): simplify coordinate transformations in DrawContentQuadAA
-  // similar to the way DrawContentQuadNoAA works and then consider
-  // combining DrawContentQuadAA and DrawContentQuadNoAA into one method.
-  if (use_aa)
-    DrawContentQuadAA(frame, quad, resource_id, device_transform, clip_region);
-  else
-    DrawContentQuadNoAA(frame, quad, resource_id, clip_region);
-}
-
-void GLRenderer::DrawContentQuadAA(const DrawingFrame* frame,
-                                   const ContentDrawQuadBase* quad,
-                                   ResourceProvider::ResourceId resource_id,
-                                   const gfx::Transform& device_transform,
-                                   const gfx::QuadF* clip_region) {
-  if (!device_transform.IsInvertible())
-    return;
-
-  gfx::Rect tile_rect = quad->visible_rect;
-
-  gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional(
-      quad->tex_coord_rect, quad->rect, tile_rect);
-  float tex_to_geom_scale_x = quad->rect.width() / quad->tex_coord_rect.width();
-  float tex_to_geom_scale_y =
-      quad->rect.height() / quad->tex_coord_rect.height();
-
-  gfx::RectF clamp_geom_rect(tile_rect);
-  gfx::RectF clamp_tex_rect(tex_coord_rect);
-  // Clamp texture coordinates to avoid sampling outside the layer
-  // by deflating the tile region half a texel or half a texel
-  // minus epsilon for one pixel layers. The resulting clamp region
-  // is mapped to the unit square by the vertex shader and mapped
-  // back to normalized texture coordinates by the fragment shader
-  // after being clamped to 0-1 range.
-  float tex_clamp_x =
-      std::min(0.5f, 0.5f * clamp_tex_rect.width() - kAntiAliasingEpsilon);
-  float tex_clamp_y =
-      std::min(0.5f, 0.5f * clamp_tex_rect.height() - kAntiAliasingEpsilon);
-  float geom_clamp_x =
-      std::min(tex_clamp_x * tex_to_geom_scale_x,
-               0.5f * clamp_geom_rect.width() - kAntiAliasingEpsilon);
-  float geom_clamp_y =
-      std::min(tex_clamp_y * tex_to_geom_scale_y,
-               0.5f * clamp_geom_rect.height() - kAntiAliasingEpsilon);
-  clamp_geom_rect.Inset(geom_clamp_x, geom_clamp_y, geom_clamp_x, geom_clamp_y);
-  clamp_tex_rect.Inset(tex_clamp_x, tex_clamp_y, tex_clamp_x, tex_clamp_y);
-
-  // Map clamping rectangle to unit square.
-  float vertex_tex_translate_x = -clamp_geom_rect.x() / clamp_geom_rect.width();
-  float vertex_tex_translate_y =
-      -clamp_geom_rect.y() / clamp_geom_rect.height();
-  float vertex_tex_scale_x = tile_rect.width() / clamp_geom_rect.width();
-  float vertex_tex_scale_y = tile_rect.height() / clamp_geom_rect.height();
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_, &highp_threshold_cache_, highp_threshold_min_, quad->texture_size);
-
-  gfx::QuadF local_quad = gfx::QuadF(gfx::RectF(tile_rect));
-  float edge[24];
-  SetupQuadForClippingAndAntialiasing(device_transform, quad, true, clip_region,
-                                      &local_quad, edge);
-  ResourceProvider::ScopedSamplerGL quad_resource_lock(
-      resource_provider_, resource_id,
-      quad->nearest_neighbor ? GL_NEAREST : GL_LINEAR);
-  SamplerType sampler =
-      SamplerTypeFromTextureTarget(quad_resource_lock.target());
-
-  float fragment_tex_translate_x = clamp_tex_rect.x();
-  float fragment_tex_translate_y = clamp_tex_rect.y();
-  float fragment_tex_scale_x = clamp_tex_rect.width();
-  float fragment_tex_scale_y = clamp_tex_rect.height();
-
-  // Map to normalized texture coordinates.
-  if (sampler != SAMPLER_TYPE_2D_RECT) {
-    gfx::Size texture_size = quad->texture_size;
-    DCHECK(!texture_size.IsEmpty());
-    fragment_tex_translate_x /= texture_size.width();
-    fragment_tex_translate_y /= texture_size.height();
-    fragment_tex_scale_x /= texture_size.width();
-    fragment_tex_scale_y /= texture_size.height();
-  }
-
-  TileProgramUniforms uniforms;
-  if (quad->swizzle_contents) {
-    TileUniformLocation(GetTileProgramSwizzleAA(tex_coord_precision, sampler),
-                        &uniforms);
-  } else {
-    TileUniformLocation(GetTileProgramAA(tex_coord_precision, sampler),
-                        &uniforms);
-  }
-
-  SetUseProgram(uniforms.program);
-  GLC(gl_, gl_->Uniform1i(uniforms.sampler_location, 0));
-
-  float viewport[4] = {
-      static_cast<float>(viewport_.x()),
-      static_cast<float>(viewport_.y()),
-      static_cast<float>(viewport_.width()),
-      static_cast<float>(viewport_.height()),
-  };
-  GLC(gl_, gl_->Uniform4fv(uniforms.viewport_location, 1, viewport));
-  GLC(gl_, gl_->Uniform3fv(uniforms.edge_location, 8, edge));
-
-  GLC(gl_,
-      gl_->Uniform4f(uniforms.vertex_tex_transform_location,
-                     vertex_tex_translate_x,
-                     vertex_tex_translate_y,
-                     vertex_tex_scale_x,
-                     vertex_tex_scale_y));
-  GLC(gl_,
-      gl_->Uniform4f(uniforms.fragment_tex_transform_location,
-                     fragment_tex_translate_x,
-                     fragment_tex_translate_y,
-                     fragment_tex_scale_x,
-                     fragment_tex_scale_y));
-
-  // Blending is required for antialiasing.
-  SetBlendEnabled(true);
-
-  // Normalize to tile_rect.
-  local_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
-
-  SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
-  SetShaderQuadF(local_quad, uniforms.quad_location);
-
-  // The transform and vertex data are used to figure out the extents that the
-  // un-antialiased quad should have and which vertex this is and the float
-  // quad passed in via uniform is the actual geometry that gets used to draw
-  // it. This is why this centered rect is used and not the original quad_rect.
-  gfx::RectF centered_rect(
-      gfx::PointF(-0.5f * tile_rect.width(), -0.5f * tile_rect.height()),
-      tile_rect.size());
-  DrawQuadGeometry(
-      frame, quad->quadTransform(), centered_rect, uniforms.matrix_location);
-}
-
-void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
-                                     const ContentDrawQuadBase* quad,
-                                     ResourceProvider::ResourceId resource_id,
-                                     const gfx::QuadF* clip_region) {
-  gfx::RectF tex_coord_rect = MathUtil::ScaleRectProportional(
-      quad->tex_coord_rect, quad->rect, quad->visible_rect);
-  float tex_to_geom_scale_x = quad->rect.width() / quad->tex_coord_rect.width();
-  float tex_to_geom_scale_y =
-      quad->rect.height() / quad->tex_coord_rect.height();
-
-  bool scaled = (tex_to_geom_scale_x != 1.f || tex_to_geom_scale_y != 1.f);
-  GLenum filter =
-      (scaled || !quad->quadTransform().IsIdentityOrIntegerTranslation()) &&
-              !quad->nearest_neighbor
-          ? GL_LINEAR
-          : GL_NEAREST;
-
-  ResourceProvider::ScopedSamplerGL quad_resource_lock(
-      resource_provider_, resource_id, filter);
-  SamplerType sampler =
-      SamplerTypeFromTextureTarget(quad_resource_lock.target());
-
-  float vertex_tex_translate_x = tex_coord_rect.x();
-  float vertex_tex_translate_y = tex_coord_rect.y();
-  float vertex_tex_scale_x = tex_coord_rect.width();
-  float vertex_tex_scale_y = tex_coord_rect.height();
-
-  // Map to normalized texture coordinates.
-  if (sampler != SAMPLER_TYPE_2D_RECT) {
-    gfx::Size texture_size = quad->texture_size;
-    DCHECK(!texture_size.IsEmpty());
-    vertex_tex_translate_x /= texture_size.width();
-    vertex_tex_translate_y /= texture_size.height();
-    vertex_tex_scale_x /= texture_size.width();
-    vertex_tex_scale_y /= texture_size.height();
-  }
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_, &highp_threshold_cache_, highp_threshold_min_, quad->texture_size);
-
-  TileProgramUniforms uniforms;
-  if (quad->ShouldDrawWithBlending()) {
-    if (quad->swizzle_contents) {
-      TileUniformLocation(GetTileProgramSwizzle(tex_coord_precision, sampler),
-                          &uniforms);
-    } else {
-      TileUniformLocation(GetTileProgram(tex_coord_precision, sampler),
-                          &uniforms);
-    }
-  } else {
-    if (quad->swizzle_contents) {
-      TileUniformLocation(
-          GetTileProgramSwizzleOpaque(tex_coord_precision, sampler), &uniforms);
-    } else {
-      TileUniformLocation(GetTileProgramOpaque(tex_coord_precision, sampler),
-                          &uniforms);
-    }
-  }
-
-  SetUseProgram(uniforms.program);
-  GLC(gl_, gl_->Uniform1i(uniforms.sampler_location, 0));
-
-  GLC(gl_,
-      gl_->Uniform4f(uniforms.vertex_tex_transform_location,
-                     vertex_tex_translate_x,
-                     vertex_tex_translate_y,
-                     vertex_tex_scale_x,
-                     vertex_tex_scale_y));
-
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  SetShaderOpacity(quad->opacity(), uniforms.alpha_location);
-
-  // Pass quad coordinates to the uniform in the same order as GeometryBinding
-  // does, then vertices will match the texture mapping in the vertex buffer.
-  // The method SetShaderQuadF() changes the order of vertices and so it's
-  // not used here.
-  gfx::QuadF tile_rect(quad->visible_rect);
-  float width = quad->visible_rect.width();
-  float height = quad->visible_rect.height();
-  gfx::PointF top_left = quad->visible_rect.origin();
-  if (clip_region) {
-    tile_rect = *clip_region;
-    float gl_uv[8] = {
-        (tile_rect.p4().x() - top_left.x()) / width,
-        (tile_rect.p4().y() - top_left.y()) / height,
-        (tile_rect.p1().x() - top_left.x()) / width,
-        (tile_rect.p1().y() - top_left.y()) / height,
-        (tile_rect.p2().x() - top_left.x()) / width,
-        (tile_rect.p2().y() - top_left.y()) / height,
-        (tile_rect.p3().x() - top_left.x()) / width,
-        (tile_rect.p3().y() - top_left.y()) / height,
-    };
-    PrepareGeometry(CLIPPED_BINDING);
-    clipped_geometry_->InitializeCustomQuadWithUVs(
-        gfx::QuadF(quad->visible_rect), gl_uv);
-  } else {
-    PrepareGeometry(SHARED_BINDING);
-  }
-  float gl_quad[8] = {
-      tile_rect.p4().x(),
-      tile_rect.p4().y(),
-      tile_rect.p1().x(),
-      tile_rect.p1().y(),
-      tile_rect.p2().x(),
-      tile_rect.p2().y(),
-      tile_rect.p3().x(),
-      tile_rect.p3().y(),
-  };
-  GLC(gl_, gl_->Uniform2fv(uniforms.quad_location, 4, gl_quad));
-
-  static float gl_matrix[16];
-  ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad->quadTransform());
-  GLC(gl_,
-      gl_->UniformMatrix4fv(uniforms.matrix_location, 1, false, &gl_matrix[0]));
-
-  GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
-}
-
-void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
-                                  const YUVVideoDrawQuad* quad,
-                                  const gfx::QuadF* clip_region) {
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_,
-      &highp_threshold_cache_,
-      highp_threshold_min_,
-      quad->shared_quad_state->visible_content_rect.bottom_right());
-
-  bool use_alpha_plane = quad->a_plane_resource_id != 0;
-
-  ResourceProvider::ScopedSamplerGL y_plane_lock(
-      resource_provider_, quad->y_plane_resource_id, GL_TEXTURE1, GL_LINEAR);
-  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), y_plane_lock.target());
-  ResourceProvider::ScopedSamplerGL u_plane_lock(
-      resource_provider_, quad->u_plane_resource_id, GL_TEXTURE2, GL_LINEAR);
-  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), u_plane_lock.target());
-  ResourceProvider::ScopedSamplerGL v_plane_lock(
-      resource_provider_, quad->v_plane_resource_id, GL_TEXTURE3, GL_LINEAR);
-  DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), v_plane_lock.target());
-  scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
-  if (use_alpha_plane) {
-    a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
-        resource_provider_, quad->a_plane_resource_id, GL_TEXTURE4, GL_LINEAR));
-    DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), a_plane_lock->target());
-  }
-
-  int matrix_location = -1;
-  int tex_scale_location = -1;
-  int tex_offset_location = -1;
-  int clamp_rect_location = -1;
-  int y_texture_location = -1;
-  int u_texture_location = -1;
-  int v_texture_location = -1;
-  int a_texture_location = -1;
-  int yuv_matrix_location = -1;
-  int yuv_adj_location = -1;
-  int alpha_location = -1;
-  if (use_alpha_plane) {
-    const VideoYUVAProgram* program = GetVideoYUVAProgram(tex_coord_precision);
-    DCHECK(program && (program->initialized() || IsContextLost()));
-    SetUseProgram(program->program());
-    matrix_location = program->vertex_shader().matrix_location();
-    tex_scale_location = program->vertex_shader().tex_scale_location();
-    tex_offset_location = program->vertex_shader().tex_offset_location();
-    y_texture_location = program->fragment_shader().y_texture_location();
-    u_texture_location = program->fragment_shader().u_texture_location();
-    v_texture_location = program->fragment_shader().v_texture_location();
-    a_texture_location = program->fragment_shader().a_texture_location();
-    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
-    yuv_adj_location = program->fragment_shader().yuv_adj_location();
-    clamp_rect_location = program->fragment_shader().clamp_rect_location();
-    alpha_location = program->fragment_shader().alpha_location();
-  } else {
-    const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision);
-    DCHECK(program && (program->initialized() || IsContextLost()));
-    SetUseProgram(program->program());
-    matrix_location = program->vertex_shader().matrix_location();
-    tex_scale_location = program->vertex_shader().tex_scale_location();
-    tex_offset_location = program->vertex_shader().tex_offset_location();
-    y_texture_location = program->fragment_shader().y_texture_location();
-    u_texture_location = program->fragment_shader().u_texture_location();
-    v_texture_location = program->fragment_shader().v_texture_location();
-    yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
-    yuv_adj_location = program->fragment_shader().yuv_adj_location();
-    clamp_rect_location = program->fragment_shader().clamp_rect_location();
-    alpha_location = program->fragment_shader().alpha_location();
-  }
-
-  GLC(gl_,
-      gl_->Uniform2f(tex_scale_location,
-                     quad->tex_coord_rect.width(),
-                     quad->tex_coord_rect.height()));
-  GLC(gl_,
-      gl_->Uniform2f(tex_offset_location,
-                     quad->tex_coord_rect.x(),
-                     quad->tex_coord_rect.y()));
-  // Clamping to half a texel inside the tex coord rect prevents bilinear
-  // filtering from filtering outside the tex coord rect.
-  gfx::RectF clamp_rect(quad->tex_coord_rect);
-  // Special case: empty texture size implies no clamping.
-  if (!quad->tex_size.IsEmpty()) {
-    clamp_rect.Inset(0.5f / quad->tex_size.width(),
-                     0.5f / quad->tex_size.height());
-  }
-  GLC(gl_, gl_->Uniform4f(clamp_rect_location, clamp_rect.x(), clamp_rect.y(),
-                          clamp_rect.right(), clamp_rect.bottom()));
-
-  GLC(gl_, gl_->Uniform1i(y_texture_location, 1));
-  GLC(gl_, gl_->Uniform1i(u_texture_location, 2));
-  GLC(gl_, gl_->Uniform1i(v_texture_location, 3));
-  if (use_alpha_plane)
-    GLC(gl_, gl_->Uniform1i(a_texture_location, 4));
-
-  // These values are magic numbers that are used in the transformation from YUV
-  // to RGB color values.  They are taken from the following webpage:
-  // http://www.fourcc.org/fccyvrgb.php
-  float yuv_to_rgb_rec601[9] = {
-      1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
-  };
-  float yuv_to_rgb_jpeg[9] = {
-      1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
-  };
-  float yuv_to_rgb_rec709[9] = {
-      1.164f, 1.164f, 1.164f, 0.0f, -0.213f, 2.112f, 1.793f, -0.533f, 0.0f,
-  };
-
-  // These values map to 16, 128, and 128 respectively, and are computed
-  // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
-  // They are used in the YUV to RGBA conversion formula:
-  //   Y - 16   : Gives 16 values of head and footroom for overshooting
-  //   U - 128  : Turns unsigned U into signed U [-128,127]
-  //   V - 128  : Turns unsigned V into signed V [-128,127]
-  float yuv_adjust_constrained[3] = {
-      -0.0625f, -0.5f, -0.5f,
-  };
-
-  // Same as above, but without the head and footroom.
-  float yuv_adjust_full[3] = {
-      0.0f, -0.5f, -0.5f,
-  };
-
-  float* yuv_to_rgb = NULL;
-  float* yuv_adjust = NULL;
-
-  switch (quad->color_space) {
-    case YUVVideoDrawQuad::REC_601:
-      yuv_to_rgb = yuv_to_rgb_rec601;
-      yuv_adjust = yuv_adjust_constrained;
-      break;
-    case YUVVideoDrawQuad::REC_709:
-      yuv_to_rgb = yuv_to_rgb_rec709;
-      yuv_adjust = yuv_adjust_constrained;
-      break;
-    case YUVVideoDrawQuad::JPEG:
-      yuv_to_rgb = yuv_to_rgb_jpeg;
-      yuv_adjust = yuv_adjust_full;
-      break;
-  }
-
-  // The transform and vertex data are used to figure out the extents that the
-  // un-antialiased quad should have and which vertex this is and the float
-  // quad passed in via uniform is the actual geometry that gets used to draw
-  // it. This is why this centered rect is used and not the original quad_rect.
-  gfx::RectF tile_rect = quad->rect;
-  GLC(gl_, gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
-  GLC(gl_, gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust));
-
-  SetShaderOpacity(quad->opacity(), alpha_location);
-  if (!clip_region) {
-    DrawQuadGeometry(frame, quad->quadTransform(), tile_rect, matrix_location);
-  } else {
-    float uvs[8] = {0};
-    GetScaledUVs(quad->visible_rect, clip_region, uvs);
-    gfx::QuadF region_quad = *clip_region;
-    region_quad.Scale(1.0f / tile_rect.width(), 1.0f / tile_rect.height());
-    region_quad -= gfx::Vector2dF(0.5f, 0.5f);
-    DrawQuadGeometryClippedByQuadF(frame, quad->quadTransform(), tile_rect,
-                                   region_quad, matrix_location, uvs);
-  }
-}
-
-void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame,
-                                     const StreamVideoDrawQuad* quad,
-                                     const gfx::QuadF* clip_region) {
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  static float gl_matrix[16];
-
-  DCHECK(capabilities_.using_egl_image);
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_,
-      &highp_threshold_cache_,
-      highp_threshold_min_,
-      quad->shared_quad_state->visible_content_rect.bottom_right());
-
-  const VideoStreamTextureProgram* program =
-      GetVideoStreamTextureProgram(tex_coord_precision);
-  SetUseProgram(program->program());
-
-  ToGLMatrix(&gl_matrix[0], quad->matrix);
-  GLC(gl_,
-      gl_->UniformMatrix4fv(
-          program->vertex_shader().tex_matrix_location(), 1, false, gl_matrix));
-
-  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
-                                          quad->resource_id);
-  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id()));
-
-  GLC(gl_, gl_->Uniform1i(program->fragment_shader().sampler_location(), 0));
-
-  SetShaderOpacity(quad->opacity(),
-                   program->fragment_shader().alpha_location());
-  if (!clip_region) {
-    DrawQuadGeometry(frame, quad->quadTransform(), quad->rect,
-                     program->vertex_shader().matrix_location());
-  } else {
-    gfx::QuadF region_quad(*clip_region);
-    region_quad.Scale(1.0f / quad->rect.width(), 1.0f / quad->rect.height());
-    region_quad -= gfx::Vector2dF(0.5f, 0.5f);
-    float uvs[8] = {0};
-    GetScaledUVs(quad->visible_rect, clip_region, uvs);
-    DrawQuadGeometryClippedByQuadF(
-        frame, quad->quadTransform(), quad->rect, region_quad,
-        program->vertex_shader().matrix_location(), uvs);
-  }
-}
-
-struct TextureProgramBinding {
-  template <class Program>
-  void Set(Program* program) {
-    DCHECK(program);
-    program_id = program->program();
-    sampler_location = program->fragment_shader().sampler_location();
-    matrix_location = program->vertex_shader().matrix_location();
-    background_color_location =
-        program->fragment_shader().background_color_location();
-  }
-  int program_id;
-  int sampler_location;
-  int matrix_location;
-  int transform_location;
-  int background_color_location;
-};
-
-struct TexTransformTextureProgramBinding : TextureProgramBinding {
-  template <class Program>
-  void Set(Program* program) {
-    TextureProgramBinding::Set(program);
-    tex_transform_location = program->vertex_shader().tex_transform_location();
-    vertex_opacity_location =
-        program->vertex_shader().vertex_opacity_location();
-  }
-  int tex_transform_location;
-  int vertex_opacity_location;
-};
-
-void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
-  // Check to see if we have anything to draw.
-  if (draw_cache_.program_id == -1)
-    return;
-
-  PrepareGeometry(flush_binding);
-
-  // Set the correct blending mode.
-  SetBlendEnabled(draw_cache_.needs_blending);
-
-  // Bind the program to the GL state.
-  SetUseProgram(draw_cache_.program_id);
-
-  // Bind the correct texture sampler location.
-  GLC(gl_, gl_->Uniform1i(draw_cache_.sampler_location, 0));
-
-  // Assume the current active textures is 0.
-  ResourceProvider::ScopedSamplerGL locked_quad(
-      resource_provider_,
-      draw_cache_.resource_id,
-      draw_cache_.nearest_neighbor ? GL_NEAREST : GL_LINEAR);
-  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, locked_quad.texture_id()));
-
-  static_assert(sizeof(Float4) == 4 * sizeof(float),
-                "Float4 struct should be densely packed");
-  static_assert(sizeof(Float16) == 16 * sizeof(float),
-                "Float16 struct should be densely packed");
-
-  // Upload the tranforms for both points and uvs.
-  GLC(gl_,
-      gl_->UniformMatrix4fv(
-          static_cast<int>(draw_cache_.matrix_location),
-          static_cast<int>(draw_cache_.matrix_data.size()),
-          false,
-          reinterpret_cast<float*>(&draw_cache_.matrix_data.front())));
-  GLC(gl_,
-      gl_->Uniform4fv(
-          static_cast<int>(draw_cache_.uv_xform_location),
-          static_cast<int>(draw_cache_.uv_xform_data.size()),
-          reinterpret_cast<float*>(&draw_cache_.uv_xform_data.front())));
-
-  if (draw_cache_.background_color != SK_ColorTRANSPARENT) {
-    Float4 background_color = PremultipliedColor(draw_cache_.background_color);
-    GLC(gl_,
-        gl_->Uniform4fv(
-            draw_cache_.background_color_location, 1, background_color.data));
-  }
-
-  GLC(gl_,
-      gl_->Uniform1fv(
-          static_cast<int>(draw_cache_.vertex_opacity_location),
-          static_cast<int>(draw_cache_.vertex_opacity_data.size()),
-          static_cast<float*>(&draw_cache_.vertex_opacity_data.front())));
-
-  // Draw the quads!
-  GLC(gl_,
-      gl_->DrawElements(GL_TRIANGLES,
-                        6 * draw_cache_.matrix_data.size(),
-                        GL_UNSIGNED_SHORT,
-                        0));
-
-  // Clear the cache.
-  draw_cache_.program_id = -1;
-  draw_cache_.uv_xform_data.resize(0);
-  draw_cache_.vertex_opacity_data.resize(0);
-  draw_cache_.matrix_data.resize(0);
-
-  // If we had a clipped binding, prepare the shared binding for the
-  // next inserts.
-  if (flush_binding == CLIPPED_BINDING) {
-    PrepareGeometry(SHARED_BINDING);
-  }
-}
-
-void GLRenderer::EnqueueTextureQuad(const DrawingFrame* frame,
-                                    const TextureDrawQuad* quad,
-                                    const gfx::QuadF* clip_region) {
-  // If we have a clip_region then we have to render the next quad
-  // with dynamic geometry, therefore we must flush all pending
-  // texture quads.
-  if (clip_region) {
-    // We send in false here because we want to flush what's currently in the
-    // queue using the shared_geometry and not clipped_geometry
-    FlushTextureQuadCache(SHARED_BINDING);
-  }
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_,
-      &highp_threshold_cache_,
-      highp_threshold_min_,
-      quad->shared_quad_state->visible_content_rect.bottom_right());
-
-  // Choose the correct texture program binding
-  TexTransformTextureProgramBinding binding;
-  if (quad->premultiplied_alpha) {
-    if (quad->background_color == SK_ColorTRANSPARENT) {
-      binding.Set(GetTextureProgram(tex_coord_precision));
-    } else {
-      binding.Set(GetTextureBackgroundProgram(tex_coord_precision));
-    }
-  } else {
-    if (quad->background_color == SK_ColorTRANSPARENT) {
-      binding.Set(GetNonPremultipliedTextureProgram(tex_coord_precision));
-    } else {
-      binding.Set(
-          GetNonPremultipliedTextureBackgroundProgram(tex_coord_precision));
-    }
-  }
-
-  int resource_id = quad->resource_id;
-
-  if (draw_cache_.program_id != binding.program_id ||
-      draw_cache_.resource_id != resource_id ||
-      draw_cache_.needs_blending != quad->ShouldDrawWithBlending() ||
-      draw_cache_.nearest_neighbor != quad->nearest_neighbor ||
-      draw_cache_.background_color != quad->background_color ||
-      draw_cache_.matrix_data.size() >= 8) {
-    FlushTextureQuadCache(SHARED_BINDING);
-    draw_cache_.program_id = binding.program_id;
-    draw_cache_.resource_id = resource_id;
-    draw_cache_.needs_blending = quad->ShouldDrawWithBlending();
-    draw_cache_.nearest_neighbor = quad->nearest_neighbor;
-    draw_cache_.background_color = quad->background_color;
-
-    draw_cache_.uv_xform_location = binding.tex_transform_location;
-    draw_cache_.background_color_location = binding.background_color_location;
-    draw_cache_.vertex_opacity_location = binding.vertex_opacity_location;
-    draw_cache_.matrix_location = binding.matrix_location;
-    draw_cache_.sampler_location = binding.sampler_location;
-  }
-
-  // Generate the uv-transform
-  if (!clip_region) {
-    draw_cache_.uv_xform_data.push_back(UVTransform(quad));
-  } else {
-    Float4 uv_transform = {{0.0f, 0.0f, 1.0f, 1.0f}};
-    draw_cache_.uv_xform_data.push_back(uv_transform);
-  }
-
-  // Generate the vertex opacity
-  const float opacity = quad->opacity();
-  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity);
-  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[1] * opacity);
-  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[2] * opacity);
-  draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[3] * opacity);
-
-  // Generate the transform matrix
-  gfx::Transform quad_rect_matrix;
-  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
-  quad_rect_matrix = frame->projection_matrix * quad_rect_matrix;
-
-  Float16 m;
-  quad_rect_matrix.matrix().asColMajorf(m.data);
-  draw_cache_.matrix_data.push_back(m);
-
-  if (clip_region) {
-    gfx::QuadF scaled_region;
-    if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) {
-      scaled_region = SharedGeometryQuad().BoundingBox();
-    }
-    // Both the scaled region and the SharedGeomtryQuad are in the space
-    // -0.5->0.5. We need to move that to the space 0->1.
-    float uv[8];
-    uv[0] = scaled_region.p1().x() + 0.5f;
-    uv[1] = scaled_region.p1().y() + 0.5f;
-    uv[2] = scaled_region.p2().x() + 0.5f;
-    uv[3] = scaled_region.p2().y() + 0.5f;
-    uv[4] = scaled_region.p3().x() + 0.5f;
-    uv[5] = scaled_region.p3().y() + 0.5f;
-    uv[6] = scaled_region.p4().x() + 0.5f;
-    uv[7] = scaled_region.p4().y() + 0.5f;
-    PrepareGeometry(CLIPPED_BINDING);
-    clipped_geometry_->InitializeCustomQuadWithUVs(scaled_region, uv);
-    FlushTextureQuadCache(CLIPPED_BINDING);
-  }
-}
-
-void GLRenderer::DrawIOSurfaceQuad(const DrawingFrame* frame,
-                                   const IOSurfaceDrawQuad* quad,
-                                   const gfx::QuadF* clip_region) {
-  SetBlendEnabled(quad->ShouldDrawWithBlending());
-
-  TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
-      gl_,
-      &highp_threshold_cache_,
-      highp_threshold_min_,
-      quad->shared_quad_state->visible_content_rect.bottom_right());
-
-  TexTransformTextureProgramBinding binding;
-  binding.Set(GetTextureIOSurfaceProgram(tex_coord_precision));
-
-  SetUseProgram(binding.program_id);
-  GLC(gl_, gl_->Uniform1i(binding.sampler_location, 0));
-  if (quad->orientation == IOSurfaceDrawQuad::FLIPPED) {
-    GLC(gl_,
-        gl_->Uniform4f(binding.tex_transform_location,
-                       0,
-                       quad->io_surface_size.height(),
-                       quad->io_surface_size.width(),
-                       quad->io_surface_size.height() * -1.0f));
-  } else {
-    GLC(gl_,
-        gl_->Uniform4f(binding.tex_transform_location,
-                       0,
-                       0,
-                       quad->io_surface_size.width(),
-                       quad->io_surface_size.height()));
-  }
-
-  const float vertex_opacity[] = {quad->opacity(), quad->opacity(),
-                                  quad->opacity(), quad->opacity()};
-  GLC(gl_, gl_->Uniform1fv(binding.vertex_opacity_location, 4, vertex_opacity));
-
-  ResourceProvider::ScopedReadLockGL lock(resource_provider_,
-                                          quad->io_surface_resource_id);
-  DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, lock.texture_id()));
-
-  if (!clip_region) {
-    DrawQuadGeometry(frame, quad->quadTransform(), quad->rect,
-                     binding.matrix_location);
-  } else {
-    float uvs[8] = {0};
-    GetScaledUVs(quad->visible_rect, clip_region, uvs);
-    DrawQuadGeometryClippedByQuadF(frame, quad->quadTransform(), quad->rect,
-                                   *clip_region, binding.matrix_location, uvs);
-  }
-
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_RECTANGLE_ARB, 0));
-}
-
-void GLRenderer::FinishDrawingFrame(DrawingFrame* frame) {
-  if (use_sync_query_) {
-    DCHECK(current_sync_query_);
-    current_sync_query_->End();
-    pending_sync_queries_.push_back(current_sync_query_.Pass());
-  }
-
-  current_framebuffer_lock_ = nullptr;
-  swap_buffer_rect_.Union(gfx::ToEnclosingRect(frame->root_damage_rect));
-
-  GLC(gl_, gl_->Disable(GL_BLEND));
-  blend_shadow_ = false;
-
-  ScheduleOverlays(frame);
-}
-
-void GLRenderer::FinishDrawingQuadList() {
-  FlushTextureQuadCache(SHARED_BINDING);
-}
-
-bool GLRenderer::FlippedFramebuffer(const DrawingFrame* frame) const {
-  if (frame->current_render_pass != frame->root_render_pass)
-    return true;
-  return FlippedRootFramebuffer();
-}
-
-bool GLRenderer::FlippedRootFramebuffer() const {
-  // GL is normally flipped, so a flipped output results in an unflipping.
-  return !output_surface_->capabilities().flipped_output_surface;
-}
-
-void GLRenderer::EnsureScissorTestEnabled() {
-  if (is_scissor_enabled_)
-    return;
-
-  FlushTextureQuadCache(SHARED_BINDING);
-  GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
-  is_scissor_enabled_ = true;
-}
-
-void GLRenderer::EnsureScissorTestDisabled() {
-  if (!is_scissor_enabled_)
-    return;
-
-  FlushTextureQuadCache(SHARED_BINDING);
-  GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
-  is_scissor_enabled_ = false;
-}
-
-void GLRenderer::CopyCurrentRenderPassToBitmap(
-    DrawingFrame* frame,
-    scoped_ptr<CopyOutputRequest> request) {
-  TRACE_EVENT0("cc", "GLRenderer::CopyCurrentRenderPassToBitmap");
-  gfx::Rect copy_rect = frame->current_render_pass->output_rect;
-  if (request->has_area())
-    copy_rect.Intersect(request->area());
-  GetFramebufferPixelsAsync(frame, copy_rect, request.Pass());
-}
-
-void GLRenderer::ToGLMatrix(float* gl_matrix, const gfx::Transform& transform) {
-  transform.matrix().asColMajorf(gl_matrix);
-}
-
-void GLRenderer::SetShaderQuadF(const gfx::QuadF& quad, int quad_location) {
-  if (quad_location == -1)
-    return;
-
-  float gl_quad[8];
-  gl_quad[0] = quad.p1().x();
-  gl_quad[1] = quad.p1().y();
-  gl_quad[2] = quad.p2().x();
-  gl_quad[3] = quad.p2().y();
-  gl_quad[4] = quad.p3().x();
-  gl_quad[5] = quad.p3().y();
-  gl_quad[6] = quad.p4().x();
-  gl_quad[7] = quad.p4().y();
-  GLC(gl_, gl_->Uniform2fv(quad_location, 4, gl_quad));
-}
-
-void GLRenderer::SetShaderOpacity(float opacity, int alpha_location) {
-  if (alpha_location != -1)
-    GLC(gl_, gl_->Uniform1f(alpha_location, opacity));
-}
-
-void GLRenderer::SetStencilEnabled(bool enabled) {
-  if (enabled == stencil_shadow_)
-    return;
-
-  if (enabled)
-    GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
-  else
-    GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
-  stencil_shadow_ = enabled;
-}
-
-void GLRenderer::SetBlendEnabled(bool enabled) {
-  if (enabled == blend_shadow_)
-    return;
-
-  if (enabled)
-    GLC(gl_, gl_->Enable(GL_BLEND));
-  else
-    GLC(gl_, gl_->Disable(GL_BLEND));
-  blend_shadow_ = enabled;
-}
-
-void GLRenderer::SetUseProgram(unsigned program) {
-  if (program == program_shadow_)
-    return;
-  gl_->UseProgram(program);
-  program_shadow_ = program;
-}
-
-void GLRenderer::DrawQuadGeometryClippedByQuadF(
-    const DrawingFrame* frame,
-    const gfx::Transform& draw_transform,
-    const gfx::RectF& quad_rect,
-    const gfx::QuadF& clipping_region_quad,
-    int matrix_location,
-    const float* uvs) {
-  PrepareGeometry(CLIPPED_BINDING);
-  if (uvs) {
-    clipped_geometry_->InitializeCustomQuadWithUVs(clipping_region_quad, uvs);
-  } else {
-    clipped_geometry_->InitializeCustomQuad(clipping_region_quad);
-  }
-  gfx::Transform quad_rect_matrix;
-  QuadRectTransform(&quad_rect_matrix, draw_transform, quad_rect);
-  static float gl_matrix[16];
-  ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad_rect_matrix);
-  GLC(gl_, gl_->UniformMatrix4fv(matrix_location, 1, false, &gl_matrix[0]));
-
-  GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT,
-                             reinterpret_cast<const void*>(0)));
-}
-
-void GLRenderer::DrawQuadGeometry(const DrawingFrame* frame,
-                                  const gfx::Transform& draw_transform,
-                                  const gfx::RectF& quad_rect,
-                                  int matrix_location) {
-  PrepareGeometry(SHARED_BINDING);
-  gfx::Transform quad_rect_matrix;
-  QuadRectTransform(&quad_rect_matrix, draw_transform, quad_rect);
-  static float gl_matrix[16];
-  ToGLMatrix(&gl_matrix[0], frame->projection_matrix * quad_rect_matrix);
-  GLC(gl_, gl_->UniformMatrix4fv(matrix_location, 1, false, &gl_matrix[0]));
-
-  GLC(gl_, gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0));
-}
-
-void GLRenderer::Finish() {
-  TRACE_EVENT0("cc", "GLRenderer::Finish");
-  GLC(gl_, gl_->Finish());
-}
-
-void GLRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
-  DCHECK(!is_backbuffer_discarded_);
-
-  TRACE_EVENT0("cc,benchmark", "GLRenderer::SwapBuffers");
-  // We're done! Time to swapbuffers!
-
-  gfx::Size surface_size = output_surface_->SurfaceSize();
-
-  CompositorFrame compositor_frame;
-  compositor_frame.metadata = metadata;
-  compositor_frame.gl_frame_data = make_scoped_ptr(new GLFrameData);
-  compositor_frame.gl_frame_data->size = surface_size;
-  if (capabilities_.using_partial_swap) {
-    // If supported, we can save significant bandwidth by only swapping the
-    // damaged/scissored region (clamped to the viewport).
-    swap_buffer_rect_.Intersect(gfx::Rect(surface_size));
-    int flipped_y_pos_of_rect_bottom = surface_size.height() -
-                                       swap_buffer_rect_.y() -
-                                       swap_buffer_rect_.height();
-    compositor_frame.gl_frame_data->sub_buffer_rect =
-        gfx::Rect(swap_buffer_rect_.x(),
-                  FlippedRootFramebuffer() ? flipped_y_pos_of_rect_bottom
-                                           : swap_buffer_rect_.y(),
-                  swap_buffer_rect_.width(),
-                  swap_buffer_rect_.height());
-  } else {
-    compositor_frame.gl_frame_data->sub_buffer_rect =
-        gfx::Rect(output_surface_->SurfaceSize());
-  }
-  output_surface_->SwapBuffers(&compositor_frame);
-
-  // Release previously used overlay resources and hold onto the pending ones
-  // until the next swap buffers.
-  in_use_overlay_resources_.clear();
-  in_use_overlay_resources_.swap(pending_overlay_resources_);
-
-  swap_buffer_rect_ = gfx::Rect();
-}
-
-void GLRenderer::EnforceMemoryPolicy() {
-  if (!visible()) {
-    TRACE_EVENT0("cc", "GLRenderer::EnforceMemoryPolicy dropping resources");
-    ReleaseRenderPassTextures();
-    DiscardBackbuffer();
-    resource_provider_->ReleaseCachedData();
-    output_surface_->context_provider()->DeleteCachedResources();
-    GLC(gl_, gl_->Flush());
-  }
-  PrepareGeometry(NO_BINDING);
-}
-
-void GLRenderer::DiscardBackbuffer() {
-  if (is_backbuffer_discarded_)
-    return;
-
-  output_surface_->DiscardBackbuffer();
-
-  is_backbuffer_discarded_ = true;
-
-  // Damage tracker needs a full reset every time framebuffer is discarded.
-  client_->SetFullRootLayerDamage();
-}
-
-void GLRenderer::EnsureBackbuffer() {
-  if (!is_backbuffer_discarded_)
-    return;
-
-  output_surface_->EnsureBackbuffer();
-  is_backbuffer_discarded_ = false;
-}
-
-void GLRenderer::GetFramebufferPixelsAsync(
-    const DrawingFrame* frame,
-    const gfx::Rect& rect,
-    scoped_ptr<CopyOutputRequest> request) {
-  DCHECK(!request->IsEmpty());
-  if (request->IsEmpty())
-    return;
-  if (rect.IsEmpty())
-    return;
-
-  gfx::Rect window_rect = MoveFromDrawToWindowSpace(frame, rect);
-  DCHECK_GE(window_rect.x(), 0);
-  DCHECK_GE(window_rect.y(), 0);
-  DCHECK_LE(window_rect.right(), current_surface_size_.width());
-  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
-
-  if (!request->force_bitmap_result()) {
-    bool own_mailbox = !request->has_texture_mailbox();
-
-    GLuint texture_id = 0;
-    gpu::Mailbox mailbox;
-    if (own_mailbox) {
-      GLC(gl_, gl_->GenMailboxCHROMIUM(mailbox.name));
-      gl_->GenTextures(1, &texture_id);
-      GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
-
-      GLC(gl_,
-          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-      GLC(gl_,
-          gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-      GLC(gl_,
-          gl_->TexParameteri(
-              GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-      GLC(gl_,
-          gl_->TexParameteri(
-              GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-      GLC(gl_, gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
-    } else {
-      mailbox = request->texture_mailbox().mailbox();
-      DCHECK_EQ(static_cast<unsigned>(GL_TEXTURE_2D),
-                request->texture_mailbox().target());
-      DCHECK(!mailbox.IsZero());
-      unsigned incoming_sync_point = request->texture_mailbox().sync_point();
-      if (incoming_sync_point)
-        GLC(gl_, gl_->WaitSyncPointCHROMIUM(incoming_sync_point));
-
-      texture_id = GLC(
-          gl_,
-          gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name));
-    }
-    GetFramebufferTexture(texture_id, RGBA_8888, window_rect);
-
-    unsigned sync_point = gl_->InsertSyncPointCHROMIUM();
-    TextureMailbox texture_mailbox(mailbox, GL_TEXTURE_2D, sync_point);
-
-    scoped_ptr<SingleReleaseCallback> release_callback;
-    if (own_mailbox) {
-      GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
-      release_callback = texture_mailbox_deleter_->GetReleaseCallback(
-          output_surface_->context_provider(), texture_id);
-    } else {
-      gl_->DeleteTextures(1, &texture_id);
-    }
-
-    request->SendTextureResult(
-        window_rect.size(), texture_mailbox, release_callback.Pass());
-    return;
-  }
-
-  DCHECK(request->force_bitmap_result());
-
-  scoped_ptr<PendingAsyncReadPixels> pending_read(new PendingAsyncReadPixels);
-  pending_read->copy_request = request.Pass();
-  pending_async_read_pixels_.insert(pending_async_read_pixels_.begin(),
-                                    pending_read.Pass());
-
-  bool do_workaround = NeedsIOSurfaceReadbackWorkaround();
-
-  unsigned temporary_texture = 0;
-  unsigned temporary_fbo = 0;
-
-  if (do_workaround) {
-    // On Mac OS X, calling glReadPixels() against an FBO whose color attachment
-    // is an IOSurface-backed texture causes corruption of future glReadPixels()
-    // calls, even those on different OpenGL contexts. It is believed that this
-    // is the root cause of top crasher
-    // http://crbug.com/99393. <rdar://problem/10949687>
-
-    gl_->GenTextures(1, &temporary_texture);
-    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, temporary_texture));
-    GLC(gl_,
-        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    GLC(gl_,
-        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    GLC(gl_,
-        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-    GLC(gl_,
-        gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-    // Copy the contents of the current (IOSurface-backed) framebuffer into a
-    // temporary texture.
-    GetFramebufferTexture(
-        temporary_texture, RGBA_8888, gfx::Rect(current_surface_size_));
-    gl_->GenFramebuffers(1, &temporary_fbo);
-    // Attach this texture to an FBO, and perform the readback from that FBO.
-    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, temporary_fbo));
-    GLC(gl_,
-        gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
-                                  GL_COLOR_ATTACHMENT0,
-                                  GL_TEXTURE_2D,
-                                  temporary_texture,
-                                  0));
-
-    DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE),
-              gl_->CheckFramebufferStatus(GL_FRAMEBUFFER));
-  }
-
-  GLuint buffer = 0;
-  gl_->GenBuffers(1, &buffer);
-  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, buffer));
-  GLC(gl_,
-      gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
-                      4 * window_rect.size().GetArea(),
-                      NULL,
-                      GL_STREAM_READ));
-
-  GLuint query = 0;
-  gl_->GenQueriesEXT(1, &query);
-  GLC(gl_, gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, query));
-
-  GLC(gl_,
-      gl_->ReadPixels(window_rect.x(),
-                      window_rect.y(),
-                      window_rect.width(),
-                      window_rect.height(),
-                      GL_RGBA,
-                      GL_UNSIGNED_BYTE,
-                      NULL));
-
-  GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
-
-  if (do_workaround) {
-    // Clean up.
-    GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, 0));
-    GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
-    GLC(gl_, gl_->DeleteFramebuffers(1, &temporary_fbo));
-    GLC(gl_, gl_->DeleteTextures(1, &temporary_texture));
-  }
-
-  base::Closure finished_callback = base::Bind(&GLRenderer::FinishedReadback,
-                                               base::Unretained(this),
-                                               buffer,
-                                               query,
-                                               window_rect.size());
-  // Save the finished_callback so it can be cancelled.
-  pending_async_read_pixels_.front()->finished_read_pixels_callback.Reset(
-      finished_callback);
-  base::Closure cancelable_callback =
-      pending_async_read_pixels_.front()->
-          finished_read_pixels_callback.callback();
-
-  // Save the buffer to verify the callbacks happen in the expected order.
-  pending_async_read_pixels_.front()->buffer = buffer;
-
-  GLC(gl_, gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM));
-  context_support_->SignalQuery(query, cancelable_callback);
-
-  EnforceMemoryPolicy();
-}
-
-void GLRenderer::FinishedReadback(unsigned source_buffer,
-                                  unsigned query,
-                                  const gfx::Size& size) {
-  DCHECK(!pending_async_read_pixels_.empty());
-
-  if (query != 0) {
-    GLC(gl_, gl_->DeleteQueriesEXT(1, &query));
-  }
-
-  PendingAsyncReadPixels* current_read = pending_async_read_pixels_.back();
-  // Make sure we service the readbacks in order.
-  DCHECK_EQ(source_buffer, current_read->buffer);
-
-  uint8* src_pixels = NULL;
-  scoped_ptr<SkBitmap> bitmap;
-
-  if (source_buffer != 0) {
-    GLC(gl_,
-        gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, source_buffer));
-    src_pixels = static_cast<uint8*>(gl_->MapBufferCHROMIUM(
-        GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
-
-    if (src_pixels) {
-      bitmap.reset(new SkBitmap);
-      bitmap->allocN32Pixels(size.width(), size.height());
-      scoped_ptr<SkAutoLockPixels> lock(new SkAutoLockPixels(*bitmap));
-      uint8* dest_pixels = static_cast<uint8*>(bitmap->getPixels());
-
-      size_t row_bytes = size.width() * 4;
-      int num_rows = size.height();
-      size_t total_bytes = num_rows * row_bytes;
-      for (size_t dest_y = 0; dest_y < total_bytes; dest_y += row_bytes) {
-        // Flip Y axis.
-        size_t src_y = total_bytes - dest_y - row_bytes;
-        // Swizzle OpenGL -> Skia byte order.
-        for (size_t x = 0; x < row_bytes; x += 4) {
-          dest_pixels[dest_y + x + SK_R32_SHIFT / 8] =
-              src_pixels[src_y + x + 0];
-          dest_pixels[dest_y + x + SK_G32_SHIFT / 8] =
-              src_pixels[src_y + x + 1];
-          dest_pixels[dest_y + x + SK_B32_SHIFT / 8] =
-              src_pixels[src_y + x + 2];
-          dest_pixels[dest_y + x + SK_A32_SHIFT / 8] =
-              src_pixels[src_y + x + 3];
-        }
-      }
-
-      GLC(gl_,
-          gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM));
-    }
-    GLC(gl_, gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0));
-    GLC(gl_, gl_->DeleteBuffers(1, &source_buffer));
-  }
-
-  if (bitmap)
-    current_read->copy_request->SendBitmapResult(bitmap.Pass());
-  pending_async_read_pixels_.pop_back();
-}
-
-void GLRenderer::GetFramebufferTexture(unsigned texture_id,
-                                       ResourceFormat texture_format,
-                                       const gfx::Rect& window_rect) {
-  DCHECK(texture_id);
-  DCHECK_GE(window_rect.x(), 0);
-  DCHECK_GE(window_rect.y(), 0);
-  DCHECK_LE(window_rect.right(), current_surface_size_.width());
-  DCHECK_LE(window_rect.bottom(), current_surface_size_.height());
-
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, texture_id));
-  GLC(gl_,
-      gl_->CopyTexImage2D(GL_TEXTURE_2D,
-                          0,
-                          GLDataFormat(texture_format),
-                          window_rect.x(),
-                          window_rect.y(),
-                          window_rect.width(),
-                          window_rect.height(),
-                          0));
-  GLC(gl_, gl_->BindTexture(GL_TEXTURE_2D, 0));
-}
-
-bool GLRenderer::UseScopedTexture(DrawingFrame* frame,
-                                  const ScopedResource* texture,
-                                  const gfx::Rect& viewport_rect) {
-  DCHECK(texture->id());
-  frame->current_render_pass = NULL;
-  frame->current_texture = texture;
-
-  return BindFramebufferToTexture(frame, texture, viewport_rect);
-}
-
-void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
-  current_framebuffer_lock_ = nullptr;
-  output_surface_->BindFramebuffer();
-
-  if (output_surface_->HasExternalStencilTest()) {
-    SetStencilEnabled(true);
-    GLC(gl_, gl_->StencilFunc(GL_EQUAL, 1, 1));
-  } else {
-    SetStencilEnabled(false);
-  }
-}
-
-bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame,
-                                          const ScopedResource* texture,
-                                          const gfx::Rect& target_rect) {
-  DCHECK(texture->id());
-
-  // Explicitly release lock, otherwise we can crash when try to lock
-  // same texture again.
-  current_framebuffer_lock_ = nullptr;
-
-  SetStencilEnabled(false);
-  GLC(gl_, gl_->BindFramebuffer(GL_FRAMEBUFFER, offscreen_framebuffer_id_));
-  current_framebuffer_lock_ =
-      make_scoped_ptr(new ResourceProvider::ScopedWriteLockGL(
-          resource_provider_, texture->id()));
-  unsigned texture_id = current_framebuffer_lock_->texture_id();
-  GLC(gl_,
-      gl_->FramebufferTexture2D(
-          GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0));
-
-  DCHECK(gl_->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
-             GL_FRAMEBUFFER_COMPLETE ||
-         IsContextLost());
-  return true;
-}
-
-void GLRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
-  EnsureScissorTestEnabled();
-
-  // Don't unnecessarily ask the context to change the scissor, because it
-  // may cause undesired GPU pipeline flushes.
-  if (scissor_rect == scissor_rect_ && !scissor_rect_needs_reset_)
-    return;
-
-  scissor_rect_ = scissor_rect;
-  FlushTextureQuadCache(SHARED_BINDING);
-  GLC(gl_,
-      gl_->Scissor(scissor_rect.x(),
-                   scissor_rect.y(),
-                   scissor_rect.width(),
-                   scissor_rect.height()));
-
-  scissor_rect_needs_reset_ = false;
-}
-
-void GLRenderer::SetDrawViewport(const gfx::Rect& window_space_viewport) {
-  viewport_ = window_space_viewport;
-  GLC(gl_,
-      gl_->Viewport(window_space_viewport.x(),
-                    window_space_viewport.y(),
-                    window_space_viewport.width(),
-                    window_space_viewport.height()));
-}
-
-void GLRenderer::InitializeSharedObjects() {
-  TRACE_EVENT0("cc", "GLRenderer::InitializeSharedObjects");
-
-  // Create an FBO for doing offscreen rendering.
-  GLC(gl_, gl_->GenFramebuffers(1, &offscreen_framebuffer_id_));
-
-  shared_geometry_ =
-      make_scoped_ptr(new StaticGeometryBinding(gl_, QuadVertexRect()));
-  clipped_geometry_ = make_scoped_ptr(new DynamicGeometryBinding(gl_));
-}
-
-void GLRenderer::PrepareGeometry(BoundGeometry binding) {
-  if (binding == bound_geometry_) {
-    return;
-  }
-
-  switch (binding) {
-    case SHARED_BINDING:
-      shared_geometry_->PrepareForDraw();
-      break;
-    case CLIPPED_BINDING:
-      clipped_geometry_->PrepareForDraw();
-      break;
-    case NO_BINDING:
-      break;
-  }
-  bound_geometry_ = binding;
-}
-
-const GLRenderer::TileCheckerboardProgram*
-GLRenderer::GetTileCheckerboardProgram() {
-  if (!tile_checkerboard_program_.initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::checkerboardProgram::initalize");
-    tile_checkerboard_program_.Initialize(output_surface_->context_provider(),
-                                          TEX_COORD_PRECISION_NA,
-                                          SAMPLER_TYPE_NA);
-  }
-  return &tile_checkerboard_program_;
-}
-
-const GLRenderer::DebugBorderProgram* GLRenderer::GetDebugBorderProgram() {
-  if (!debug_border_program_.initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::debugBorderProgram::initialize");
-    debug_border_program_.Initialize(output_surface_->context_provider(),
-                                     TEX_COORD_PRECISION_NA, SAMPLER_TYPE_NA);
-  }
-  return &debug_border_program_;
-}
-
-const GLRenderer::SolidColorProgram* GLRenderer::GetSolidColorProgram() {
-  if (!solid_color_program_.initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::solidColorProgram::initialize");
-    solid_color_program_.Initialize(output_surface_->context_provider(),
-                                    TEX_COORD_PRECISION_NA, SAMPLER_TYPE_NA);
-  }
-  return &solid_color_program_;
-}
-
-const GLRenderer::SolidColorProgramAA* GLRenderer::GetSolidColorProgramAA() {
-  if (!solid_color_program_aa_.initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::solidColorProgramAA::initialize");
-    solid_color_program_aa_.Initialize(output_surface_->context_provider(),
-                                       TEX_COORD_PRECISION_NA, SAMPLER_TYPE_NA);
-  }
-  return &solid_color_program_aa_;
-}
-
-const GLRenderer::RenderPassProgram* GLRenderer::GetRenderPassProgram(
-    TexCoordPrecision precision,
-    BlendMode blend_mode) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassProgram* program = &render_pass_program_[precision][blend_mode];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::renderPassProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D, blend_mode);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassProgramAA* GLRenderer::GetRenderPassProgramAA(
-    TexCoordPrecision precision,
-    BlendMode blend_mode) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassProgramAA* program =
-      &render_pass_program_aa_[precision][blend_mode];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::renderPassProgramAA::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D, blend_mode);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassMaskProgram* GLRenderer::GetRenderPassMaskProgram(
-    TexCoordPrecision precision,
-    SamplerType sampler,
-    BlendMode blend_mode,
-    bool mask_for_background) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassMaskProgram* program =
-      &render_pass_mask_program_[precision][sampler][blend_mode]
-                                [mask_for_background ? HAS_MASK : NO_MASK];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision,
-        sampler, blend_mode, mask_for_background);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassMaskProgramAA*
-GLRenderer::GetRenderPassMaskProgramAA(TexCoordPrecision precision,
-                                       SamplerType sampler,
-                                       BlendMode blend_mode,
-                                       bool mask_for_background) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassMaskProgramAA* program =
-      &render_pass_mask_program_aa_[precision][sampler][blend_mode]
-                                   [mask_for_background ? HAS_MASK : NO_MASK];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::renderPassMaskProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision,
-        sampler, blend_mode, mask_for_background);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassColorMatrixProgram*
-GLRenderer::GetRenderPassColorMatrixProgram(TexCoordPrecision precision,
-                                            BlendMode blend_mode) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassColorMatrixProgram* program =
-      &render_pass_color_matrix_program_[precision][blend_mode];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D, blend_mode);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassColorMatrixProgramAA*
-GLRenderer::GetRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
-                                              BlendMode blend_mode) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassColorMatrixProgramAA* program =
-      &render_pass_color_matrix_program_aa_[precision][blend_mode];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc",
-                 "GLRenderer::renderPassColorMatrixProgramAA::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D, blend_mode);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassMaskColorMatrixProgram*
-GLRenderer::GetRenderPassMaskColorMatrixProgram(
-    TexCoordPrecision precision,
-    SamplerType sampler,
-    BlendMode blend_mode,
-    bool mask_for_background) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassMaskColorMatrixProgram* program =
-      &render_pass_mask_color_matrix_program_[precision][sampler][blend_mode]
-          [mask_for_background ? HAS_MASK : NO_MASK];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc",
-                 "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision,
-        sampler, blend_mode, mask_for_background);
-  }
-  return program;
-}
-
-const GLRenderer::RenderPassMaskColorMatrixProgramAA*
-GLRenderer::GetRenderPassMaskColorMatrixProgramAA(
-    TexCoordPrecision precision,
-    SamplerType sampler,
-    BlendMode blend_mode,
-    bool mask_for_background) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  DCHECK_GE(blend_mode, 0);
-  DCHECK_LE(blend_mode, LAST_BLEND_MODE);
-  RenderPassMaskColorMatrixProgramAA* program =
-      &render_pass_mask_color_matrix_program_aa_[precision][sampler][blend_mode]
-          [mask_for_background ? HAS_MASK : NO_MASK];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc",
-                 "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision,
-        sampler, blend_mode, mask_for_background);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgram* GLRenderer::GetTileProgram(
-    TexCoordPrecision precision,
-    SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgram* program = &tile_program_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgram::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgramOpaque* GLRenderer::GetTileProgramOpaque(
-    TexCoordPrecision precision,
-    SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgramOpaque* program = &tile_program_opaque_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgramOpaque::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgramAA* GLRenderer::GetTileProgramAA(
-    TexCoordPrecision precision,
-    SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgramAA* program = &tile_program_aa_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgramAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgramSwizzle* GLRenderer::GetTileProgramSwizzle(
-    TexCoordPrecision precision,
-    SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgramSwizzle* program = &tile_program_swizzle_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzle::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgramSwizzleOpaque*
-GLRenderer::GetTileProgramSwizzleOpaque(TexCoordPrecision precision,
-                                        SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgramSwizzleOpaque* program =
-      &tile_program_swizzle_opaque_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleOpaque::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TileProgramSwizzleAA* GLRenderer::GetTileProgramSwizzleAA(
-    TexCoordPrecision precision,
-    SamplerType sampler) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  DCHECK_GE(sampler, 0);
-  DCHECK_LE(sampler, LAST_SAMPLER_TYPE);
-  TileProgramSwizzleAA* program = &tile_program_swizzle_aa_[precision][sampler];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::tileProgramSwizzleAA::initialize");
-    program->Initialize(
-        output_surface_->context_provider(), precision, sampler);
-  }
-  return program;
-}
-
-const GLRenderer::TextureProgram* GLRenderer::GetTextureProgram(
-    TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  TextureProgram* program = &texture_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::NonPremultipliedTextureProgram*
-GLRenderer::GetNonPremultipliedTextureProgram(TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  NonPremultipliedTextureProgram* program =
-      &nonpremultiplied_texture_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc",
-                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::TextureBackgroundProgram*
-GLRenderer::GetTextureBackgroundProgram(TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  TextureBackgroundProgram* program = &texture_background_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::textureProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::NonPremultipliedTextureBackgroundProgram*
-GLRenderer::GetNonPremultipliedTextureBackgroundProgram(
-    TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  NonPremultipliedTextureBackgroundProgram* program =
-      &nonpremultiplied_texture_background_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc",
-                 "GLRenderer::NonPremultipliedTextureProgram::Initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::TextureProgram* GLRenderer::GetTextureIOSurfaceProgram(
-    TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  TextureProgram* program = &texture_io_surface_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::textureIOSurfaceProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D_RECT);
-  }
-  return program;
-}
-
-const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram(
-    TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  VideoYUVProgram* program = &video_yuv_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::VideoYUVAProgram* GLRenderer::GetVideoYUVAProgram(
-    TexCoordPrecision precision) {
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  VideoYUVAProgram* program = &video_yuva_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::videoYUVAProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_2D);
-  }
-  return program;
-}
-
-const GLRenderer::VideoStreamTextureProgram*
-GLRenderer::GetVideoStreamTextureProgram(TexCoordPrecision precision) {
-  if (!Capabilities().using_egl_image)
-    return NULL;
-  DCHECK_GE(precision, 0);
-  DCHECK_LE(precision, LAST_TEX_COORD_PRECISION);
-  VideoStreamTextureProgram* program =
-      &video_stream_texture_program_[precision];
-  if (!program->initialized()) {
-    TRACE_EVENT0("cc", "GLRenderer::streamTextureProgram::initialize");
-    program->Initialize(output_surface_->context_provider(), precision,
-                        SAMPLER_TYPE_EXTERNAL_OES);
-  }
-  return program;
-}
-
-void GLRenderer::CleanupSharedObjects() {
-  shared_geometry_ = nullptr;
-
-  for (int i = 0; i <= LAST_TEX_COORD_PRECISION; ++i) {
-    for (int j = 0; j <= LAST_SAMPLER_TYPE; ++j) {
-      tile_program_[i][j].Cleanup(gl_);
-      tile_program_opaque_[i][j].Cleanup(gl_);
-      tile_program_swizzle_[i][j].Cleanup(gl_);
-      tile_program_swizzle_opaque_[i][j].Cleanup(gl_);
-      tile_program_aa_[i][j].Cleanup(gl_);
-      tile_program_swizzle_aa_[i][j].Cleanup(gl_);
-
-      for (int k = 0; k <= LAST_BLEND_MODE; k++) {
-        for (int l = 0; l <= LAST_MASK_VALUE; ++l) {
-          render_pass_mask_program_[i][j][k][l].Cleanup(gl_);
-          render_pass_mask_program_aa_[i][j][k][l].Cleanup(gl_);
-          render_pass_mask_color_matrix_program_aa_[i][j][k][l].Cleanup(gl_);
-          render_pass_mask_color_matrix_program_[i][j][k][l].Cleanup(gl_);
-        }
-      }
-    }
-    for (int j = 0; j <= LAST_BLEND_MODE; j++) {
-      render_pass_program_[i][j].Cleanup(gl_);
-      render_pass_program_aa_[i][j].Cleanup(gl_);
-      render_pass_color_matrix_program_[i][j].Cleanup(gl_);
-      render_pass_color_matrix_program_aa_[i][j].Cleanup(gl_);
-    }
-
-    texture_program_[i].Cleanup(gl_);
-    nonpremultiplied_texture_program_[i].Cleanup(gl_);
-    texture_background_program_[i].Cleanup(gl_);
-    nonpremultiplied_texture_background_program_[i].Cleanup(gl_);
-    texture_io_surface_program_[i].Cleanup(gl_);
-
-    video_yuv_program_[i].Cleanup(gl_);
-    video_yuva_program_[i].Cleanup(gl_);
-    video_stream_texture_program_[i].Cleanup(gl_);
-  }
-
-  tile_checkerboard_program_.Cleanup(gl_);
-
-  debug_border_program_.Cleanup(gl_);
-  solid_color_program_.Cleanup(gl_);
-  solid_color_program_aa_.Cleanup(gl_);
-
-  if (offscreen_framebuffer_id_)
-    GLC(gl_, gl_->DeleteFramebuffers(1, &offscreen_framebuffer_id_));
-
-  if (on_demand_tile_raster_resource_id_)
-    resource_provider_->DeleteResource(on_demand_tile_raster_resource_id_);
-
-  ReleaseRenderPassTextures();
-}
-
-void GLRenderer::ReinitializeGLState() {
-  is_scissor_enabled_ = false;
-  scissor_rect_needs_reset_ = true;
-  stencil_shadow_ = false;
-  blend_shadow_ = true;
-  program_shadow_ = 0;
-
-  RestoreGLState();
-}
-
-void GLRenderer::RestoreGLState() {
-  // This restores the current GLRenderer state to the GL context.
-  bound_geometry_ = NO_BINDING;
-  PrepareGeometry(SHARED_BINDING);
-
-  GLC(gl_, gl_->Disable(GL_DEPTH_TEST));
-  GLC(gl_, gl_->Disable(GL_CULL_FACE));
-  GLC(gl_, gl_->ColorMask(true, true, true, true));
-  GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
-  GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
-
-  if (program_shadow_)
-    gl_->UseProgram(program_shadow_);
-
-  if (stencil_shadow_)
-    GLC(gl_, gl_->Enable(GL_STENCIL_TEST));
-  else
-    GLC(gl_, gl_->Disable(GL_STENCIL_TEST));
-
-  if (blend_shadow_)
-    GLC(gl_, gl_->Enable(GL_BLEND));
-  else
-    GLC(gl_, gl_->Disable(GL_BLEND));
-
-  if (is_scissor_enabled_) {
-    GLC(gl_, gl_->Enable(GL_SCISSOR_TEST));
-    GLC(gl_,
-        gl_->Scissor(scissor_rect_.x(),
-                     scissor_rect_.y(),
-                     scissor_rect_.width(),
-                     scissor_rect_.height()));
-  } else {
-    GLC(gl_, gl_->Disable(GL_SCISSOR_TEST));
-  }
-}
-
-void GLRenderer::RestoreFramebuffer(DrawingFrame* frame) {
-  UseRenderPass(frame, frame->current_render_pass);
-}
-
-bool GLRenderer::IsContextLost() {
-  return output_surface_->context_provider()->IsContextLost();
-}
-
-void GLRenderer::ScheduleOverlays(DrawingFrame* frame) {
-  if (!frame->overlay_list.size())
-    return;
-
-  ResourceProvider::ResourceIdArray resources;
-  OverlayCandidateList& overlays = frame->overlay_list;
-  OverlayCandidateList::iterator it;
-  for (it = overlays.begin(); it != overlays.end(); ++it) {
-    const OverlayCandidate& overlay = *it;
-    // Skip primary plane.
-    if (overlay.plane_z_order == 0)
-      continue;
-
-    pending_overlay_resources_.push_back(
-        make_scoped_ptr(new ResourceProvider::ScopedReadLockGL(
-            resource_provider_, overlay.resource_id)));
-
-    context_support_->ScheduleOverlayPlane(
-        overlay.plane_z_order,
-        overlay.transform,
-        pending_overlay_resources_.back()->texture_id(),
-        overlay.display_rect,
-        overlay.uv_rect);
-  }
-}
-
-}  // namespace cc
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
deleted file mode 100644
index 1bb8c2d..0000000
--- a/cc/output/gl_renderer.h
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 2010 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.
-
-#ifndef CC_OUTPUT_GL_RENDERER_H_
-#define CC_OUTPUT_GL_RENDERER_H_
-
-#include "base/cancelable_callback.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/output/gl_renderer_draw_cache.h"
-#include "cc/output/program_binding.h"
-#include "cc/output/renderer.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-class SkBitmap;
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace cc {
-
-class GLRendererShaderTest;
-class OutputSurface;
-class PictureDrawQuad;
-class ScopedResource;
-class StreamVideoDrawQuad;
-class TextureDrawQuad;
-class TextureMailboxDeleter;
-class StaticGeometryBinding;
-class DynamicGeometryBinding;
-class ScopedEnsureFramebufferAllocation;
-
-// Class that handles drawing of composited render layers using GL.
-class GLRenderer : public DirectRenderer {
- public:
-  class ScopedUseGrContext;
-
-  static scoped_ptr<GLRenderer> Create(
-      RendererClient* client,
-      const RendererSettings* settings,
-      OutputSurface* output_surface,
-      ResourceProvider* resource_provider,
-      TextureMailboxDeleter* texture_mailbox_deleter,
-      int highp_threshold_min);
-
-  ~GLRenderer() override;
-
-  const RendererCapabilitiesImpl& Capabilities() const override;
-
-  // Waits for rendering to finish.
-  void Finish() override;
-
-  void DoNoOp() override;
-  void SwapBuffers(const CompositorFrameMetadata& metadata) override;
-
-  virtual bool IsContextLost();
-
-  static void DebugGLCall(gpu::gles2::GLES2Interface* gl,
-                          const char* command,
-                          const char* file,
-                          int line);
-
- protected:
-  GLRenderer(RendererClient* client,
-             const RendererSettings* settings,
-             OutputSurface* output_surface,
-             ResourceProvider* resource_provider,
-             TextureMailboxDeleter* texture_mailbox_deleter,
-             int highp_threshold_min);
-
-  void DidChangeVisibility() override;
-
-  bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; }
-
-  const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; }
-  const StaticGeometryBinding* SharedGeometry() const {
-    return shared_geometry_.get();
-  }
-
-  void GetFramebufferPixelsAsync(const DrawingFrame* frame,
-                                 const gfx::Rect& rect,
-                                 scoped_ptr<CopyOutputRequest> request);
-  void GetFramebufferTexture(unsigned texture_id,
-                             ResourceFormat texture_format,
-                             const gfx::Rect& device_rect);
-  void ReleaseRenderPassTextures();
-  enum BoundGeometry { NO_BINDING, SHARED_BINDING, CLIPPED_BINDING };
-  void PrepareGeometry(BoundGeometry geometry_to_bind);
-  void SetStencilEnabled(bool enabled);
-  bool stencil_enabled() const { return stencil_shadow_; }
-  void SetBlendEnabled(bool enabled);
-  bool blend_enabled() const { return blend_shadow_; }
-
-  void BindFramebufferToOutputSurface(DrawingFrame* frame) override;
-  bool BindFramebufferToTexture(DrawingFrame* frame,
-                                const ScopedResource* resource,
-                                const gfx::Rect& target_rect) override;
-  void SetDrawViewport(const gfx::Rect& window_space_viewport) override;
-  void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
-  void PrepareSurfaceForPass(DrawingFrame* frame,
-                             SurfaceInitializationMode initialization_mode,
-                             const gfx::Rect& render_pass_scissor) override;
-  void DoDrawQuad(DrawingFrame* frame,
-                  const class DrawQuad*,
-                  const gfx::QuadF* draw_region) override;
-  void BeginDrawingFrame(DrawingFrame* frame) override;
-  void FinishDrawingFrame(DrawingFrame* frame) override;
-  bool FlippedFramebuffer(const DrawingFrame* frame) const override;
-  bool FlippedRootFramebuffer() const;
-  void EnsureScissorTestEnabled() override;
-  void EnsureScissorTestDisabled() override;
-  void CopyCurrentRenderPassToBitmap(
-      DrawingFrame* frame,
-      scoped_ptr<CopyOutputRequest> request) override;
-  void FinishDrawingQuadList() override;
-
-  // Returns true if quad requires antialiasing and false otherwise.
-  static bool ShouldAntialiasQuad(const gfx::Transform& device_transform,
-                                  const DrawQuad* quad,
-                                  bool force_antialiasing);
-
-  // Inflate the quad and fill edge array for fragment shader.
-  // |local_quad| is set to inflated quad. |edge| array is filled with
-  // inflated quad's edge data.
-  static void SetupQuadForClippingAndAntialiasing(
-      const gfx::Transform& device_transform,
-      const DrawQuad* quad,
-      bool use_aa,
-      const gfx::QuadF* clip_region,
-      gfx::QuadF* local_quad,
-      float edge[24]);
-
- private:
-  friend class GLRendererShaderPixelTest;
-  friend class GLRendererShaderTest;
-
-  static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform);
-
-  void DiscardPixels();
-  void ClearFramebuffer(DrawingFrame* frame);
-
-  void DrawCheckerboardQuad(const DrawingFrame* frame,
-                            const CheckerboardDrawQuad* quad,
-                            const gfx::QuadF* clip_region);
-  void DrawDebugBorderQuad(const DrawingFrame* frame,
-                           const DebugBorderDrawQuad* quad);
-  static bool IsDefaultBlendMode(SkXfermode::Mode blend_mode) {
-    return blend_mode == SkXfermode::kSrcOver_Mode;
-  }
-  bool CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode);
-  void ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode);
-  void RestoreBlendFuncToDefault(SkXfermode::Mode blend_mode);
-
-  gfx::Rect GetBackdropBoundingBoxForRenderPassQuad(
-      DrawingFrame* frame,
-      const RenderPassDrawQuad* quad,
-      const gfx::Transform& contents_device_transform,
-      const gfx::QuadF* clip_region,
-      bool use_aa);
-  scoped_ptr<ScopedResource> GetBackdropTexture(const gfx::Rect& bounding_rect);
-
-  void DrawRenderPassQuad(DrawingFrame* frame,
-                          const RenderPassDrawQuad* quadi,
-                          const gfx::QuadF* clip_region);
-  void DrawSolidColorQuad(const DrawingFrame* frame,
-                          const SolidColorDrawQuad* quad,
-                          const gfx::QuadF* clip_region);
-  void DrawStreamVideoQuad(const DrawingFrame* frame,
-                           const StreamVideoDrawQuad* quad,
-                           const gfx::QuadF* clip_region);
-  void DrawTextureQuad(const DrawingFrame* frame,
-                       const TextureDrawQuad* quad,
-                       const gfx::QuadF* clip_region);
-  void EnqueueTextureQuad(const DrawingFrame* frame,
-                          const TextureDrawQuad* quad,
-                          const gfx::QuadF* clip_region);
-  void FlushTextureQuadCache(BoundGeometry flush_binding);
-  void DrawIOSurfaceQuad(const DrawingFrame* frame,
-                         const IOSurfaceDrawQuad* quad,
-                         const gfx::QuadF* clip_region);
-  void DrawTileQuad(const DrawingFrame* frame,
-                    const TileDrawQuad* quad,
-                    const gfx::QuadF* clip_region);
-  void DrawContentQuad(const DrawingFrame* frame,
-                       const ContentDrawQuadBase* quad,
-                       ResourceProvider::ResourceId resource_id,
-                       const gfx::QuadF* clip_region);
-  void DrawContentQuadAA(const DrawingFrame* frame,
-                         const ContentDrawQuadBase* quad,
-                         ResourceProvider::ResourceId resource_id,
-                         const gfx::Transform& device_transform,
-                         const gfx::QuadF* clip_region);
-  void DrawContentQuadNoAA(const DrawingFrame* frame,
-                           const ContentDrawQuadBase* quad,
-                           ResourceProvider::ResourceId resource_id,
-                           const gfx::QuadF* clip_region);
-  void DrawYUVVideoQuad(const DrawingFrame* frame,
-                        const YUVVideoDrawQuad* quad,
-                        const gfx::QuadF* clip_region);
-  void DrawPictureQuad(const DrawingFrame* frame,
-                       const PictureDrawQuad* quad,
-                       const gfx::QuadF* clip_region);
-
-  void SetShaderOpacity(float opacity, int alpha_location);
-  void SetShaderQuadF(const gfx::QuadF& quad, int quad_location);
-  void DrawQuadGeometryClippedByQuadF(const DrawingFrame* frame,
-                                      const gfx::Transform& draw_transform,
-                                      const gfx::RectF& quad_rect,
-                                      const gfx::QuadF& clipping_region_quad,
-                                      int matrix_location,
-                                      const float uv[8]);
-  void DrawQuadGeometry(const DrawingFrame* frame,
-                        const gfx::Transform& draw_transform,
-                        const gfx::RectF& quad_rect,
-                        int matrix_location);
-  void SetUseProgram(unsigned program);
-
-  bool UseScopedTexture(DrawingFrame* frame,
-                        const ScopedResource* resource,
-                        const gfx::Rect& viewport_rect);
-
-  bool MakeContextCurrent();
-
-  void InitializeSharedObjects();
-  void CleanupSharedObjects();
-
-  typedef base::Callback<void(scoped_ptr<CopyOutputRequest> copy_request,
-                              bool success)>
-      AsyncGetFramebufferPixelsCleanupCallback;
-  void FinishedReadback(unsigned source_buffer,
-                        unsigned query,
-                        const gfx::Size& size);
-
-  void ReinitializeGLState();
-  void RestoreGLState();
-  void RestoreFramebuffer(DrawingFrame* frame);
-
-  void DiscardBackbuffer() override;
-  void EnsureBackbuffer() override;
-  void EnforceMemoryPolicy();
-
-  void ScheduleOverlays(DrawingFrame* frame);
-
-  typedef ScopedPtrVector<ResourceProvider::ScopedReadLockGL>
-      OverlayResourceLockList;
-  OverlayResourceLockList pending_overlay_resources_;
-  OverlayResourceLockList in_use_overlay_resources_;
-
-  RendererCapabilitiesImpl capabilities_;
-
-  unsigned offscreen_framebuffer_id_;
-
-  scoped_ptr<StaticGeometryBinding> shared_geometry_;
-  scoped_ptr<DynamicGeometryBinding> clipped_geometry_;
-  gfx::QuadF shared_geometry_quad_;
-
-  // This block of bindings defines all of the programs used by the compositor
-  // itself.  Add any new programs here to GLRendererShaderTest.
-
-  // Tiled layer shaders.
-  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexAlpha>
-      TileProgram;
-  typedef ProgramBinding<VertexShaderTileAA, FragmentShaderRGBATexClampAlphaAA>
-      TileProgramAA;
-  typedef ProgramBinding<VertexShaderTileAA,
-                         FragmentShaderRGBATexClampSwizzleAlphaAA>
-      TileProgramSwizzleAA;
-  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexOpaque>
-      TileProgramOpaque;
-  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleAlpha>
-      TileProgramSwizzle;
-  typedef ProgramBinding<VertexShaderTile, FragmentShaderRGBATexSwizzleOpaque>
-      TileProgramSwizzleOpaque;
-  typedef ProgramBinding<VertexShaderPosTex, FragmentShaderCheckerboard>
-      TileCheckerboardProgram;
-
-  // Texture shaders.
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexVaryingAlpha> TextureProgram;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexPremultiplyAlpha>
-      NonPremultipliedTextureProgram;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderTexBackgroundVaryingAlpha>
-      TextureBackgroundProgram;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderTexBackgroundPremultiplyAlpha>
-      NonPremultipliedTextureBackgroundProgram;
-
-  // Render surface shaders.
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexAlpha> RenderPassProgram;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexAlphaMask> RenderPassMaskProgram;
-  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
-                         FragmentShaderRGBATexAlphaAA> RenderPassProgramAA;
-  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
-                         FragmentShaderRGBATexAlphaMaskAA>
-      RenderPassMaskProgramAA;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexColorMatrixAlpha>
-      RenderPassColorMatrixProgram;
-  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
-                         FragmentShaderRGBATexAlphaMaskColorMatrixAA>
-      RenderPassMaskColorMatrixProgramAA;
-  typedef ProgramBinding<VertexShaderQuadTexTransformAA,
-                         FragmentShaderRGBATexAlphaColorMatrixAA>
-      RenderPassColorMatrixProgramAA;
-  typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexAlphaMaskColorMatrix>
-      RenderPassMaskColorMatrixProgram;
-
-  // Video shaders.
-  typedef ProgramBinding<VertexShaderVideoTransform, FragmentShaderRGBATex>
-      VideoStreamTextureProgram;
-  typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset,
-                         FragmentShaderYUVVideo> VideoYUVProgram;
-  typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset,
-                         FragmentShaderYUVAVideo> VideoYUVAProgram;
-
-  // Special purpose / effects shaders.
-  typedef ProgramBinding<VertexShaderPos, FragmentShaderColor>
-      DebugBorderProgram;
-  typedef ProgramBinding<VertexShaderQuad, FragmentShaderColor>
-      SolidColorProgram;
-  typedef ProgramBinding<VertexShaderQuadAA, FragmentShaderColorAA>
-      SolidColorProgramAA;
-
-  const TileProgram* GetTileProgram(
-      TexCoordPrecision precision, SamplerType sampler);
-  const TileProgramOpaque* GetTileProgramOpaque(
-      TexCoordPrecision precision, SamplerType sampler);
-  const TileProgramAA* GetTileProgramAA(
-      TexCoordPrecision precision, SamplerType sampler);
-  const TileProgramSwizzle* GetTileProgramSwizzle(
-      TexCoordPrecision precision, SamplerType sampler);
-  const TileProgramSwizzleOpaque* GetTileProgramSwizzleOpaque(
-      TexCoordPrecision precision, SamplerType sampler);
-  const TileProgramSwizzleAA* GetTileProgramSwizzleAA(
-      TexCoordPrecision precision, SamplerType sampler);
-
-  const TileCheckerboardProgram* GetTileCheckerboardProgram();
-
-  const RenderPassProgram* GetRenderPassProgram(TexCoordPrecision precision,
-                                                BlendMode blend_mode);
-  const RenderPassProgramAA* GetRenderPassProgramAA(TexCoordPrecision precision,
-                                                    BlendMode blend_mode);
-  const RenderPassMaskProgram* GetRenderPassMaskProgram(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      BlendMode blend_mode,
-      bool mask_for_background);
-  const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      BlendMode blend_mode,
-      bool mask_for_background);
-  const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram(
-      TexCoordPrecision precision,
-      BlendMode blend_mode);
-  const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA(
-      TexCoordPrecision precision,
-      BlendMode blend_mode);
-  const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram(
-      TexCoordPrecision precision,
-      SamplerType sampler,
-      BlendMode blend_mode,
-      bool mask_for_background);
-  const RenderPassMaskColorMatrixProgramAA*
-  GetRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
-                                        SamplerType sampler,
-                                        BlendMode blend_mode,
-                                        bool mask_for_background);
-
-  const TextureProgram* GetTextureProgram(
-      TexCoordPrecision precision);
-  const NonPremultipliedTextureProgram* GetNonPremultipliedTextureProgram(
-      TexCoordPrecision precision);
-  const TextureBackgroundProgram* GetTextureBackgroundProgram(
-      TexCoordPrecision precision);
-  const NonPremultipliedTextureBackgroundProgram*
-      GetNonPremultipliedTextureBackgroundProgram(TexCoordPrecision precision);
-  const TextureProgram* GetTextureIOSurfaceProgram(
-      TexCoordPrecision precision);
-
-  const VideoYUVProgram* GetVideoYUVProgram(
-      TexCoordPrecision precision);
-  const VideoYUVAProgram* GetVideoYUVAProgram(
-      TexCoordPrecision precision);
-  const VideoStreamTextureProgram* GetVideoStreamTextureProgram(
-      TexCoordPrecision precision);
-
-  const DebugBorderProgram* GetDebugBorderProgram();
-  const SolidColorProgram* GetSolidColorProgram();
-  const SolidColorProgramAA* GetSolidColorProgramAA();
-
-  TileProgram
-      tile_program_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1];
-  TileProgramOpaque
-      tile_program_opaque_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1];
-  TileProgramAA
-      tile_program_aa_[LAST_TEX_COORD_PRECISION + 1][LAST_SAMPLER_TYPE + 1];
-  TileProgramSwizzle tile_program_swizzle_[LAST_TEX_COORD_PRECISION +
-                                           1][LAST_SAMPLER_TYPE + 1];
-  TileProgramSwizzleOpaque
-      tile_program_swizzle_opaque_[LAST_TEX_COORD_PRECISION +
-                                   1][LAST_SAMPLER_TYPE + 1];
-  TileProgramSwizzleAA tile_program_swizzle_aa_[LAST_TEX_COORD_PRECISION +
-                                                1][LAST_SAMPLER_TYPE + 1];
-
-  TileCheckerboardProgram tile_checkerboard_program_;
-
-  TextureProgram texture_program_[LAST_TEX_COORD_PRECISION + 1];
-  NonPremultipliedTextureProgram
-      nonpremultiplied_texture_program_[LAST_TEX_COORD_PRECISION + 1];
-  TextureBackgroundProgram
-      texture_background_program_[LAST_TEX_COORD_PRECISION + 1];
-  NonPremultipliedTextureBackgroundProgram
-      nonpremultiplied_texture_background_program_[LAST_TEX_COORD_PRECISION +
-                                                   1];
-  TextureProgram texture_io_surface_program_[LAST_TEX_COORD_PRECISION + 1];
-
-  RenderPassProgram
-      render_pass_program_[LAST_TEX_COORD_PRECISION + 1][LAST_BLEND_MODE + 1];
-  RenderPassProgramAA render_pass_program_aa_[LAST_TEX_COORD_PRECISION +
-                                              1][LAST_BLEND_MODE + 1];
-  RenderPassMaskProgram
-      render_pass_mask_program_[LAST_TEX_COORD_PRECISION + 1]
-                               [LAST_SAMPLER_TYPE + 1]
-                               [LAST_BLEND_MODE + 1]
-                               [LAST_MASK_VALUE + 1];
-  RenderPassMaskProgramAA
-      render_pass_mask_program_aa_[LAST_TEX_COORD_PRECISION + 1]
-                                  [LAST_SAMPLER_TYPE + 1]
-                                  [LAST_BLEND_MODE + 1]
-                                  [LAST_MASK_VALUE + 1];
-  RenderPassColorMatrixProgram
-      render_pass_color_matrix_program_[LAST_TEX_COORD_PRECISION +
-                                        1][LAST_BLEND_MODE + 1];
-  RenderPassColorMatrixProgramAA
-      render_pass_color_matrix_program_aa_[LAST_TEX_COORD_PRECISION +
-                                           1][LAST_BLEND_MODE + 1];
-  RenderPassMaskColorMatrixProgram
-      render_pass_mask_color_matrix_program_[LAST_TEX_COORD_PRECISION + 1]
-                                            [LAST_SAMPLER_TYPE + 1]
-                                            [LAST_BLEND_MODE + 1]
-                                            [LAST_MASK_VALUE + 1];
-  RenderPassMaskColorMatrixProgramAA
-      render_pass_mask_color_matrix_program_aa_[LAST_TEX_COORD_PRECISION + 1]
-                                               [LAST_SAMPLER_TYPE + 1]
-                                               [LAST_BLEND_MODE + 1]
-                                               [LAST_MASK_VALUE + 1];
-
-  VideoYUVProgram video_yuv_program_[LAST_TEX_COORD_PRECISION + 1];
-  VideoYUVAProgram video_yuva_program_[LAST_TEX_COORD_PRECISION + 1];
-  VideoStreamTextureProgram
-      video_stream_texture_program_[LAST_TEX_COORD_PRECISION + 1];
-
-  DebugBorderProgram debug_border_program_;
-  SolidColorProgram solid_color_program_;
-  SolidColorProgramAA solid_color_program_aa_;
-
-  gpu::gles2::GLES2Interface* gl_;
-  gpu::ContextSupport* context_support_;
-
-  TextureMailboxDeleter* texture_mailbox_deleter_;
-
-  gfx::Rect swap_buffer_rect_;
-  gfx::Rect scissor_rect_;
-  gfx::Rect viewport_;
-  bool is_backbuffer_discarded_;
-  bool is_using_bind_uniform_;
-  bool is_scissor_enabled_;
-  bool scissor_rect_needs_reset_;
-  bool stencil_shadow_;
-  bool blend_shadow_;
-  unsigned program_shadow_;
-  TexturedQuadDrawCache draw_cache_;
-  int highp_threshold_min_;
-  int highp_threshold_cache_;
-
-  struct PendingAsyncReadPixels;
-  ScopedPtrVector<PendingAsyncReadPixels> pending_async_read_pixels_;
-
-  scoped_ptr<ResourceProvider::ScopedWriteLockGL> current_framebuffer_lock_;
-
-  class SyncQuery;
-  ScopedPtrDeque<SyncQuery> pending_sync_queries_;
-  ScopedPtrDeque<SyncQuery> available_sync_queries_;
-  scoped_ptr<SyncQuery> current_sync_query_;
-  bool use_sync_query_;
-  bool use_blend_equation_advanced_;
-  bool use_blend_equation_advanced_coherent_;
-
-  SkBitmap on_demand_tile_raster_bitmap_;
-  ResourceProvider::ResourceId on_demand_tile_raster_resource_id_;
-  BoundGeometry bound_geometry_;
-  DISALLOW_COPY_AND_ASSIGN(GLRenderer);
-};
-
-// Setting DEBUG_GL_CALLS to 1 will call glGetError() after almost every GL
-// call made by the compositor. Useful for debugging rendering issues but
-// will significantly degrade performance.
-#define DEBUG_GL_CALLS 0
-
-#if DEBUG_GL_CALLS && !defined(NDEBUG)
-#define GLC(context, x)                                                        \
-  (x, GLRenderer::DebugGLCall(&* context, #x, __FILE__, __LINE__))
-#else
-#define GLC(context, x) (x)
-#endif
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_GL_RENDERER_H_
diff --git a/cc/output/gl_renderer_draw_cache.cc b/cc/output/gl_renderer_draw_cache.cc
deleted file mode 100644
index 91581f4..0000000
--- a/cc/output/gl_renderer_draw_cache.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/gl_renderer_draw_cache.h"
-
-namespace cc {
-
-TexturedQuadDrawCache::TexturedQuadDrawCache()
-    : program_id(-1),
-      resource_id(-1),
-      needs_blending(false),
-      nearest_neighbor(false),
-      background_color(0),
-      uv_xform_location(-1),
-      background_color_location(-1),
-      vertex_opacity_location(-1),
-      matrix_location(-1),
-      sampler_location(-1) {
-}
-
-TexturedQuadDrawCache::~TexturedQuadDrawCache() {}
-
-}  // namespace cc
diff --git a/cc/output/gl_renderer_draw_cache.h b/cc/output/gl_renderer_draw_cache.h
deleted file mode 100644
index a16c8a5..0000000
--- a/cc/output/gl_renderer_draw_cache.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_GL_RENDERER_DRAW_CACHE_H_
-#define CC_OUTPUT_GL_RENDERER_DRAW_CACHE_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-
-// Collects 4 floats at a time for easy upload to GL.
-struct Float4 {
-  float data[4];
-};
-
-// Collects 16 floats at a time for easy upload to GL.
-struct Float16 {
-  float data[16];
-};
-
-// A cache for storing textured quads to be drawn.  Stores the minimum required
-// data to tell if two back to back draws only differ in their transform. Quads
-// that only differ by transform may be coalesced into a single draw call.
-struct TexturedQuadDrawCache {
-  TexturedQuadDrawCache();
-  ~TexturedQuadDrawCache();
-
-  // Values tracked to determine if textured quads may be coalesced.
-  int program_id;
-  int resource_id;
-  bool needs_blending;
-  bool nearest_neighbor;
-  SkColor background_color;
-
-  // Information about the program binding that is required to draw.
-  int uv_xform_location;
-  int background_color_location;
-  int vertex_opacity_location;
-  int matrix_location;
-  int sampler_location;
-
-  // A cache for the coalesced quad data.
-  std::vector<Float4> uv_xform_data;
-  std::vector<float> vertex_opacity_data;
-  std::vector<Float16> matrix_data;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TexturedQuadDrawCache);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_GL_RENDERER_DRAW_CACHE_H_
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
deleted file mode 100644
index 7e0f8e0..0000000
--- a/cc/output/gl_renderer_unittest.cc
+++ /dev/null
@@ -1,2076 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/gl_renderer.h"
-
-#include <set>
-
-#include "cc/base/math_util.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/test/fake_impl_proxy.h"
-#include "cc/test/fake_layer_tree_host_impl.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_renderer_client.h"
-#include "cc/test/pixel_test.h"
-#include "cc/test/render_pass_test_common.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/context_support.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
-#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "ui/gfx/transform.h"
-
-using testing::_;
-using testing::AnyNumber;
-using testing::Args;
-using testing::AtLeast;
-using testing::ElementsAre;
-using testing::Expectation;
-using testing::InSequence;
-using testing::Mock;
-using testing::Return;
-using testing::StrictMock;
-
-namespace cc {
-
-class GLRendererTest : public testing::Test {
- protected:
-  RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); }
-
-  RenderPassList render_passes_in_draw_order_;
-};
-
-#define EXPECT_PROGRAM_VALID(program_binding)      \
-  do {                                             \
-    EXPECT_TRUE((program_binding)->program());     \
-    EXPECT_TRUE((program_binding)->initialized()); \
-  } while (false)
-
-static inline SkXfermode::Mode BlendModeToSkXfermode(BlendMode blend_mode) {
-  switch (blend_mode) {
-    case BLEND_MODE_NONE:
-    case BLEND_MODE_NORMAL:
-      return SkXfermode::kSrcOver_Mode;
-    case BLEND_MODE_SCREEN:
-      return SkXfermode::kScreen_Mode;
-    case BLEND_MODE_OVERLAY:
-      return SkXfermode::kOverlay_Mode;
-    case BLEND_MODE_DARKEN:
-      return SkXfermode::kDarken_Mode;
-    case BLEND_MODE_LIGHTEN:
-      return SkXfermode::kLighten_Mode;
-    case BLEND_MODE_COLOR_DODGE:
-      return SkXfermode::kColorDodge_Mode;
-    case BLEND_MODE_COLOR_BURN:
-      return SkXfermode::kColorBurn_Mode;
-    case BLEND_MODE_HARD_LIGHT:
-      return SkXfermode::kHardLight_Mode;
-    case BLEND_MODE_SOFT_LIGHT:
-      return SkXfermode::kSoftLight_Mode;
-    case BLEND_MODE_DIFFERENCE:
-      return SkXfermode::kDifference_Mode;
-    case BLEND_MODE_EXCLUSION:
-      return SkXfermode::kExclusion_Mode;
-    case BLEND_MODE_MULTIPLY:
-      return SkXfermode::kMultiply_Mode;
-    case BLEND_MODE_HUE:
-      return SkXfermode::kHue_Mode;
-    case BLEND_MODE_SATURATION:
-      return SkXfermode::kSaturation_Mode;
-    case BLEND_MODE_COLOR:
-      return SkXfermode::kColor_Mode;
-    case BLEND_MODE_LUMINOSITY:
-      return SkXfermode::kLuminosity_Mode;
-  }
-  return SkXfermode::kSrcOver_Mode;
-}
-
-// Explicitly named to be a friend in GLRenderer for shader access.
-class GLRendererShaderPixelTest : public GLRendererPixelTest {
- public:
-  void SetUp() override {
-    GLRendererPixelTest::SetUp();
-    ASSERT_FALSE(renderer()->IsContextLost());
-  }
-
-  void TearDown() override {
-    GLRendererPixelTest::TearDown();
-    ASSERT_FALSE(renderer()->IsContextLost());
-  }
-
-  void TestBasicShaders() {
-    EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram());
-    EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram());
-    EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram());
-    EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA());
-  }
-
-  void TestShadersWithPrecision(TexCoordPrecision precision) {
-    EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetNonPremultipliedTextureProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetNonPremultipliedTextureBackgroundProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
-    EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision));
-    if (renderer()->Capabilities().using_egl_image)
-      EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
-    else
-      EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision));
-  }
-
-  void TestShadersWithPrecisionAndBlend(TexCoordPrecision precision,
-                                        BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassProgram(precision, blend_mode));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetRenderPassProgramAA(precision, blend_mode));
-  }
-
-  void TestShadersWithPrecisionAndSampler(TexCoordPrecision precision,
-                                          SamplerType sampler) {
-    if (!renderer()->Capabilities().using_egl_image &&
-        sampler == SAMPLER_TYPE_EXTERNAL_OES) {
-      // This will likely be hit in tests due to usage of osmesa.
-      return;
-    }
-
-    EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler));
-    EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler));
-    EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler));
-    EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetTileProgramSwizzleOpaque(precision, sampler));
-    EXPECT_PROGRAM_VALID(
-        renderer()->GetTileProgramSwizzleAA(precision, sampler));
-  }
-
-  void TestShadersWithMasks(TexCoordPrecision precision,
-                            SamplerType sampler,
-                            BlendMode blend_mode,
-                            bool mask_for_background) {
-    if (!renderer()->Capabilities().using_egl_image &&
-        sampler == SAMPLER_TYPE_EXTERNAL_OES) {
-      // This will likely be hit in tests due to usage of osmesa.
-      return;
-    }
-
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(
-        precision, sampler, blend_mode, mask_for_background));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(
-        precision, sampler, blend_mode, mask_for_background));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgramAA(
-        precision, sampler, blend_mode, mask_for_background));
-    EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskColorMatrixProgram(
-        precision, sampler, blend_mode, mask_for_background));
-  }
-};
-
-namespace {
-
-#if !defined(OS_ANDROID) && !defined(OS_WIN)
-static const TexCoordPrecision kPrecisionList[] = {TEX_COORD_PRECISION_MEDIUM,
-                                                   TEX_COORD_PRECISION_HIGH};
-
-static const BlendMode kBlendModeList[LAST_BLEND_MODE + 1] = {
-    BLEND_MODE_NONE,
-    BLEND_MODE_NORMAL,
-    BLEND_MODE_SCREEN,
-    BLEND_MODE_OVERLAY,
-    BLEND_MODE_DARKEN,
-    BLEND_MODE_LIGHTEN,
-    BLEND_MODE_COLOR_DODGE,
-    BLEND_MODE_COLOR_BURN,
-    BLEND_MODE_HARD_LIGHT,
-    BLEND_MODE_SOFT_LIGHT,
-    BLEND_MODE_DIFFERENCE,
-    BLEND_MODE_EXCLUSION,
-    BLEND_MODE_MULTIPLY,
-    BLEND_MODE_HUE,
-    BLEND_MODE_SATURATION,
-    BLEND_MODE_COLOR,
-    BLEND_MODE_LUMINOSITY,
-};
-
-static const SamplerType kSamplerList[] = {
-    SAMPLER_TYPE_2D,
-    SAMPLER_TYPE_2D_RECT,
-    SAMPLER_TYPE_EXTERNAL_OES,
-};
-
-TEST_F(GLRendererShaderPixelTest, BasicShadersCompile) {
-  TestBasicShaders();
-}
-
-class PrecisionShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<TexCoordPrecision> {};
-
-TEST_P(PrecisionShaderPixelTest, ShadersCompile) {
-  TestShadersWithPrecision(GetParam());
-}
-
-INSTANTIATE_TEST_CASE_P(PrecisionShadersCompile,
-                        PrecisionShaderPixelTest,
-                        ::testing::ValuesIn(kPrecisionList));
-
-class PrecisionBlendShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tr1::tuple<TexCoordPrecision, BlendMode>> {};
-
-TEST_P(PrecisionBlendShaderPixelTest, ShadersCompile) {
-  TestShadersWithPrecisionAndBlend(std::tr1::get<0>(GetParam()),
-                                   std::tr1::get<1>(GetParam()));
-}
-
-INSTANTIATE_TEST_CASE_P(
-    PrecisionBlendShadersCompile,
-    PrecisionBlendShaderPixelTest,
-    ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                       ::testing::ValuesIn(kBlendModeList)));
-
-class PrecisionSamplerShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tr1::tuple<TexCoordPrecision, SamplerType>> {};
-
-TEST_P(PrecisionSamplerShaderPixelTest, ShadersCompile) {
-  TestShadersWithPrecisionAndSampler(std::tr1::get<0>(GetParam()),
-                                     std::tr1::get<1>(GetParam()));
-}
-
-INSTANTIATE_TEST_CASE_P(PrecisionSamplerShadersCompile,
-                        PrecisionSamplerShaderPixelTest,
-                        ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                                           ::testing::ValuesIn(kSamplerList)));
-
-class MaskShaderPixelTest
-    : public GLRendererShaderPixelTest,
-      public ::testing::WithParamInterface<
-          std::tr1::tuple<TexCoordPrecision, SamplerType, BlendMode, bool>> {};
-
-TEST_P(MaskShaderPixelTest, ShadersCompile) {
-  TestShadersWithMasks(
-      std::tr1::get<0>(GetParam()), std::tr1::get<1>(GetParam()),
-      std::tr1::get<2>(GetParam()), std::tr1::get<3>(GetParam()));
-}
-
-INSTANTIATE_TEST_CASE_P(MaskShadersCompile,
-                        MaskShaderPixelTest,
-                        ::testing::Combine(::testing::ValuesIn(kPrecisionList),
-                                           ::testing::ValuesIn(kSamplerList),
-                                           ::testing::ValuesIn(kBlendModeList),
-                                           ::testing::Bool()));
-
-#endif
-
-class FakeRendererGL : public GLRenderer {
- public:
-  FakeRendererGL(RendererClient* client,
-                 const RendererSettings* settings,
-                 OutputSurface* output_surface,
-                 ResourceProvider* resource_provider)
-      : GLRenderer(client,
-                   settings,
-                   output_surface,
-                   resource_provider,
-                   NULL,
-                   0) {}
-
-  // GLRenderer methods.
-
-  // Changing visibility to public.
-  using GLRenderer::IsBackbufferDiscarded;
-  using GLRenderer::DoDrawQuad;
-  using GLRenderer::BeginDrawingFrame;
-  using GLRenderer::FinishDrawingQuadList;
-  using GLRenderer::stencil_enabled;
-};
-
-class GLRendererWithDefaultHarnessTest : public GLRendererTest {
- protected:
-  GLRendererWithDefaultHarnessTest() {
-    output_surface_ =
-        FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass();
-    CHECK(output_surface_->BindToClient(&output_surface_client_));
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1).Pass();
-    renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_,
-                                                   &settings_,
-                                                   output_surface_.get(),
-                                                   resource_provider_.get()));
-  }
-
-  void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
-
-  RendererSettings settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_ptr<FakeOutputSurface> output_surface_;
-  FakeRendererClient renderer_client_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<FakeRendererGL> renderer_;
-};
-
-// Closing the namespace here so that GLRendererShaderTest can take advantage
-// of the friend relationship with GLRenderer and all of the mock classes
-// declared above it.
-}  // namespace
-
-class GLRendererShaderTest : public GLRendererTest {
- protected:
-  GLRendererShaderTest() {
-    output_surface_ = FakeOutputSurface::Create3d().Pass();
-    CHECK(output_surface_->BindToClient(&output_surface_client_));
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1).Pass();
-    renderer_.reset(new FakeRendererGL(&renderer_client_,
-                                       &settings_,
-                                       output_surface_.get(),
-                                       resource_provider_.get()));
-  }
-
-  void TestRenderPassProgram(TexCoordPrecision precision,
-                             BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_program_[precision][blend_mode]);
-    EXPECT_EQ(renderer_->render_pass_program_[precision][blend_mode].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestRenderPassColorMatrixProgram(TexCoordPrecision precision,
-                                        BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_color_matrix_program_[precision][blend_mode]);
-    EXPECT_EQ(
-        renderer_->render_pass_color_matrix_program_[precision][blend_mode]
-            .program(),
-        renderer_->program_shadow_);
-  }
-
-  void TestRenderPassMaskProgram(TexCoordPrecision precision,
-                                 SamplerType sampler,
-                                 BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_mask_program_[precision]
-                                             [sampler]
-                                             [blend_mode]
-                                             [NO_MASK]);
-    EXPECT_EQ(
-        renderer_->render_pass_mask_program_[precision]
-                                            [sampler]
-                                            [blend_mode]
-                                            [NO_MASK].program(),
-        renderer_->program_shadow_);
-  }
-
-  void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision,
-                                            SamplerType sampler,
-                                            BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_
-                              [precision][sampler][blend_mode][NO_MASK]);
-    EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_
-                  [precision][sampler][blend_mode][NO_MASK].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestRenderPassProgramAA(TexCoordPrecision precision,
-                               BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_->render_pass_program_aa_[precision][blend_mode]);
-    EXPECT_EQ(
-        renderer_->render_pass_program_aa_[precision][blend_mode].program(),
-        renderer_->program_shadow_);
-  }
-
-  void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision,
-                                          BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_
-             ->render_pass_color_matrix_program_aa_[precision][blend_mode]);
-    EXPECT_EQ(
-        renderer_->render_pass_color_matrix_program_aa_[precision][blend_mode]
-            .program(),
-        renderer_->program_shadow_);
-  }
-
-  void TestRenderPassMaskProgramAA(TexCoordPrecision precision,
-                                   SamplerType sampler,
-                                   BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(
-        &renderer_
-             ->render_pass_mask_program_aa_
-                 [precision][sampler][blend_mode][NO_MASK]);
-    EXPECT_EQ(
-        renderer_->render_pass_mask_program_aa_[precision][sampler][blend_mode]
-            [NO_MASK].program(),
-        renderer_->program_shadow_);
-  }
-
-  void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision,
-                                              SamplerType sampler,
-                                              BlendMode blend_mode) {
-    EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_color_matrix_program_aa_
-                              [precision][sampler][blend_mode][NO_MASK]);
-    EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_
-                  [precision][sampler][blend_mode][NO_MASK].program(),
-              renderer_->program_shadow_);
-  }
-
-  void TestSolidColorProgramAA() {
-    EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_);
-    EXPECT_EQ(renderer_->solid_color_program_aa_.program(),
-              renderer_->program_shadow_);
-  }
-
-  RendererSettings settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_ptr<FakeOutputSurface> output_surface_;
-  FakeRendererClient renderer_client_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<FakeRendererGL> renderer_;
-};
-
-namespace {
-
-// Test GLRenderer DiscardBackbuffer functionality:
-// Suggest discarding framebuffer when one exists and the renderer is not
-// visible.
-// Expected: it is discarded and damage tracker is reset.
-TEST_F(
-    GLRendererWithDefaultHarnessTest,
-    SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) {
-  renderer_->SetVisible(false);
-  EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
-  EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
-}
-
-// Test GLRenderer DiscardBackbuffer functionality:
-// Suggest discarding framebuffer when one exists and the renderer is visible.
-// Expected: the allocation is ignored.
-TEST_F(GLRendererWithDefaultHarnessTest,
-       SuggestBackbufferNoDoNothingWhenVisible) {
-  renderer_->SetVisible(true);
-  EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count());
-  EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
-}
-
-// Test GLRenderer DiscardBackbuffer functionality:
-// Suggest discarding framebuffer when one does not exist.
-// Expected: it does nothing.
-TEST_F(GLRendererWithDefaultHarnessTest,
-       SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) {
-  renderer_->SetVisible(false);
-  EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
-  EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
-
-  EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
-  EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
-}
-
-// Test GLRenderer DiscardBackbuffer functionality:
-// Begin drawing a frame while a framebuffer is discarded.
-// Expected: will recreate framebuffer.
-TEST_F(GLRendererWithDefaultHarnessTest,
-       DiscardedBackbufferIsRecreatedForScopeDuration) {
-  gfx::Rect viewport_rect(1, 1);
-  renderer_->SetVisible(false);
-  EXPECT_TRUE(renderer_->IsBackbufferDiscarded());
-  EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count());
-
-  AddRenderPass(&render_passes_in_draw_order_,
-                RenderPassId(1, 0),
-                viewport_rect,
-                gfx::Transform());
-
-  renderer_->SetVisible(true);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  EXPECT_FALSE(renderer_->IsBackbufferDiscarded());
-
-  SwapBuffers();
-  EXPECT_EQ(1u, output_surface_->num_sent_frames());
-}
-
-TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) {
-  gfx::Rect viewport_rect(1, 1);
-  EXPECT_FALSE(renderer_->stencil_enabled());
-
-  output_surface_->set_has_external_stencil_test(true);
-
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            RenderPassId(1, 0),
-                                            viewport_rect,
-                                            gfx::Transform());
-  root_pass->has_transparent_background = false;
-
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-  EXPECT_TRUE(renderer_->stencil_enabled());
-}
-
-class ForbidSynchronousCallContext : public TestWebGraphicsContext3D {
- public:
-  ForbidSynchronousCallContext() {}
-
-  void getAttachedShaders(GLuint program,
-                          GLsizei max_count,
-                          GLsizei* count,
-                          GLuint* shaders) override {
-    ADD_FAILURE();
-  }
-  GLint getAttribLocation(GLuint program, const GLchar* name) override {
-    ADD_FAILURE();
-    return 0;
-  }
-  void getBooleanv(GLenum pname, GLboolean* value) override { ADD_FAILURE(); }
-  void getBufferParameteriv(GLenum target,
-                            GLenum pname,
-                            GLint* value) override {
-    ADD_FAILURE();
-  }
-  GLenum getError() override {
-    ADD_FAILURE();
-    return GL_NO_ERROR;
-  }
-  void getFloatv(GLenum pname, GLfloat* value) override { ADD_FAILURE(); }
-  void getFramebufferAttachmentParameteriv(GLenum target,
-                                           GLenum attachment,
-                                           GLenum pname,
-                                           GLint* value) override {
-    ADD_FAILURE();
-  }
-  void getIntegerv(GLenum pname, GLint* value) override {
-    if (pname == GL_MAX_TEXTURE_SIZE) {
-      // MAX_TEXTURE_SIZE is cached client side, so it's OK to query.
-      *value = 1024;
-    } else {
-      ADD_FAILURE();
-    }
-  }
-
-  // We allow querying the shader compilation and program link status in debug
-  // mode, but not release.
-  void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
-#ifndef NDEBUG
-    *value = 1;
-#else
-    ADD_FAILURE();
-#endif
-  }
-
-  void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
-#ifndef NDEBUG
-    *value = 1;
-#else
-    ADD_FAILURE();
-#endif
-  }
-
-  void getRenderbufferParameteriv(GLenum target,
-                                  GLenum pname,
-                                  GLint* value) override {
-    ADD_FAILURE();
-  }
-
-  void getShaderPrecisionFormat(GLenum shadertype,
-                                GLenum precisiontype,
-                                GLint* range,
-                                GLint* precision) override {
-    ADD_FAILURE();
-  }
-  void getTexParameterfv(GLenum target, GLenum pname, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-  void getTexParameteriv(GLenum target, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-  void getUniformfv(GLuint program, GLint location, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-  void getUniformiv(GLuint program, GLint location, GLint* value) override {
-    ADD_FAILURE();
-  }
-  GLint getUniformLocation(GLuint program, const GLchar* name) override {
-    ADD_FAILURE();
-    return 0;
-  }
-  void getVertexAttribfv(GLuint index, GLenum pname, GLfloat* value) override {
-    ADD_FAILURE();
-  }
-  void getVertexAttribiv(GLuint index, GLenum pname, GLint* value) override {
-    ADD_FAILURE();
-  }
-  GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname) override {
-    ADD_FAILURE();
-    return 0;
-  }
-};
-TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) {
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
-      scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext)));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-}
-
-class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D {
- public:
-  LoseContextOnFirstGetContext() {}
-
-  void getProgramiv(GLuint program, GLenum pname, GLint* value) override {
-    context_lost_ = true;
-    *value = 0;
-  }
-
-  void getShaderiv(GLuint shader, GLenum pname, GLint* value) override {
-    context_lost_ = true;
-    *value = 0;
-  }
-};
-
-TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) {
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d(
-      scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext)));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-}
-
-class ClearCountingContext : public TestWebGraphicsContext3D {
- public:
-  ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; }
-
-  MOCK_METHOD3(discardFramebufferEXT,
-               void(GLenum target,
-                    GLsizei numAttachments,
-                    const GLenum* attachments));
-  MOCK_METHOD1(clear, void(GLbitfield mask));
-};
-
-TEST_F(GLRendererTest, OpaqueBackground) {
-  scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
-  ClearCountingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  gfx::Rect viewport_rect(1, 1);
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            RenderPassId(1, 0),
-                                            viewport_rect,
-                                            gfx::Transform());
-  root_pass->has_transparent_background = false;
-
-  // On DEBUG builds, render passes with opaque background clear to blue to
-  // easily see regions that were not drawn on the screen.
-  EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
-      .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT)))
-      .Times(1);
-#ifdef NDEBUG
-  EXPECT_CALL(*context, clear(_)).Times(0);
-#else
-  EXPECT_CALL(*context, clear(_)).Times(1);
-#endif
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_F(GLRendererTest, TransparentBackground) {
-  scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
-  ClearCountingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  gfx::Rect viewport_rect(1, 1);
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            RenderPassId(1, 0),
-                                            viewport_rect,
-                                            gfx::Transform());
-  root_pass->has_transparent_background = true;
-
-  EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1);
-  EXPECT_CALL(*context, clear(_)).Times(1);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_F(GLRendererTest, OffscreenOutputSurface) {
-  scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext);
-  ClearCountingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::CreateOffscreen(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  gfx::Rect viewport_rect(1, 1);
-  AddRenderPass(&render_passes_in_draw_order_,
-                RenderPassId(1, 0),
-                viewport_rect,
-                gfx::Transform());
-
-  EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _))
-      .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0)))
-      .Times(1);
-  EXPECT_CALL(*context, clear(_)).Times(AnyNumber());
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-  Mock::VerifyAndClearExpectations(context);
-}
-
-class VisibilityChangeIsLastCallTrackingContext
-    : public TestWebGraphicsContext3D {
- public:
-  VisibilityChangeIsLastCallTrackingContext()
-      : last_call_was_set_visibility_(false) {}
-
-  // TestWebGraphicsContext3D methods.
-  void flush() override { last_call_was_set_visibility_ = false; }
-  void deleteTexture(GLuint) override { last_call_was_set_visibility_ = false; }
-  void deleteFramebuffer(GLuint) override {
-    last_call_was_set_visibility_ = false;
-  }
-  void deleteQueryEXT(GLuint) override {
-    last_call_was_set_visibility_ = false;
-  }
-  void deleteRenderbuffer(GLuint) override {
-    last_call_was_set_visibility_ = false;
-  }
-
-  // Methods added for test.
-  void set_last_call_was_visibility(bool visible) {
-    DCHECK(last_call_was_set_visibility_ == false);
-    last_call_was_set_visibility_ = true;
-  }
-  bool last_call_was_set_visibility() const {
-    return last_call_was_set_visibility_;
-  }
-
- private:
-  bool last_call_was_set_visibility_;
-};
-
-TEST_F(GLRendererTest, VisibilityChangeIsLastCall) {
-  scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned(
-      new VisibilityChangeIsLastCallTrackingContext);
-  VisibilityChangeIsLastCallTrackingContext* context = context_owned.get();
-
-  scoped_refptr<TestContextProvider> provider =
-      TestContextProvider::Create(context_owned.Pass());
-
-  provider->support()->SetSurfaceVisibleCallback(base::Bind(
-      &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility,
-      base::Unretained(context)));
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(provider));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  gfx::Rect viewport_rect(1, 1);
-  AddRenderPass(&render_passes_in_draw_order_,
-                RenderPassId(1, 0),
-                viewport_rect,
-                gfx::Transform());
-
-  // Ensure that the call to SetSurfaceVisible is the last call issue to the
-  // GPU process, after glFlush is called, and after the RendererClient's
-  // SetManagedMemoryPolicy is called. Plumb this tracking between both the
-  // RenderClient and the Context by giving them both a pointer to a variable on
-  // the stack.
-  renderer.SetVisible(true);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-  renderer.SetVisible(false);
-  EXPECT_TRUE(context->last_call_was_set_visibility());
-}
-
-class TextureStateTrackingContext : public TestWebGraphicsContext3D {
- public:
-  TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) {
-    test_capabilities_.gpu.egl_image_external = true;
-  }
-
-  MOCK_METHOD1(waitSyncPoint, void(unsigned sync_point));
-  MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
-  MOCK_METHOD4(drawElements,
-               void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
-
-  virtual void activeTexture(GLenum texture) {
-    EXPECT_NE(texture, active_texture_);
-    active_texture_ = texture;
-  }
-
-  GLenum active_texture() const { return active_texture_; }
-
- private:
-  GLenum active_texture_;
-};
-
-TEST_F(GLRendererTest, ActiveTextureState) {
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  // During initialization we are allowed to set any texture parameters.
-  EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber());
-
-  RenderPassId id(1, 1);
-  TestRenderPass* root_pass = AddRenderPass(
-      &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform());
-  root_pass->AppendOneOfEveryQuadType(resource_provider.get(),
-                                      RenderPassId(2, 1));
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-
-  // Set up expected texture filter state transitions that match the quads
-  // created in AppendOneOfEveryQuadType().
-  Mock::VerifyAndClearExpectations(context);
-  {
-    InSequence sequence;
-
-    // The sync points for all quads are waited on first. This sync point is
-    // for a texture quad drawn later in the frame.
-    EXPECT_CALL(*context,
-                waitSyncPoint(TestRenderPass::kSyncPointForMailboxTextureQuad))
-        .Times(1);
-
-    // yuv_quad is drawn with the default linear filter.
-    EXPECT_CALL(*context, drawElements(_, _, _, _));
-
-    // tile_quad is drawn with GL_NEAREST because it is not transformed or
-    // scaled.
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
-    EXPECT_CALL(*context, drawElements(_, _, _, _));
-
-    // transformed_tile_quad uses GL_LINEAR.
-    EXPECT_CALL(*context, drawElements(_, _, _, _));
-
-    // scaled_tile_quad also uses GL_LINEAR.
-    EXPECT_CALL(*context, drawElements(_, _, _, _));
-
-    // The remaining quads also use GL_LINEAR because nearest neighbor
-    // filtering is currently only used with tile quads.
-    EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(7);
-  }
-
-  gfx::Rect viewport_rect(100, 100);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-  Mock::VerifyAndClearExpectations(context);
-}
-
-class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D {
- public:
-  MOCK_METHOD1(clear, void(GLbitfield mask));
-  MOCK_METHOD4(drawElements,
-               void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
-};
-
-TEST_F(GLRendererTest, ShouldClearRootRenderPass) {
-  scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned(
-      new NoClearRootRenderPassMockContext);
-  NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(mock_context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  settings.should_clear_root_render_pass = false;
-
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-
-  gfx::Rect viewport_rect(10, 10);
-
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            root_pass_id,
-                                            viewport_rect,
-                                            gfx::Transform());
-  AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-
-  RenderPassId child_pass_id(2, 0);
-  TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                             child_pass_id,
-                                             viewport_rect,
-                                             gfx::Transform());
-  AddQuad(child_pass, viewport_rect, SK_ColorBLUE);
-
-  AddRenderPassQuad(root_pass, child_pass);
-
-#ifdef NDEBUG
-  GLint clear_bits = GL_COLOR_BUFFER_BIT;
-#else
-  GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
-#endif
-
-  // First render pass is not the root one, clearing should happen.
-  EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1));
-
-  Expectation first_render_pass =
-      EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1);
-
-  // The second render pass is the root one, clearing should be prevented.
-  EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After(
-      first_render_pass);
-
-  EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After(
-      first_render_pass);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-
-  // In multiple render passes all but the root pass should clear the
-  // framebuffer.
-  Mock::VerifyAndClearExpectations(&mock_context);
-}
-
-class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D {
- public:
-  ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {}
-
-  void clear(GLbitfield) override { EXPECT_FALSE(scissor_enabled_); }
-
-  void enable(GLenum cap) override {
-    if (cap == GL_SCISSOR_TEST)
-      scissor_enabled_ = true;
-  }
-
-  void disable(GLenum cap) override {
-    if (cap == GL_SCISSOR_TEST)
-      scissor_enabled_ = false;
-  }
-
- private:
-  bool scissor_enabled_;
-};
-
-TEST_F(GLRendererTest, ScissorTestWhenClearing) {
-  scoped_ptr<ScissorTestOnClearCheckingContext> context_owned(
-      new ScissorTestOnClearCheckingContext);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-  EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
-
-  gfx::Rect viewport_rect(1, 1);
-
-  gfx::Rect grand_child_rect(25, 25);
-  RenderPassId grand_child_pass_id(3, 0);
-  TestRenderPass* grand_child_pass =
-      AddRenderPass(&render_passes_in_draw_order_,
-                    grand_child_pass_id,
-                    grand_child_rect,
-                    gfx::Transform());
-  AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW);
-
-  gfx::Rect child_rect(50, 50);
-  RenderPassId child_pass_id(2, 0);
-  TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                             child_pass_id,
-                                             child_rect,
-                                             gfx::Transform());
-  AddQuad(child_pass, child_rect, SK_ColorBLUE);
-
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            root_pass_id,
-                                            viewport_rect,
-                                            gfx::Transform());
-  AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-
-  AddRenderPassQuad(root_pass, child_pass);
-  AddRenderPassQuad(child_pass, grand_child_pass);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     viewport_rect,
-                     viewport_rect,
-                     false);
-}
-
-class DiscardCheckingContext : public TestWebGraphicsContext3D {
- public:
-  DiscardCheckingContext() : discarded_(0) {
-    set_have_post_sub_buffer(true);
-    set_have_discard_framebuffer(true);
-  }
-
-  void discardFramebufferEXT(GLenum target,
-                             GLsizei numAttachments,
-                             const GLenum* attachments) override {
-    ++discarded_;
-  }
-
-  int discarded() const { return discarded_; }
-  void reset() { discarded_ = 0; }
-
- private:
-  int discarded_;
-};
-
-class NonReshapableOutputSurface : public FakeOutputSurface {
- public:
-  explicit NonReshapableOutputSurface(
-      scoped_ptr<TestWebGraphicsContext3D> context3d)
-      : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()),
-                          false) {
-    surface_size_ = gfx::Size(500, 500);
-  }
-  void Reshape(const gfx::Size& size, float scale_factor) override {}
-  void set_fixed_size(const gfx::Size& size) { surface_size_ = size; }
-};
-
-TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) {
-  scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext);
-  DiscardCheckingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<NonReshapableOutputSurface> output_surface(
-      new NonReshapableOutputSurface(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-  output_surface->set_fixed_size(gfx::Size(100, 100));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-  EXPECT_TRUE(renderer.Capabilities().using_partial_swap);
-
-  gfx::Rect viewport_rect(100, 100);
-  gfx::Rect clip_rect(100, 100);
-
-  {
-    // Partial frame, should not discard.
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(0, context->discarded());
-    context->reset();
-  }
-  {
-    // Full frame, should discard.
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(1, context->discarded());
-    context->reset();
-  }
-  {
-    // Full frame, external scissor is set, should not discard.
-    output_surface->set_has_external_stencil_test(true);
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-    root_pass->has_transparent_background = false;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(0, context->discarded());
-    context->reset();
-    output_surface->set_has_external_stencil_test(false);
-  }
-  {
-    // Full frame, clipped, should not discard.
-    clip_rect = gfx::Rect(10, 10, 10, 10);
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(0, context->discarded());
-    context->reset();
-  }
-  {
-    // Full frame, doesn't cover the surface, should not discard.
-    viewport_rect = gfx::Rect(10, 10, 10, 10);
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(0, context->discarded());
-    context->reset();
-  }
-  {
-    // Full frame, doesn't cover the surface (no offset), should not discard.
-    clip_rect = gfx::Rect(100, 100);
-    viewport_rect = gfx::Rect(50, 50);
-    RenderPassId root_pass_id(1, 0);
-    TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                              root_pass_id,
-                                              viewport_rect,
-                                              gfx::Transform());
-    AddQuad(root_pass, viewport_rect, SK_ColorGREEN);
-    root_pass->damage_rect = root_pass->output_rect;
-
-    renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-    renderer.DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       clip_rect,
-                       false);
-    EXPECT_EQ(0, context->discarded());
-    context->reset();
-  }
-}
-
-class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D {
- public:
-  MOCK_METHOD4(viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
-  MOCK_METHOD4(scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
-};
-
-TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) {
-  // In Android WebView, the OutputSurface is unable to respect reshape() calls
-  // and maintains a fixed size. This test verifies that glViewport and
-  // glScissor's Y coordinate is flipped correctly in this environment, and that
-  // the glViewport can be at a nonzero origin within the surface.
-  scoped_ptr<FlippedScissorAndViewportContext> context_owned(
-      new FlippedScissorAndViewportContext);
-
-  // We expect exactly one call to viewport on this context and exactly two
-  // to scissor (one to scissor the clear, one to scissor the quad draw).
-  EXPECT_CALL(*context_owned, viewport(10, 390, 100, 100));
-  EXPECT_CALL(*context_owned, scissor(10, 390, 100, 100));
-  EXPECT_CALL(*context_owned, scissor(30, 450, 20, 20));
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      new NonReshapableOutputSurface(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client,
-                          &settings,
-                          output_surface.get(),
-                          resource_provider.get());
-  EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
-
-  gfx::Rect device_viewport_rect(10, 10, 100, 100);
-  gfx::Rect viewport_rect(device_viewport_rect.size());
-  gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
-
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                            root_pass_id,
-                                            viewport_rect,
-                                            gfx::Transform());
-  AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer.DrawFrame(&render_passes_in_draw_order_,
-                     1.f,
-                     device_viewport_rect,
-                     device_viewport_rect,
-                     false);
-}
-
-TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) {
-  // When using render-to-FBO to display the surface, all rendering is done
-  // to a non-zero FBO. Make sure that the framebuffer is always restored to
-  // the correct framebuffer during rendering, if changed.
-  // Note: there is one path that will set it to 0, but that is after the render
-  // has finished.
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create().Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      output_surface.get(), shared_bitmap_manager.get(), NULL, NULL, 0, false,
-      1));
-
-  RendererSettings settings;
-  FakeRendererClient renderer_client;
-  FakeRendererGL renderer(&renderer_client, &settings, output_surface.get(),
-                          resource_provider.get());
-  EXPECT_FALSE(renderer.Capabilities().using_partial_swap);
-
-  gfx::Rect device_viewport_rect(0, 0, 100, 100);
-  gfx::Rect viewport_rect(device_viewport_rect.size());
-  gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20);
-
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass =
-      AddRenderPass(&render_passes_in_draw_order_, root_pass_id, viewport_rect,
-                    gfx::Transform());
-  AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN);
-
-  unsigned fbo;
-  gpu::gles2::GLES2Interface* gl =
-      output_surface->context_provider()->ContextGL();
-  gl->GenFramebuffers(1, &fbo);
-  output_surface->set_framebuffer(fbo);
-
-  renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect,
-                     device_viewport_rect, false);
-
-  int bound_fbo;
-  gl->GetIntegerv(GL_FRAMEBUFFER_BINDING, &bound_fbo);
-  EXPECT_EQ(static_cast<int>(fbo), bound_fbo);
-}
-
-TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
-  gfx::Rect viewport_rect(1, 1);
-
-  gfx::Rect child_rect(50, 50);
-  RenderPassId child_pass_id(2, 0);
-  TestRenderPass* child_pass;
-
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass;
-
-  ResourceProvider::ResourceId mask = resource_provider_->CreateResource(
-      gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider_->best_texture_format());
-  resource_provider_->AllocateForTesting(mask);
-
-  SkScalar matrix[20];
-  float amount = 0.5f;
-  matrix[0] = 0.213f + 0.787f * amount;
-  matrix[1] = 0.715f - 0.715f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = matrix[4] = 0;
-  matrix[5] = 0.213f - 0.213f * amount;
-  matrix[6] = 0.715f + 0.285f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = matrix[9] = 0;
-  matrix[10] = 0.213f - 0.213f * amount;
-  matrix[11] = 0.715f - 0.715f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = matrix[14] = 0;
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
-  matrix[18] = 1;
-  skia::RefPtr<SkColorFilter> color_filter(
-      skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
-  skia::RefPtr<SkImageFilter> filter = skia::AdoptRef(
-      SkColorFilterImageFilter::Create(color_filter.get(), NULL));
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateReferenceFilter(filter));
-
-  gfx::Transform transform_causing_aa;
-  transform_causing_aa.Rotate(20.0);
-
-  for (int i = 0; i <= LAST_BLEND_MODE; ++i) {
-    BlendMode blend_mode = static_cast<BlendMode>(i);
-    SkXfermode::Mode xfer_mode = BlendModeToSkXfermode(blend_mode);
-    settings_.force_blending_with_shaders = (blend_mode != BLEND_MODE_NONE);
-    // RenderPassProgram
-    render_passes_in_draw_order_.clear();
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               gfx::Transform());
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(root_pass,
-                      child_pass,
-                      0,
-                      FilterOperations(),
-                      gfx::Transform(),
-                      xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassColorMatrixProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               transform_causing_aa);
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(
-        root_pass, child_pass, 0, filters, gfx::Transform(), xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassMaskProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               gfx::Transform());
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(root_pass,
-                      child_pass,
-                      mask,
-                      FilterOperations(),
-                      gfx::Transform(),
-                      xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassMaskProgram(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
-                              blend_mode);
-
-    // RenderPassMaskColorMatrixProgram
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               gfx::Transform());
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(
-        root_pass, child_pass, mask, filters, gfx::Transform(), xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassMaskColorMatrixProgram(TEX_COORD_PRECISION_MEDIUM,
-                                         SAMPLER_TYPE_2D, blend_mode);
-
-    // RenderPassProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               transform_causing_aa);
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(root_pass,
-                      child_pass,
-                      0,
-                      FilterOperations(),
-                      transform_causing_aa,
-                      xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassColorMatrixProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               transform_causing_aa);
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(
-        root_pass, child_pass, 0, filters, transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM, blend_mode);
-
-    // RenderPassMaskProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               transform_causing_aa);
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              gfx::Transform());
-
-    AddRenderPassQuad(root_pass,
-                      child_pass,
-                      mask,
-                      FilterOperations(),
-                      transform_causing_aa,
-                      xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassMaskProgramAA(TEX_COORD_PRECISION_MEDIUM, SAMPLER_TYPE_2D,
-                                blend_mode);
-
-    // RenderPassMaskColorMatrixProgramAA
-    render_passes_in_draw_order_.clear();
-
-    child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                               child_pass_id,
-                               child_rect,
-                               transform_causing_aa);
-
-    root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                              root_pass_id,
-                              viewport_rect,
-                              transform_causing_aa);
-
-    AddRenderPassQuad(
-        root_pass, child_pass, mask, filters, transform_causing_aa, xfer_mode);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         1.f,
-                         viewport_rect,
-                         viewport_rect,
-                         false);
-    TestRenderPassMaskColorMatrixProgramAA(TEX_COORD_PRECISION_MEDIUM,
-                                           SAMPLER_TYPE_2D, blend_mode);
-  }
-}
-
-// At this time, the AA code path cannot be taken if the surface's rect would
-// project incorrectly by the given transform, because of w<0 clipping.
-TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) {
-  gfx::Rect child_rect(50, 50);
-  RenderPassId child_pass_id(2, 0);
-  TestRenderPass* child_pass;
-
-  gfx::Rect viewport_rect(1, 1);
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass;
-
-  gfx::Transform transform_preventing_aa;
-  transform_preventing_aa.ApplyPerspectiveDepth(40.0);
-  transform_preventing_aa.RotateAboutYAxis(-20.0);
-  transform_preventing_aa.Scale(30.0, 1.0);
-
-  // Verify that the test transform and test rect actually do cause the clipped
-  // flag to trigger. Otherwise we are not testing the intended scenario.
-  bool clipped = false;
-  MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped);
-  ASSERT_TRUE(clipped);
-
-  child_pass = AddRenderPass(&render_passes_in_draw_order_,
-                             child_pass_id,
-                             child_rect,
-                             transform_preventing_aa);
-
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
-
-  AddRenderPassQuad(root_pass,
-                    child_pass,
-                    0,
-                    FilterOperations(),
-                    transform_preventing_aa,
-                    SkXfermode::kSrcOver_Mode);
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-
-  // If use_aa incorrectly ignores clipping, it will use the
-  // RenderPassProgramAA shader instead of the RenderPassProgram.
-  TestRenderPassProgram(TEX_COORD_PRECISION_MEDIUM, BLEND_MODE_NONE);
-}
-
-TEST_F(GLRendererShaderTest, DrawSolidColorShader) {
-  gfx::Rect viewport_rect(1, 1);
-  RenderPassId root_pass_id(1, 0);
-  TestRenderPass* root_pass;
-
-  gfx::Transform pixel_aligned_transform_causing_aa;
-  pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f);
-  pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f);
-
-  root_pass = AddRenderPass(&render_passes_in_draw_order_,
-                            root_pass_id,
-                            viewport_rect,
-                            gfx::Transform());
-  AddTransformedQuad(root_pass,
-                     viewport_rect,
-                     SK_ColorYELLOW,
-                     pixel_aligned_transform_causing_aa);
-
-  renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_);
-  renderer_->DrawFrame(&render_passes_in_draw_order_,
-                       1.f,
-                       viewport_rect,
-                       viewport_rect,
-                       false);
-
-  TestSolidColorProgramAA();
-}
-
-class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
- public:
-  OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; }
-
-  // Specifically override methods even if they are unused (used in conjunction
-  // with StrictMock). We need to make sure that GLRenderer does not issue
-  // framebuffer-related GLuint calls directly. Instead these are supposed to go
-  // through the OutputSurface abstraction.
-  MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer));
-  MOCK_METHOD3(reshapeWithScaleFactor,
-               void(int width, int height, float scale_factor));
-  MOCK_METHOD4(drawElements,
-               void(GLenum mode, GLsizei count, GLenum type, GLintptr offset));
-};
-
-class MockOutputSurface : public OutputSurface {
- public:
-  MockOutputSurface()
-      : OutputSurface(
-            TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>(
-                new StrictMock<OutputSurfaceMockContext>))) {
-    surface_size_ = gfx::Size(100, 100);
-  }
-  virtual ~MockOutputSurface() {}
-
-  MOCK_METHOD0(EnsureBackbuffer, void());
-  MOCK_METHOD0(DiscardBackbuffer, void());
-  MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor));
-  MOCK_METHOD0(BindFramebuffer, void());
-  MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame));
-};
-
-class MockOutputSurfaceTest : public GLRendererTest {
- protected:
-  virtual void SetUp() {
-    FakeOutputSurfaceClient output_surface_client_;
-    CHECK(output_surface_.BindToClient(&output_surface_client_));
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-    resource_provider_ = ResourceProvider::Create(&output_surface_,
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1).Pass();
-
-    renderer_.reset(new FakeRendererGL(&renderer_client_,
-                                       &settings_,
-                                       &output_surface_,
-                                       resource_provider_.get()));
-  }
-
-  void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
-
-  void DrawFrame(float device_scale_factor,
-                 const gfx::Rect& device_viewport_rect) {
-    RenderPassId render_pass_id(1, 0);
-    TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_,
-                                                render_pass_id,
-                                                device_viewport_rect,
-                                                gfx::Transform());
-    AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN);
-
-    EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return());
-
-    EXPECT_CALL(output_surface_,
-                Reshape(device_viewport_rect.size(), device_scale_factor))
-        .Times(1);
-
-    EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1);
-
-    EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1);
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        render_passes_in_draw_order_);
-    renderer_->DrawFrame(&render_passes_in_draw_order_,
-                         device_scale_factor,
-                         device_viewport_rect,
-                         device_viewport_rect,
-                         false);
-  }
-
-  OutputSurfaceMockContext* Context() {
-    return static_cast<OutputSurfaceMockContext*>(
-        static_cast<TestContextProvider*>(output_surface_.context_provider())
-            ->TestContext3d());
-  }
-
-  RendererSettings settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  StrictMock<MockOutputSurface> output_surface_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  FakeRendererClient renderer_client_;
-  scoped_ptr<FakeRendererGL> renderer_;
-};
-
-TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) {
-  gfx::Rect device_viewport_rect(1, 1);
-  DrawFrame(1.f, device_viewport_rect);
-
-  EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
-  renderer_->SwapBuffers(CompositorFrameMetadata());
-}
-
-TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) {
-  gfx::Rect device_viewport_rect(1, 1);
-
-  DrawFrame(1.f, device_viewport_rect);
-  EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
-  renderer_->SwapBuffers(CompositorFrameMetadata());
-
-  device_viewport_rect = gfx::Rect(2, 2);
-
-  DrawFrame(2.f, device_viewport_rect);
-  EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
-  renderer_->SwapBuffers(CompositorFrameMetadata());
-
-  DrawFrame(2.f, device_viewport_rect);
-  EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
-  renderer_->SwapBuffers(CompositorFrameMetadata());
-
-  device_viewport_rect = gfx::Rect(1, 1);
-
-  DrawFrame(1.f, device_viewport_rect);
-  EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1);
-  renderer_->SwapBuffers(CompositorFrameMetadata());
-}
-
-class GLRendererTestSyncPoint : public GLRendererPixelTest {
- protected:
-  static void SyncPointCallback(int* callback_count) {
-    ++(*callback_count);
-    base::MessageLoop::current()->QuitWhenIdle();
-  }
-
-  static void OtherCallback(int* callback_count) {
-    ++(*callback_count);
-    base::MessageLoop::current()->QuitWhenIdle();
-  }
-};
-
-#if !defined(OS_ANDROID)
-TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) {
-  int sync_point_callback_count = 0;
-  int other_callback_count = 0;
-  gpu::gles2::GLES2Interface* gl =
-      output_surface_->context_provider()->ContextGL();
-  gpu::ContextSupport* context_support =
-      output_surface_->context_provider()->ContextSupport();
-
-  uint32 sync_point = gl->InsertSyncPointCHROMIUM();
-
-  gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
-                          GL_INNOCENT_CONTEXT_RESET_ARB);
-
-  context_support->SignalSyncPoint(
-      sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
-  EXPECT_EQ(0, sync_point_callback_count);
-  EXPECT_EQ(0, other_callback_count);
-
-  // Make the sync point happen.
-  gl->Finish();
-  // Post a task after the sync point.
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
-
-  base::MessageLoop::current()->Run();
-
-  // The sync point shouldn't have happened since the context was lost.
-  EXPECT_EQ(0, sync_point_callback_count);
-  EXPECT_EQ(1, other_callback_count);
-}
-
-TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) {
-  int sync_point_callback_count = 0;
-  int other_callback_count = 0;
-
-  gpu::gles2::GLES2Interface* gl =
-      output_surface_->context_provider()->ContextGL();
-  gpu::ContextSupport* context_support =
-      output_surface_->context_provider()->ContextSupport();
-
-  uint32 sync_point = gl->InsertSyncPointCHROMIUM();
-
-  context_support->SignalSyncPoint(
-      sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count));
-  EXPECT_EQ(0, sync_point_callback_count);
-  EXPECT_EQ(0, other_callback_count);
-
-  // Make the sync point happen.
-  gl->Finish();
-  // Post a task after the sync point.
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE, base::Bind(&OtherCallback, &other_callback_count));
-
-  base::MessageLoop::current()->Run();
-
-  // The sync point should have happened.
-  EXPECT_EQ(1, sync_point_callback_count);
-  EXPECT_EQ(1, other_callback_count);
-}
-#endif  // OS_ANDROID
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc
deleted file mode 100644
index 630019e..0000000
--- a/cc/output/output_surface.cc
+++ /dev/null
@@ -1,250 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "cc/output/output_surface.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/output_surface_client.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-
-namespace cc {
-
-OutputSurface::OutputSurface(
-    const scoped_refptr<ContextProvider>& context_provider,
-    const scoped_refptr<ContextProvider>& worker_context_provider,
-    scoped_ptr<SoftwareOutputDevice> software_device)
-    : client_(NULL),
-      context_provider_(context_provider),
-      worker_context_provider_(worker_context_provider),
-      software_device_(software_device.Pass()),
-      device_scale_factor_(-1),
-      external_stencil_test_enabled_(false),
-      weak_ptr_factory_(this) {
-}
-
-OutputSurface::OutputSurface(
-    const scoped_refptr<ContextProvider>& context_provider)
-    : OutputSurface(context_provider, nullptr, nullptr) {
-}
-
-OutputSurface::OutputSurface(
-    const scoped_refptr<ContextProvider>& context_provider,
-    const scoped_refptr<ContextProvider>& worker_context_provider)
-    : OutputSurface(context_provider, worker_context_provider, nullptr) {
-}
-
-OutputSurface::OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
-    : OutputSurface(nullptr, nullptr, software_device.Pass()) {
-}
-
-OutputSurface::OutputSurface(
-    const scoped_refptr<ContextProvider>& context_provider,
-    scoped_ptr<SoftwareOutputDevice> software_device)
-    : OutputSurface(context_provider, nullptr, software_device.Pass()) {
-}
-
-void OutputSurface::CommitVSyncParameters(base::TimeTicks timebase,
-                                          base::TimeDelta interval) {
-  TRACE_EVENT2("cc",
-               "OutputSurface::CommitVSyncParameters",
-               "timebase",
-               (timebase - base::TimeTicks()).InSecondsF(),
-               "interval",
-               interval.InSecondsF());
-  client_->CommitVSyncParameters(timebase, interval);
-}
-
-// Forwarded to OutputSurfaceClient
-void OutputSurface::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
-  TRACE_EVENT0("cc", "OutputSurface::SetNeedsRedrawRect");
-  client_->SetNeedsRedrawRect(damage_rect);
-}
-
-void OutputSurface::ReclaimResources(const CompositorFrameAck* ack) {
-  client_->ReclaimResources(ack);
-}
-
-void OutputSurface::DidLoseOutputSurface() {
-  TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface");
-  client_->DidLoseOutputSurface();
-}
-
-void OutputSurface::SetExternalStencilTest(bool enabled) {
-  external_stencil_test_enabled_ = enabled;
-}
-
-void OutputSurface::SetExternalDrawConstraints(
-    const gfx::Transform& transform,
-    const gfx::Rect& viewport,
-    const gfx::Rect& clip,
-    const gfx::Rect& viewport_rect_for_tile_priority,
-    const gfx::Transform& transform_for_tile_priority,
-    bool resourceless_software_draw) {
-  client_->SetExternalDrawConstraints(transform,
-                                      viewport,
-                                      clip,
-                                      viewport_rect_for_tile_priority,
-                                      transform_for_tile_priority,
-                                      resourceless_software_draw);
-}
-
-OutputSurface::~OutputSurface() {
-  ResetContext3d();
-}
-
-bool OutputSurface::HasExternalStencilTest() const {
-  return external_stencil_test_enabled_;
-}
-
-bool OutputSurface::BindToClient(OutputSurfaceClient* client) {
-  DCHECK(client);
-  client_ = client;
-  bool success = true;
-
-  if (context_provider_.get()) {
-    success = context_provider_->BindToCurrentThread();
-    if (success)
-      SetUpContext3d();
-  }
-
-  if (success && worker_context_provider_.get()) {
-    success = worker_context_provider_->BindToCurrentThread();
-    if (success) {
-      worker_context_provider_->SetupLock();
-      // The destructor resets the context lost callback, so base::Unretained
-      // is safe, as long as the worker threads stop using the context before
-      // the output surface is destroyed.
-      worker_context_provider_->SetLostContextCallback(base::Bind(
-          &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
-    }
-  }
-
-  if (!success)
-    client_ = NULL;
-
-  return success;
-}
-
-bool OutputSurface::InitializeAndSetContext3d(
-    scoped_refptr<ContextProvider> context_provider,
-    scoped_refptr<ContextProvider> worker_context_provider) {
-  DCHECK(!context_provider_.get());
-  DCHECK(context_provider.get());
-  DCHECK(client_);
-
-  bool success = context_provider->BindToCurrentThread();
-  if (success) {
-    context_provider_ = context_provider;
-    SetUpContext3d();
-  }
-  if (success && worker_context_provider.get()) {
-    success = worker_context_provider->BindToCurrentThread();
-    if (success) {
-      worker_context_provider_ = worker_context_provider;
-      // The destructor resets the context lost callback, so base::Unretained
-      // is safe, as long as the worker threads stop using the context before
-      // the output surface is destroyed.
-      worker_context_provider_->SetLostContextCallback(base::Bind(
-          &OutputSurface::DidLoseOutputSurface, base::Unretained(this)));
-    }
-  }
-
-  if (!success)
-    ResetContext3d();
-  else
-    client_->DeferredInitialize();
-
-  return success;
-}
-
-void OutputSurface::ReleaseGL() {
-  DCHECK(client_);
-  DCHECK(context_provider_.get());
-  client_->ReleaseGL();
-  DCHECK(!context_provider_.get());
-}
-
-void OutputSurface::SetUpContext3d() {
-  DCHECK(context_provider_.get());
-  DCHECK(client_);
-
-  context_provider_->SetLostContextCallback(
-      base::Bind(&OutputSurface::DidLoseOutputSurface,
-                 base::Unretained(this)));
-}
-
-void OutputSurface::ReleaseContextProvider() {
-  DCHECK(client_);
-  DCHECK(context_provider_.get());
-  ResetContext3d();
-}
-
-void OutputSurface::ResetContext3d() {
-  if (context_provider_.get()) {
-    context_provider_->SetLostContextCallback(
-        ContextProvider::LostContextCallback());
-  }
-  if (worker_context_provider_.get()) {
-    worker_context_provider_->SetLostContextCallback(
-        ContextProvider::LostContextCallback());
-  }
-  context_provider_ = NULL;
-  worker_context_provider_ = NULL;
-}
-
-void OutputSurface::EnsureBackbuffer() {
-  if (software_device_)
-    software_device_->EnsureBackbuffer();
-}
-
-void OutputSurface::DiscardBackbuffer() {
-  if (context_provider_.get())
-    context_provider_->ContextGL()->DiscardBackbufferCHROMIUM();
-  if (software_device_)
-    software_device_->DiscardBackbuffer();
-}
-
-void OutputSurface::Reshape(const gfx::Size& size, float scale_factor) {
-  if (size == surface_size_ && scale_factor == device_scale_factor_)
-    return;
-
-  surface_size_ = size;
-  device_scale_factor_ = scale_factor;
-  if (context_provider_.get()) {
-    context_provider_->ContextGL()->ResizeCHROMIUM(
-        size.width(), size.height(), scale_factor);
-  }
-  if (software_device_)
-    software_device_->Resize(size, scale_factor);
-}
-
-gfx::Size OutputSurface::SurfaceSize() const {
-  return surface_size_;
-}
-
-void OutputSurface::BindFramebuffer() {
-  DCHECK(context_provider_.get());
-  context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
-}
-
-void OutputSurface::PostSwapBuffersComplete() {
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&OutputSurface::OnSwapBuffersComplete,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-// We don't post tasks bound to the client directly since they might run
-// after the OutputSurface has been destroyed.
-void OutputSurface::OnSwapBuffersComplete() {
-  client_->DidSwapBuffersComplete();
-}
-
-}  // namespace cc
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
deleted file mode 100644
index 8994a6b..0000000
--- a/cc/output/output_surface.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_OUTPUT_SURFACE_H_
-#define CC_OUTPUT_OUTPUT_SURFACE_H_
-
-#include <deque>
-
-#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/output/context_provider.h"
-#include "cc/output/overlay_candidate_validator.h"
-#include "cc/output/software_output_device.h"
-
-namespace base { class SingleThreadTaskRunner; }
-
-namespace ui { struct LatencyInfo; }
-
-namespace gfx {
-class Rect;
-class Size;
-class Transform;
-}
-
-namespace cc {
-
-class CompositorFrame;
-class CompositorFrameAck;
-class OutputSurfaceClient;
-
-// Represents the output surface for a compositor. The compositor owns
-// and manages its destruction. Its lifetime is:
-//   1. Created on the main thread by the LayerTreeHost through its client.
-//   2. Passed to the compositor thread and bound to a client via BindToClient.
-//      From here on, it will only be used on the compositor thread.
-//   3. If the 3D context is lost, then the compositor will delete the output
-//      surface (on the compositor thread) and go back to step 1.
-class OutputSurface {
- public:
-  enum {
-    DEFAULT_MAX_FRAMES_PENDING = 2
-  };
-
-  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
-                const scoped_refptr<ContextProvider>& worker_context_provider,
-                scoped_ptr<SoftwareOutputDevice> software_device);
-  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
-                const scoped_refptr<ContextProvider>& worker_context_provider);
-  explicit OutputSurface(
-      const scoped_refptr<ContextProvider>& context_provider);
-
-  explicit OutputSurface(scoped_ptr<SoftwareOutputDevice> software_device);
-
-  OutputSurface(const scoped_refptr<ContextProvider>& context_provider,
-                scoped_ptr<SoftwareOutputDevice> software_device);
-
-  virtual ~OutputSurface();
-
-  struct Capabilities {
-    Capabilities()
-        : delegated_rendering(false),
-          max_frames_pending(0),
-          deferred_gl_initialization(false),
-          draw_and_swap_full_viewport_every_frame(false),
-          adjust_deadline_for_parent(true),
-          uses_default_gl_framebuffer(true),
-          flipped_output_surface(false),
-          can_force_reclaim_resources(false) {}
-    bool delegated_rendering;
-    int max_frames_pending;
-    bool deferred_gl_initialization;
-    bool draw_and_swap_full_viewport_every_frame;
-    // This doesn't handle the <webview> case, but once BeginFrame is
-    // supported natively, we shouldn't need adjust_deadline_for_parent.
-    bool adjust_deadline_for_parent;
-    // Whether this output surface renders to the default OpenGL zero
-    // framebuffer or to an offscreen framebuffer.
-    bool uses_default_gl_framebuffer;
-    // Whether this OutputSurface is flipped or not.
-    bool flipped_output_surface;
-    // Whether ForceReclaimResources can be called to reclaim all resources
-    // from the OutputSurface.
-    bool can_force_reclaim_resources;
-  };
-
-  const Capabilities& capabilities() const {
-    return capabilities_;
-  }
-
-  virtual bool HasExternalStencilTest() const;
-
-  // Obtain the 3d context or the software device associated with this output
-  // surface. Either of these may return a null pointer, but not both.
-  // In the event of a lost context, the entire output surface should be
-  // recreated.
-  ContextProvider* context_provider() const { return context_provider_.get(); }
-  ContextProvider* worker_context_provider() const {
-    return worker_context_provider_.get();
-  }
-  SoftwareOutputDevice* software_device() const {
-    return software_device_.get();
-  }
-
-  // Called by the compositor on the compositor thread. This is a place where
-  // thread-specific data for the output surface can be initialized, since from
-  // this point on the output surface will only be used on the compositor
-  // thread.
-  virtual bool BindToClient(OutputSurfaceClient* client);
-
-  // This is called by the compositor on the compositor thread inside ReleaseGL
-  // in order to release the ContextProvider. Only used with
-  // deferred_gl_initialization capability.
-  void ReleaseContextProvider();
-
-  virtual void EnsureBackbuffer();
-  virtual void DiscardBackbuffer();
-
-  virtual void Reshape(const gfx::Size& size, float scale_factor);
-  virtual gfx::Size SurfaceSize() const;
-
-  // If supported, this causes a ReclaimResources for all resources that are
-  // currently in use.
-  virtual void ForceReclaimResources() {}
-
-  virtual void BindFramebuffer();
-
-  // The implementation may destroy or steal the contents of the CompositorFrame
-  // passed in (though it will not take ownership of the CompositorFrame
-  // itself). For successful swaps, the implementation must call
-  // OutputSurfaceClient::DidSwapBuffers() and eventually
-  // DidSwapBuffersComplete().
-  virtual void SwapBuffers(CompositorFrame* frame) = 0;
-  virtual void OnSwapBuffersComplete();
-
-  // Notifies frame-rate smoothness preference. If true, all non-critical
-  // processing should be stopped, or lowered in priority.
-  virtual void UpdateSmoothnessTakesPriority(bool prefer_smoothness) {}
-
-  bool HasClient() { return !!client_; }
-
-  // Get the class capable of informing cc of hardware overlay capability.
-  OverlayCandidateValidator* overlay_candidate_validator() const {
-    return overlay_candidate_validator_.get();
-  }
-
-  void DidLoseOutputSurface();
-
- protected:
-  OutputSurfaceClient* client_;
-
-  // Synchronously initialize context3d and enter hardware mode.
-  // This can only supported in threaded compositing mode.
-  bool InitializeAndSetContext3d(
-      scoped_refptr<ContextProvider> context_provider,
-      scoped_refptr<ContextProvider> worker_context_provider);
-  void ReleaseGL();
-
-  void PostSwapBuffersComplete();
-
-  struct OutputSurface::Capabilities capabilities_;
-  scoped_refptr<ContextProvider> context_provider_;
-  scoped_refptr<ContextProvider> worker_context_provider_;
-  scoped_ptr<SoftwareOutputDevice> software_device_;
-  scoped_ptr<OverlayCandidateValidator> overlay_candidate_validator_;
-  gfx::Size surface_size_;
-  float device_scale_factor_;
-
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval);
-
-  void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
-  void ReclaimResources(const CompositorFrameAck* ack);
-  void SetExternalStencilTest(bool enabled);
-  void SetExternalDrawConstraints(
-      const gfx::Transform& transform,
-      const gfx::Rect& viewport,
-      const gfx::Rect& clip,
-      const gfx::Rect& viewport_rect_for_tile_priority,
-      const gfx::Transform& transform_for_tile_priority,
-      bool resourceless_software_draw);
-
- private:
-  void SetUpContext3d();
-  void ResetContext3d();
-
-  bool external_stencil_test_enabled_;
-
-  base::WeakPtrFactory<OutputSurface> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(OutputSurface);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OUTPUT_SURFACE_H_
diff --git a/cc/output/output_surface_client.h b/cc/output/output_surface_client.h
deleted file mode 100644
index 60d9a38..0000000
--- a/cc/output/output_surface_client.h
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_OUTPUT_SURFACE_CLIENT_H_
-#define CC_OUTPUT_OUTPUT_SURFACE_CLIENT_H_
-
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "cc/output/context_provider.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace gfx {
-class Transform;
-}
-
-namespace cc {
-
-class CompositorFrameAck;
-
-class OutputSurfaceClient {
- public:
-  // Called to synchronously re-initialize using the Context3D. Upon returning
-  // the compositor should be able to draw using GL what was previously
-  // committed.
-  virtual void DeferredInitialize() = 0;
-  // Must call OutputSurface::ReleaseContextProvider inside this call.
-  virtual void ReleaseGL() = 0;
-  virtual void CommitVSyncParameters(base::TimeTicks timebase,
-                                     base::TimeDelta interval) = 0;
-  virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0;
-  virtual void DidSwapBuffers() = 0;
-  virtual void DidSwapBuffersComplete() = 0;
-  virtual void ReclaimResources(const CompositorFrameAck* ack) = 0;
-  virtual void DidLoseOutputSurface() = 0;
-  virtual void SetExternalDrawConstraints(
-      const gfx::Transform& transform,
-      const gfx::Rect& viewport,
-      const gfx::Rect& clip,
-      const gfx::Rect& viewport_rect_for_tile_priority,
-      const gfx::Transform& transform_for_tile_priority,
-      bool resourceless_software_draw) = 0;
-  // If set, |callback| will be called subsequent to each new tree activation,
-  // regardless of the compositor visibility or damage. |callback| must remain
-  // valid for the lifetime of the OutputSurfaceClient or until unregisted --
-  // use SetTreeActivationCallback(base::Closure()) to unregister it.
-  virtual void SetTreeActivationCallback(const base::Closure& callback) = 0;
-
- protected:
-  virtual ~OutputSurfaceClient() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OUTPUT_SURFACE_CLIENT_H_
diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc
deleted file mode 100644
index f32a96f..0000000
--- a/cc/output/output_surface_unittest.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/output_surface.h"
-
-#include "base/test/test_simple_task_runner.h"
-#include "cc/output/managed_memory_policy.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/output/software_output_device.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-namespace {
-
-class TestOutputSurface : public OutputSurface {
- public:
-  explicit TestOutputSurface(scoped_refptr<ContextProvider> context_provider)
-      : OutputSurface(context_provider) {}
-
-  TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
-                    scoped_refptr<ContextProvider> worker_context_provider)
-      : OutputSurface(worker_context_provider) {}
-
-  explicit TestOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device)
-      : OutputSurface(software_device.Pass()) {}
-
-  TestOutputSurface(scoped_refptr<ContextProvider> context_provider,
-                    scoped_ptr<SoftwareOutputDevice> software_device)
-      : OutputSurface(context_provider, software_device.Pass()) {}
-
-  void SwapBuffers(CompositorFrame* frame) override {
-    client_->DidSwapBuffers();
-    client_->DidSwapBuffersComplete();
-  }
-
-  bool InitializeNewContext3d(scoped_refptr<ContextProvider> context_provider) {
-    return InitializeAndSetContext3d(context_provider, nullptr);
-  }
-
-  using OutputSurface::ReleaseGL;
-
-  void CommitVSyncParametersForTesting(base::TimeTicks timebase,
-                                       base::TimeDelta interval) {
-    CommitVSyncParameters(timebase, interval);
-  }
-
-  void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); }
-
-  void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); }
-
- protected:
-};
-
-class TestSoftwareOutputDevice : public SoftwareOutputDevice {
- public:
-  TestSoftwareOutputDevice();
-  ~TestSoftwareOutputDevice() override;
-
-  // Overriden from cc:SoftwareOutputDevice
-  void DiscardBackbuffer() override;
-  void EnsureBackbuffer() override;
-
-  int discard_backbuffer_count() { return discard_backbuffer_count_; }
-  int ensure_backbuffer_count() { return ensure_backbuffer_count_; }
-
- private:
-  int discard_backbuffer_count_;
-  int ensure_backbuffer_count_;
-};
-
-TestSoftwareOutputDevice::TestSoftwareOutputDevice()
-    : discard_backbuffer_count_(0), ensure_backbuffer_count_(0) {}
-
-TestSoftwareOutputDevice::~TestSoftwareOutputDevice() {}
-
-void TestSoftwareOutputDevice::DiscardBackbuffer() {
-  SoftwareOutputDevice::DiscardBackbuffer();
-  discard_backbuffer_count_++;
-}
-
-void TestSoftwareOutputDevice::EnsureBackbuffer() {
-  SoftwareOutputDevice::EnsureBackbuffer();
-  ensure_backbuffer_count_++;
-}
-
-TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientSuccess) {
-  scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-  TestOutputSurface output_surface(provider);
-  EXPECT_FALSE(output_surface.HasClient());
-
-  FakeOutputSurfaceClient client;
-  EXPECT_TRUE(output_surface.BindToClient(&client));
-  EXPECT_TRUE(output_surface.HasClient());
-  EXPECT_FALSE(client.deferred_initialize_called());
-
-  // Verify DidLoseOutputSurface callback is hooked up correctly.
-  EXPECT_FALSE(client.did_lose_output_surface_called());
-  output_surface.context_provider()->ContextGL()->LoseContextCHROMIUM(
-      GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
-  output_surface.context_provider()->ContextGL()->Flush();
-  EXPECT_TRUE(client.did_lose_output_surface_called());
-}
-
-TEST(OutputSurfaceTest, ClientPointerIndicatesWorkerBindToClientSuccess) {
-  scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-  scoped_refptr<TestContextProvider> worker_provider =
-      TestContextProvider::Create();
-  TestOutputSurface output_surface(provider, worker_provider);
-  EXPECT_FALSE(output_surface.HasClient());
-
-  FakeOutputSurfaceClient client;
-  EXPECT_TRUE(output_surface.BindToClient(&client));
-  EXPECT_TRUE(output_surface.HasClient());
-  EXPECT_FALSE(client.deferred_initialize_called());
-
-  // Verify DidLoseOutputSurface callback is hooked up correctly.
-  EXPECT_FALSE(client.did_lose_output_surface_called());
-  output_surface.context_provider()->ContextGL()->LoseContextCHROMIUM(
-      GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
-  output_surface.context_provider()->ContextGL()->Flush();
-  EXPECT_TRUE(client.did_lose_output_surface_called());
-}
-
-TEST(OutputSurfaceTest, ClientPointerIndicatesBindToClientFailure) {
-  scoped_refptr<TestContextProvider> context_provider =
-      TestContextProvider::Create();
-
-  // Lose the context so BindToClient fails.
-  context_provider->UnboundTestContext3d()->set_context_lost(true);
-
-  TestOutputSurface output_surface(context_provider);
-  EXPECT_FALSE(output_surface.HasClient());
-
-  FakeOutputSurfaceClient client;
-  EXPECT_FALSE(output_surface.BindToClient(&client));
-  EXPECT_FALSE(output_surface.HasClient());
-}
-
-TEST(OutputSurfaceTest, ClientPointerIndicatesWorkerBindToClientFailure) {
-  scoped_refptr<TestContextProvider> context_provider =
-      TestContextProvider::Create();
-  scoped_refptr<TestContextProvider> worker_context_provider =
-      TestContextProvider::Create();
-
-  // Lose the context so BindToClient fails.
-  worker_context_provider->UnboundTestContext3d()->set_context_lost(true);
-
-  TestOutputSurface output_surface(context_provider, worker_context_provider);
-  EXPECT_FALSE(output_surface.HasClient());
-
-  FakeOutputSurfaceClient client;
-  EXPECT_FALSE(output_surface.BindToClient(&client));
-  EXPECT_FALSE(output_surface.HasClient());
-}
-
-class OutputSurfaceTestInitializeNewContext3d : public ::testing::Test {
- public:
-  OutputSurfaceTestInitializeNewContext3d()
-      : context_provider_(TestContextProvider::Create()),
-        output_surface_(
-            scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice)),
-        client_(&output_surface_) {}
-
- protected:
-  void BindOutputSurface() {
-    EXPECT_TRUE(output_surface_.BindToClient(&client_));
-    EXPECT_TRUE(output_surface_.HasClient());
-  }
-
-  void InitializeNewContextExpectFail() {
-    EXPECT_FALSE(output_surface_.InitializeNewContext3d(context_provider_));
-    EXPECT_TRUE(output_surface_.HasClient());
-
-    EXPECT_FALSE(output_surface_.context_provider());
-    EXPECT_TRUE(output_surface_.software_device());
-  }
-
-  scoped_refptr<TestContextProvider> context_provider_;
-  TestOutputSurface output_surface_;
-  FakeOutputSurfaceClient client_;
-};
-
-TEST_F(OutputSurfaceTestInitializeNewContext3d, Success) {
-  BindOutputSurface();
-  EXPECT_FALSE(client_.deferred_initialize_called());
-
-  EXPECT_TRUE(output_surface_.InitializeNewContext3d(context_provider_));
-  EXPECT_TRUE(client_.deferred_initialize_called());
-  EXPECT_EQ(context_provider_.get(), output_surface_.context_provider());
-
-  EXPECT_FALSE(client_.did_lose_output_surface_called());
-  context_provider_->ContextGL()->LoseContextCHROMIUM(
-      GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
-  context_provider_->ContextGL()->Flush();
-  EXPECT_TRUE(client_.did_lose_output_surface_called());
-
-  output_surface_.ReleaseGL();
-  EXPECT_FALSE(output_surface_.context_provider());
-}
-
-TEST_F(OutputSurfaceTestInitializeNewContext3d, Context3dMakeCurrentFails) {
-  BindOutputSurface();
-
-  context_provider_->UnboundTestContext3d()->set_context_lost(true);
-  InitializeNewContextExpectFail();
-}
-
-TEST(OutputSurfaceTest, MemoryAllocation) {
-  scoped_refptr<TestContextProvider> context_provider =
-      TestContextProvider::Create();
-
-  TestOutputSurface output_surface(context_provider);
-
-  FakeOutputSurfaceClient client;
-  EXPECT_TRUE(output_surface.BindToClient(&client));
-
-  ManagedMemoryPolicy policy(0);
-  policy.bytes_limit_when_visible = 1234;
-  policy.priority_cutoff_when_visible =
-      gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY;
-
-  context_provider->SetMemoryAllocation(policy);
-  EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible);
-  EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY,
-            client.memory_policy().priority_cutoff_when_visible);
-
-  policy.priority_cutoff_when_visible =
-      gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING;
-  context_provider->SetMemoryAllocation(policy);
-  EXPECT_EQ(gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING,
-            client.memory_policy().priority_cutoff_when_visible);
-
-  // 0 bytes limit should be ignored.
-  policy.bytes_limit_when_visible = 0;
-  context_provider->SetMemoryAllocation(policy);
-  EXPECT_EQ(1234u, client.memory_policy().bytes_limit_when_visible);
-}
-
-TEST(OutputSurfaceTest, SoftwareOutputDeviceBackbufferManagement) {
-  TestSoftwareOutputDevice* software_output_device =
-      new TestSoftwareOutputDevice();
-
-  // TestOutputSurface now owns software_output_device and has responsibility to
-  // free it.
-  TestOutputSurface output_surface(make_scoped_ptr(software_output_device));
-
-  EXPECT_EQ(0, software_output_device->ensure_backbuffer_count());
-  EXPECT_EQ(0, software_output_device->discard_backbuffer_count());
-
-  output_surface.EnsureBackbuffer();
-  EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
-  EXPECT_EQ(0, software_output_device->discard_backbuffer_count());
-  output_surface.DiscardBackbuffer();
-
-  EXPECT_EQ(1, software_output_device->ensure_backbuffer_count());
-  EXPECT_EQ(1, software_output_device->discard_backbuffer_count());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/overlay_candidate.cc b/cc/output/overlay_candidate.cc
deleted file mode 100644
index 46c3a7d..0000000
--- a/cc/output/overlay_candidate.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/overlay_candidate.h"
-
-#include <algorithm>
-#include "base/logging.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-namespace cc {
-
-OverlayCandidate::OverlayCandidate()
-    : transform(gfx::OVERLAY_TRANSFORM_NONE),
-      format(RGBA_8888),
-      uv_rect(0.f, 0.f, 1.f, 1.f),
-      resource_id(0),
-      plane_z_order(0),
-      overlay_handled(false) {}
-
-OverlayCandidate::~OverlayCandidate() {}
-
-// static
-gfx::OverlayTransform OverlayCandidate::GetOverlayTransform(
-    const gfx::Transform& quad_transform,
-    bool flipped) {
-  if (!quad_transform.IsPositiveScaleOrTranslation())
-    return gfx::OVERLAY_TRANSFORM_INVALID;
-
-  return flipped ? gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL
-                 : gfx::OVERLAY_TRANSFORM_NONE;
-}
-
-// static
-gfx::OverlayTransform OverlayCandidate::ModifyTransform(
-    gfx::OverlayTransform in,
-    gfx::OverlayTransform delta) {
-  // There are 8 different possible transforms. We can characterize these
-  // by looking at where the origin moves and the direction the horizontal goes.
-  // (TL=top-left, BR=bottom-right, H=horizontal, V=vertical).
-  // NONE: TL, H
-  // FLIP_VERTICAL: BL, H
-  // FLIP_HORIZONTAL: TR, H
-  // ROTATE_90: TR, V
-  // ROTATE_180: BR, H
-  // ROTATE_270: BL, V
-  // Missing transforms: TL, V & BR, V
-  // Basic combinations:
-  // Flip X & Y -> Rotate 180 (TL,H -> TR,H -> BR,H or TL,H -> BL,H -> BR,H)
-  // Flip X or Y + Rotate 180 -> other flip (eg, TL,H -> TR,H -> BL,H)
-  // Rotate + Rotate simply adds values.
-  // Rotate 90/270 + flip is invalid because we can only have verticals with
-  // the origin in TR or BL.
-  if (delta == gfx::OVERLAY_TRANSFORM_NONE)
-    return in;
-  switch (in) {
-    case gfx::OVERLAY_TRANSFORM_NONE:
-      return delta;
-    case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
-      switch (delta) {
-        case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
-          return gfx::OVERLAY_TRANSFORM_NONE;
-        case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_180;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-          return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
-        default:
-          return gfx::OVERLAY_TRANSFORM_INVALID;
-      }
-      break;
-    case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
-      switch (delta) {
-        case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
-          return gfx::OVERLAY_TRANSFORM_NONE;
-        case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_180;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_90:
-        case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-          return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_270:
-        default:
-          return gfx::OVERLAY_TRANSFORM_INVALID;
-      }
-      break;
-    case gfx::OVERLAY_TRANSFORM_ROTATE_90:
-      switch (delta) {
-        case gfx::OVERLAY_TRANSFORM_ROTATE_90:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_180;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_270;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_270:
-          return gfx::OVERLAY_TRANSFORM_NONE;
-        default:
-          return gfx::OVERLAY_TRANSFORM_INVALID;
-      }
-      break;
-    case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-      switch (delta) {
-        case gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL:
-          return gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL;
-        case gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL:
-          return gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_90:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_270;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-          return gfx::OVERLAY_TRANSFORM_NONE;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_270:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_90;
-        default:
-          return gfx::OVERLAY_TRANSFORM_INVALID;
-      }
-      break;
-    case gfx::OVERLAY_TRANSFORM_ROTATE_270:
-      switch (delta) {
-        case gfx::OVERLAY_TRANSFORM_ROTATE_90:
-          return gfx::OVERLAY_TRANSFORM_NONE;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_180:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_90;
-        case gfx::OVERLAY_TRANSFORM_ROTATE_270:
-          return gfx::OVERLAY_TRANSFORM_ROTATE_180;
-        default:
-          return gfx::OVERLAY_TRANSFORM_INVALID;
-      }
-      break;
-    default:
-      return gfx::OVERLAY_TRANSFORM_INVALID;
-  }
-}
-
-// static
-gfx::Rect OverlayCandidate::GetOverlayRect(const gfx::Transform& quad_transform,
-                                           const gfx::Rect& rect) {
-  DCHECK(quad_transform.IsPositiveScaleOrTranslation());
-
-  gfx::RectF float_rect(rect);
-  quad_transform.TransformRect(&float_rect);
-  return gfx::ToNearestRect(float_rect);
-}
-
-}  // namespace cc
diff --git a/cc/output/overlay_candidate.h b/cc/output/overlay_candidate.h
deleted file mode 100644
index 30cfea1..0000000
--- a/cc/output/overlay_candidate.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_OVERLAY_CANDIDATE_H_
-#define CC_OUTPUT_OVERLAY_CANDIDATE_H_
-
-#include <vector>
-
-#include "cc/resources/resource_format.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/overlay_transform.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-class OverlayCandidate {
- public:
-  static gfx::OverlayTransform GetOverlayTransform(
-      const gfx::Transform& quad_transform,
-      bool flipped);
-  // Apply transform |delta| to |in| and return the resulting transform,
-  // or OVERLAY_TRANSFORM_INVALID.
-  static gfx::OverlayTransform ModifyTransform(gfx::OverlayTransform in,
-                                               gfx::OverlayTransform delta);
-  static gfx::Rect GetOverlayRect(const gfx::Transform& quad_transform,
-                                  const gfx::Rect& rect);
-
-  OverlayCandidate();
-  ~OverlayCandidate();
-
-  // Transformation to apply to layer during composition.
-  gfx::OverlayTransform transform;
-  // Format of the buffer to composite.
-  ResourceFormat format;
-  // Rect on the display to position the overlay to.
-  gfx::Rect display_rect;
-  // Crop within the buffer to be placed inside |display_rect|.
-  gfx::RectF uv_rect;
-  // Texture resource to present in an overlay.
-  unsigned resource_id;
-  // Stacking order of the overlay plane relative to the main surface,
-  // which is 0. Signed to allow for "underlays".
-  int plane_z_order;
-
-  // To be modified by the implementer if this candidate can go into
-  // an overlay.
-  bool overlay_handled;
-};
-
-typedef std::vector<OverlayCandidate> OverlayCandidateList;
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OVERLAY_CANDIDATE_H_
diff --git a/cc/output/overlay_candidate_validator.h b/cc/output/overlay_candidate_validator.h
deleted file mode 100644
index d94f3c0..0000000
--- a/cc/output/overlay_candidate_validator.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_
-#define CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_
-
-#include <vector>
-
-#include "cc/output/overlay_candidate.h"
-
-namespace cc {
-
-// This class that can be used to answer questions about possible overlay
-// configurations for a particular output device.
-class OverlayCandidateValidator {
- public:
-  // A list of possible overlay candidates is presented to this function.
-  // The expected result is that those candidates that can be in a separate
-  // plane are marked with |overlay_handled| set to true, otherwise they are
-  // to be traditionally composited.
-  virtual void CheckOverlaySupport(OverlayCandidateList* surfaces) = 0;
-
-  virtual ~OverlayCandidateValidator() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OVERLAY_CANDIDATE_VALIDATOR_H_
diff --git a/cc/output/overlay_processor.cc b/cc/output/overlay_processor.cc
deleted file mode 100644
index 61c4ebb..0000000
--- a/cc/output/overlay_processor.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/overlay_processor.h"
-
-#include "cc/output/output_surface.h"
-#include "cc/output/overlay_strategy_single_on_top.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-OverlayProcessor::OverlayProcessor(OutputSurface* surface,
-                                   ResourceProvider* resource_provider)
-    : surface_(surface), resource_provider_(resource_provider) {}
-
-void OverlayProcessor::Initialize() {
-  DCHECK(surface_);
-  if (!resource_provider_)
-    return;
-
-  OverlayCandidateValidator* candidates =
-      surface_->overlay_candidate_validator();
-  if (candidates) {
-    strategies_.push_back(scoped_ptr<Strategy>(
-        new OverlayStrategySingleOnTop(candidates, resource_provider_)));
-  }
-}
-
-OverlayProcessor::~OverlayProcessor() {}
-
-void OverlayProcessor::ProcessForOverlays(
-    RenderPassList* render_passes_in_draw_order,
-    OverlayCandidateList* candidate_list) {
-  for (StrategyList::iterator it = strategies_.begin(); it != strategies_.end();
-       ++it) {
-    if ((*it)->Attempt(render_passes_in_draw_order, candidate_list))
-      return;
-  }
-}
-
-}  // namespace cc
diff --git a/cc/output/overlay_processor.h b/cc/output/overlay_processor.h
deleted file mode 100644
index 6c13b1b..0000000
--- a/cc/output/overlay_processor.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_OVERLAY_PROCESSOR_H_
-#define CC_OUTPUT_OVERLAY_PROCESSOR_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/overlay_candidate.h"
-#include "cc/quads/render_pass.h"
-
-namespace cc {
-class OutputSurface;
-class ResourceProvider;
-
-class OverlayProcessor {
- public:
-  class Strategy {
-   public:
-    virtual ~Strategy() {}
-    // Returns false if the strategy cannot be made to work with the
-    // current set of render passes. Returns true if the strategy was successful
-    // and adds any additional passes necessary to represent overlays to
-    // |render_passes_in_draw_order|.
-    virtual bool Attempt(RenderPassList* render_passes_in_draw_order,
-                         OverlayCandidateList* candidates) = 0;
-  };
-  typedef ScopedPtrVector<Strategy> StrategyList;
-
-  OverlayProcessor(OutputSurface* surface, ResourceProvider* resource_provider);
-  virtual ~OverlayProcessor();
-  // Virtual to allow testing different strategies.
-  virtual void Initialize();
-
-  void ProcessForOverlays(RenderPassList* render_passes_in_draw_order,
-                          OverlayCandidateList* candidate_list);
-
- protected:
-  StrategyList strategies_;
-  OutputSurface* surface_;
-  ResourceProvider* resource_provider_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(OverlayProcessor);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OVERLAY_PROCESSOR_H_
diff --git a/cc/output/overlay_strategy_single_on_top.cc b/cc/output/overlay_strategy_single_on_top.cc
deleted file mode 100644
index 71897ed..0000000
--- a/cc/output/overlay_strategy_single_on_top.cc
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/overlay_strategy_single_on_top.h"
-
-#include <limits>
-
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "ui/gfx/geometry/point3_f.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-OverlayStrategySingleOnTop::OverlayStrategySingleOnTop(
-    OverlayCandidateValidator* capability_checker,
-    ResourceProvider* resource_provider)
-    : capability_checker_(capability_checker),
-      resource_provider_(resource_provider) {}
-
-bool OverlayStrategySingleOnTop::IsOverlayQuad(const DrawQuad* draw_quad) {
-  unsigned int resource_id;
-  switch (draw_quad->material) {
-    case DrawQuad::TEXTURE_CONTENT:
-      resource_id = TextureDrawQuad::MaterialCast(draw_quad)->resource_id;
-      break;
-    case DrawQuad::STREAM_VIDEO_CONTENT:
-      resource_id = StreamVideoDrawQuad::MaterialCast(draw_quad)->resource_id;
-      break;
-    default:
-      return false;
-  }
-  return resource_provider_->AllowOverlay(resource_id);
-}
-
-bool OverlayStrategySingleOnTop::GetTextureQuadInfo(
-    const TextureDrawQuad& quad,
-    OverlayCandidate* quad_info) {
-  gfx::OverlayTransform overlay_transform =
-      OverlayCandidate::GetOverlayTransform(quad.quadTransform(), quad.flipped);
-  if (quad.background_color != SK_ColorTRANSPARENT ||
-      quad.premultiplied_alpha ||
-      overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
-    return false;
-  quad_info->resource_id = quad.resource_id;
-  quad_info->transform = overlay_transform;
-  quad_info->uv_rect = BoundingRect(quad.uv_top_left, quad.uv_bottom_right);
-  return true;
-}
-
-bool OverlayStrategySingleOnTop::GetVideoQuadInfo(
-    const StreamVideoDrawQuad& quad,
-    OverlayCandidate* quad_info) {
-  gfx::OverlayTransform overlay_transform =
-      OverlayCandidate::GetOverlayTransform(quad.quadTransform(), false);
-  if (overlay_transform == gfx::OVERLAY_TRANSFORM_INVALID)
-    return false;
-  if (!quad.matrix.IsScaleOrTranslation()) {
-    // We cannot handle anything other than scaling & translation for texture
-    // coordinates yet.
-    return false;
-  }
-  quad_info->resource_id = quad.resource_id;
-  quad_info->transform = overlay_transform;
-
-  gfx::Point3F uv0 = gfx::Point3F(0, 0, 0);
-  gfx::Point3F uv1 = gfx::Point3F(1, 1, 0);
-  quad.matrix.TransformPoint(&uv0);
-  quad.matrix.TransformPoint(&uv1);
-  gfx::Vector3dF delta = uv1 - uv0;
-  if (delta.x() < 0) {
-    quad_info->transform = OverlayCandidate::ModifyTransform(
-        quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_HORIZONTAL);
-    float x0 = uv0.x();
-    uv0.set_x(uv1.x());
-    uv1.set_x(x0);
-    delta.set_x(-delta.x());
-  }
-
-  if (delta.y() < 0) {
-    // In this situation, uv0y < uv1y. Since we overlay inverted, a request
-    // to invert the source texture means we can just output the texture
-    // normally and it will be correct.
-    quad_info->uv_rect = gfx::RectF(uv0.x(), uv1.y(), delta.x(), -delta.y());
-  } else {
-    quad_info->transform = OverlayCandidate::ModifyTransform(
-        quad_info->transform, gfx::OVERLAY_TRANSFORM_FLIP_VERTICAL);
-    quad_info->uv_rect = gfx::RectF(uv0.x(), uv0.y(), delta.x(), delta.y());
-  }
-  return true;
-}
-
-bool OverlayStrategySingleOnTop::GetCandidateQuadInfo(
-    const DrawQuad& draw_quad,
-    OverlayCandidate* quad_info) {
-  // All quad checks.
-  if (draw_quad.needs_blending || draw_quad.shared_quad_state->opacity != 1.f ||
-      draw_quad.shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode)
-    return false;
-
-  if (draw_quad.material == DrawQuad::TEXTURE_CONTENT) {
-    const TextureDrawQuad& quad = *TextureDrawQuad::MaterialCast(&draw_quad);
-    if (!GetTextureQuadInfo(quad, quad_info))
-      return false;
-  } else if (draw_quad.material == DrawQuad::STREAM_VIDEO_CONTENT) {
-    const StreamVideoDrawQuad& quad =
-        *StreamVideoDrawQuad::MaterialCast(&draw_quad);
-    if (!GetVideoQuadInfo(quad, quad_info))
-      return false;
-  }
-
-  quad_info->format = RGBA_8888;
-  quad_info->display_rect = OverlayCandidate::GetOverlayRect(
-      draw_quad.quadTransform(), draw_quad.rect);
-  return true;
-}
-
-bool OverlayStrategySingleOnTop::IsInvisibleQuad(const DrawQuad* draw_quad) {
-  if (draw_quad->material == DrawQuad::SOLID_COLOR) {
-    const SolidColorDrawQuad* solid_quad =
-        SolidColorDrawQuad::MaterialCast(draw_quad);
-    SkColor color = solid_quad->color;
-    float opacity = solid_quad->opacity();
-    float alpha = (SkColorGetA(color) * (1.0f / 255.0f)) * opacity;
-    // Ignore transparent solid color quads.
-    return solid_quad->ShouldDrawWithBlending() &&
-           alpha < std::numeric_limits<float>::epsilon();
-  }
-  return false;
-}
-
-bool OverlayStrategySingleOnTop::Attempt(
-    RenderPassList* render_passes_in_draw_order,
-    OverlayCandidateList* candidate_list) {
-  // Only attempt to handle very simple case for now.
-  if (!capability_checker_)
-    return false;
-
-  RenderPass* root_render_pass = render_passes_in_draw_order->back();
-  DCHECK(root_render_pass);
-
-  OverlayCandidate candidate;
-  QuadList& quad_list = root_render_pass->quad_list;
-  auto candidate_iterator = quad_list.end();
-  for (auto it = quad_list.begin(); it != quad_list.end(); ++it) {
-    const DrawQuad* draw_quad = *it;
-    if (IsOverlayQuad(draw_quad)) {
-      // Check that no prior quads overlap it.
-      bool intersects = false;
-      gfx::RectF rect = draw_quad->rect;
-      draw_quad->quadTransform().TransformRect(&rect);
-      for (auto overlap_iter = quad_list.cbegin(); overlap_iter != it;
-           ++overlap_iter) {
-        gfx::RectF overlap_rect = overlap_iter->rect;
-        overlap_iter->quadTransform().TransformRect(&overlap_rect);
-        if (rect.Intersects(overlap_rect) && !IsInvisibleQuad(*overlap_iter)) {
-          intersects = true;
-          break;
-        }
-      }
-      if (intersects || !GetCandidateQuadInfo(*draw_quad, &candidate))
-        continue;
-      candidate_iterator = it;
-      break;
-    }
-  }
-  if (candidate_iterator == quad_list.end())
-    return false;
-
-  // Add our primary surface.
-  OverlayCandidateList candidates;
-  OverlayCandidate main_image;
-  main_image.display_rect = root_render_pass->output_rect;
-  candidates.push_back(main_image);
-
-  // Add the overlay.
-  candidate.plane_z_order = 1;
-  candidates.push_back(candidate);
-
-  // Check for support.
-  capability_checker_->CheckOverlaySupport(&candidates);
-
-  // If the candidate can be handled by an overlay, create a pass for it.
-  if (candidates[1].overlay_handled) {
-    quad_list.EraseAndInvalidateAllPointers(candidate_iterator);
-    candidate_list->swap(candidates);
-    return true;
-  }
-  return false;
-}
-
-}  // namespace cc
diff --git a/cc/output/overlay_strategy_single_on_top.h b/cc/output/overlay_strategy_single_on_top.h
deleted file mode 100644
index 2b261af..0000000
--- a/cc/output/overlay_strategy_single_on_top.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_
-#define CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/overlay_candidate.h"
-#include "cc/output/overlay_processor.h"
-#include "cc/quads/render_pass.h"
-
-namespace cc {
-class OverlayCandidateValidator;
-class StreamVideoDrawQuad;
-class TextureDrawQuad;
-
-class OverlayStrategySingleOnTop : public OverlayProcessor::Strategy {
- public:
-  OverlayStrategySingleOnTop(OverlayCandidateValidator* capability_checker,
-                             ResourceProvider* resource_provider);
-  bool Attempt(RenderPassList* render_passes_in_draw_order,
-               OverlayCandidateList* candidate_list) override;
-
- private:
-  bool IsOverlayQuad(const DrawQuad* draw_quad);
-  bool GetCandidateQuadInfo(const DrawQuad& draw_quad,
-                            OverlayCandidate* quad_info);
-
-  // Returns true if |draw_quad| will not block quads underneath from becoming
-  // an overlay.
-  bool IsInvisibleQuad(const DrawQuad* draw_quad);
-
-  bool GetTextureQuadInfo(const TextureDrawQuad& quad,
-                          OverlayCandidate* quad_info);
-  bool GetVideoQuadInfo(const StreamVideoDrawQuad& quad,
-                        OverlayCandidate* quad_info);
-
-  OverlayCandidateValidator* capability_checker_;
-  ResourceProvider* resource_provider_;
-  DISALLOW_COPY_AND_ASSIGN(OverlayStrategySingleOnTop);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_OVERLAY_STRATEGY_SINGLE_ON_TOP_H_
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
deleted file mode 100644
index 75fbb6e..0000000
--- a/cc/output/overlay_unittest.cc
+++ /dev/null
@@ -1,1058 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/output/overlay_candidate_validator.h"
-#include "cc/output/overlay_processor.h"
-#include "cc/output/overlay_strategy_single_on_top.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/resources/texture_mailbox.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::_;
-using testing::Mock;
-
-namespace cc {
-namespace {
-
-const gfx::Rect kOverlayRect(0, 0, 128, 128);
-const gfx::Rect kOverlayTopLeftRect(0, 0, 64, 64);
-const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64);
-const gfx::PointF kUVTopLeft(0.1f, 0.2f);
-const gfx::PointF kUVBottomRight(1.0f, 1.0f);
-const gfx::Transform kNormalTransform =
-    gfx::Transform(0.9f, 0, 0, 0.8f, 0.1f, 0.2f);  // x,y -> x,y.
-const gfx::Transform kXMirrorTransform =
-    gfx::Transform(-0.9f, 0, 0, 0.8f, 1.0f, 0.2f);  // x,y -> 1-x,y.
-const gfx::Transform kYMirrorTransform =
-    gfx::Transform(0.9f, 0, 0, -0.8f, 0.1f, 1.0f);  // x,y -> x,1-y.
-const gfx::Transform kBothMirrorTransform =
-    gfx::Transform(-0.9f, 0, 0, -0.8f, 1.0f, 1.0f);  // x,y -> 1-x,1-y.
-const gfx::Transform kSwapTransform =
-    gfx::Transform(0, 1, 1, 0, 0, 0);  // x,y -> y,x.
-
-void MailboxReleased(unsigned sync_point,
-                     bool lost_resource,
-                     BlockingTaskRunner* main_thread_task_runner) {
-}
-
-class SingleOverlayValidator : public OverlayCandidateValidator {
- public:
-  void CheckOverlaySupport(OverlayCandidateList* surfaces) override;
-};
-
-void SingleOverlayValidator::CheckOverlaySupport(
-    OverlayCandidateList* surfaces) {
-  ASSERT_EQ(2U, surfaces->size());
-
-  OverlayCandidate& candidate = surfaces->back();
-  if (candidate.display_rect.width() == 64)
-    EXPECT_EQ(kOverlayBottomRightRect, candidate.display_rect);
-  else
-    EXPECT_EQ(kOverlayRect, candidate.display_rect);
-  EXPECT_EQ(BoundingRect(kUVTopLeft, kUVBottomRight).ToString(),
-            candidate.uv_rect.ToString());
-  candidate.overlay_handled = true;
-}
-
-class SingleOverlayProcessor : public OverlayProcessor {
- public:
-  SingleOverlayProcessor(OutputSurface* surface,
-                         ResourceProvider* resource_provider);
-  // Virtual to allow testing different strategies.
-  void Initialize() override;
-};
-
-SingleOverlayProcessor::SingleOverlayProcessor(
-    OutputSurface* surface,
-    ResourceProvider* resource_provider)
-    : OverlayProcessor(surface, resource_provider) {
-  EXPECT_EQ(surface, surface_);
-  EXPECT_EQ(resource_provider, resource_provider_);
-}
-
-void SingleOverlayProcessor::Initialize() {
-  OverlayCandidateValidator* candidates =
-      surface_->overlay_candidate_validator();
-  ASSERT_TRUE(candidates != NULL);
-  strategies_.push_back(scoped_ptr<Strategy>(
-      new OverlayStrategySingleOnTop(candidates, resource_provider_)));
-}
-
-class DefaultOverlayProcessor : public OverlayProcessor {
- public:
-  DefaultOverlayProcessor(OutputSurface* surface,
-                          ResourceProvider* resource_provider);
-  size_t GetStrategyCount();
-};
-
-DefaultOverlayProcessor::DefaultOverlayProcessor(
-    OutputSurface* surface,
-    ResourceProvider* resource_provider)
-    : OverlayProcessor(surface, resource_provider) {}
-
-size_t DefaultOverlayProcessor::GetStrategyCount() {
-  return strategies_.size();
-}
-
-class OverlayOutputSurface : public OutputSurface {
- public:
-  explicit OverlayOutputSurface(scoped_refptr<ContextProvider> context_provider)
-      : OutputSurface(context_provider) {}
-
-  // OutputSurface implementation
-  void SwapBuffers(CompositorFrame* frame) override;
-
-  void InitWithSingleOverlayValidator() {
-    overlay_candidate_validator_.reset(new SingleOverlayValidator);
-  }
-};
-
-void OverlayOutputSurface::SwapBuffers(CompositorFrame* frame) {
-  client_->DidSwapBuffers();
-  client_->DidSwapBuffersComplete();
-}
-
-scoped_ptr<RenderPass> CreateRenderPass() {
-  RenderPassId id(1, 0);
-  gfx::Rect output_rect(0, 0, 256, 256);
-  bool has_transparent_background = true;
-
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  pass->SetAll(id,
-               output_rect,
-               output_rect,
-               gfx::Transform(),
-               has_transparent_background);
-
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->opacity = 1.f;
-  return pass.Pass();
-}
-
-ResourceProvider::ResourceId CreateResource(
-    ResourceProvider* resource_provider) {
-  unsigned sync_point = 0;
-  TextureMailbox mailbox =
-      TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
-  mailbox.set_allow_overlay(true);
-  scoped_ptr<SingleReleaseCallbackImpl> release_callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased));
-
-  return resource_provider->CreateResourceFromTextureMailbox(
-      mailbox, release_callback.Pass());
-}
-
-SolidColorDrawQuad* CreateSolidColorQuadAt(
-    const SharedQuadState* shared_quad_state,
-    SkColor color,
-    RenderPass* render_pass,
-    const gfx::Rect& rect) {
-  SolidColorDrawQuad* quad =
-      render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  quad->SetNew(shared_quad_state, rect, rect, color, false);
-  return quad;
-}
-
-TextureDrawQuad* CreateCandidateQuadAt(ResourceProvider* resource_provider,
-                                       const SharedQuadState* shared_quad_state,
-                                       RenderPass* render_pass,
-                                       const gfx::Rect& rect) {
-  ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
-  bool premultiplied_alpha = false;
-  bool flipped = false;
-  bool nearest_neighbor = false;
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
-  TextureDrawQuad* overlay_quad =
-      render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  overlay_quad->SetNew(shared_quad_state,
-                       rect,
-                       rect,
-                       rect,
-                       resource_id,
-                       premultiplied_alpha,
-                       kUVTopLeft,
-                       kUVBottomRight,
-                       SK_ColorTRANSPARENT,
-                       vertex_opacity,
-                       flipped,
-                       nearest_neighbor);
-
-  return overlay_quad;
-}
-
-StreamVideoDrawQuad* CreateCandidateVideoQuadAt(
-    ResourceProvider* resource_provider,
-    const SharedQuadState* shared_quad_state,
-    RenderPass* render_pass,
-    const gfx::Rect& rect,
-    const gfx::Transform& transform) {
-  ResourceProvider::ResourceId resource_id = CreateResource(resource_provider);
-
-  StreamVideoDrawQuad* overlay_quad =
-      render_pass->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
-  overlay_quad->SetNew(shared_quad_state, rect, rect, rect, resource_id,
-                       transform);
-
-  return overlay_quad;
-}
-
-TextureDrawQuad* CreateFullscreenCandidateQuad(
-    ResourceProvider* resource_provider,
-    const SharedQuadState* shared_quad_state,
-    RenderPass* render_pass) {
-  return CreateCandidateQuadAt(
-      resource_provider, shared_quad_state, render_pass, kOverlayRect);
-}
-
-StreamVideoDrawQuad* CreateFullscreenCandidateVideoQuad(
-    ResourceProvider* resource_provider,
-    const SharedQuadState* shared_quad_state,
-    RenderPass* render_pass,
-    const gfx::Transform& transform) {
-  return CreateCandidateVideoQuadAt(resource_provider, shared_quad_state,
-                                    render_pass, kOverlayRect, transform);
-}
-
-void CreateCheckeredQuadAt(ResourceProvider* resource_provider,
-                           const SharedQuadState* shared_quad_state,
-                           RenderPass* render_pass,
-                           const gfx::Rect& rect) {
-  CheckerboardDrawQuad* checkerboard_quad =
-      render_pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad->SetNew(shared_quad_state, rect, rect, SkColor(), 1.f);
-}
-
-void CreateFullscreenCheckeredQuad(ResourceProvider* resource_provider,
-                                   const SharedQuadState* shared_quad_state,
-                                   RenderPass* render_pass) {
-  CreateCheckeredQuadAt(
-      resource_provider, shared_quad_state, render_pass, kOverlayRect);
-}
-
-static void CompareRenderPassLists(const RenderPassList& expected_list,
-                                   const RenderPassList& actual_list) {
-  EXPECT_EQ(expected_list.size(), actual_list.size());
-  for (size_t i = 0; i < actual_list.size(); ++i) {
-    RenderPass* expected = expected_list[i];
-    RenderPass* actual = actual_list[i];
-
-    EXPECT_EQ(expected->id, actual->id);
-    EXPECT_EQ(expected->output_rect, actual->output_rect);
-    EXPECT_EQ(expected->transform_to_root_target,
-              actual->transform_to_root_target);
-    EXPECT_EQ(expected->damage_rect, actual->damage_rect);
-    EXPECT_EQ(expected->has_transparent_background,
-              actual->has_transparent_background);
-
-    EXPECT_EQ(expected->shared_quad_state_list.size(),
-              actual->shared_quad_state_list.size());
-    EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
-
-    for (auto exp_iter = expected->quad_list.cbegin(),
-              act_iter = actual->quad_list.cbegin();
-         exp_iter != expected->quad_list.cend();
-         ++exp_iter, ++act_iter) {
-      EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
-      EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
-                act_iter->shared_quad_state->content_bounds.ToString());
-    }
-  }
-}
-
-TEST(OverlayTest, NoOverlaysByDefault) {
-  scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-  OverlayOutputSurface output_surface(provider);
-  EXPECT_EQ(NULL, output_surface.overlay_candidate_validator());
-
-  output_surface.InitWithSingleOverlayValidator();
-  EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
-}
-
-TEST(OverlayTest, OverlaysProcessorHasStrategy) {
-  scoped_refptr<TestContextProvider> provider = TestContextProvider::Create();
-  OverlayOutputSurface output_surface(provider);
-  FakeOutputSurfaceClient client;
-  EXPECT_TRUE(output_surface.BindToClient(&client));
-  output_surface.InitWithSingleOverlayValidator();
-  EXPECT_TRUE(output_surface.overlay_candidate_validator() != NULL);
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create(
-      &output_surface, shared_bitmap_manager.get(), NULL, NULL, 0, false, 1));
-
-  scoped_ptr<DefaultOverlayProcessor> overlay_processor(
-      new DefaultOverlayProcessor(&output_surface, resource_provider.get()));
-  overlay_processor->Initialize();
-  EXPECT_GE(1U, overlay_processor->GetStrategyCount());
-}
-
-class SingleOverlayOnTopTest : public testing::Test {
- protected:
-  void SetUp() override {
-    provider_ = TestContextProvider::Create();
-    output_surface_.reset(new OverlayOutputSurface(provider_));
-    EXPECT_TRUE(output_surface_->BindToClient(&client_));
-    output_surface_->InitWithSingleOverlayValidator();
-    EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL);
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1);
-
-    overlay_processor_.reset(new SingleOverlayProcessor(
-        output_surface_.get(), resource_provider_.get()));
-    overlay_processor_->Initialize();
-  }
-
-  scoped_refptr<TestContextProvider> provider_;
-  scoped_ptr<OverlayOutputSurface> output_surface_;
-  FakeOutputSurfaceClient client_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<SingleOverlayProcessor> overlay_processor_;
-};
-
-TEST_F(SingleOverlayOnTopTest, SuccessfullOverlay) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  TextureDrawQuad* original_quad =
-      CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                    pass->shared_quad_state_list.back(),
-                                    pass.get());
-  unsigned original_resource_id = original_quad->resource_id;
-
-  // Add something behind it.
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  // Check for potential candidates.
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-
-  ASSERT_EQ(1U, pass_list.size());
-  ASSERT_EQ(2U, candidate_list.size());
-
-  RenderPass* main_pass = pass_list.back();
-  // Check that the quad is gone.
-  EXPECT_EQ(2U, main_pass->quad_list.size());
-  const QuadList& quad_list = main_pass->quad_list;
-  for (QuadList::ConstBackToFrontIterator it = quad_list.BackToFrontBegin();
-       it != quad_list.BackToFrontEnd();
-       ++it) {
-    EXPECT_NE(DrawQuad::TEXTURE_CONTENT, it->material);
-  }
-
-  // Check that the right resource id got extracted.
-  EXPECT_EQ(original_resource_id, candidate_list.back().resource_id);
-}
-
-TEST_F(SingleOverlayOnTopTest, NoCandidates) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(0U, candidate_list.size());
-  // There should be nothing new here.
-  CompareRenderPassLists(pass_list, original_pass_list);
-}
-
-TEST_F(SingleOverlayOnTopTest, OccludedCandidates) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(0U, candidate_list.size());
-  // There should be nothing new here.
-  CompareRenderPassLists(pass_list, original_pass_list);
-}
-
-// Test with multiple render passes.
-TEST_F(SingleOverlayOnTopTest, MultipleRenderPasses) {
-  RenderPassList pass_list;
-  pass_list.push_back(CreateRenderPass());
-
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  // Add something behind it.
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  // Check for potential candidates.
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(2U, candidate_list.size());
-
-  // This should be the same.
-  ASSERT_EQ(2U, pass_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectPremultipliedAlpha) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  TextureDrawQuad* quad =
-      CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                    pass->shared_quad_state_list.back(),
-                                    pass.get());
-  quad->premultiplied_alpha = true;
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectBlending) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  TextureDrawQuad* quad =
-      CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                    pass->shared_quad_state_list.back(),
-                                    pass.get());
-  quad->needs_blending = true;
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectBackgroundColor) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  TextureDrawQuad* quad =
-      CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                    pass->shared_quad_state_list.back(),
-                                    pass.get());
-  quad->background_color = SK_ColorBLACK;
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectBlendMode) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  pass->shared_quad_state_list.back()->blend_mode = SkXfermode::kScreen_Mode;
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectOpacity) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  pass->shared_quad_state_list.back()->opacity = 0.5f;
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectNonScaleTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  pass->shared_quad_state_list.back()
-      ->content_to_target_transform.RotateAboutXAxis(45.f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectNegativeScaleTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
-                                                                         -1.0f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowPositiveScaleTransform) {
-  gfx::Rect rect = kOverlayRect;
-  rect.set_width(rect.width() / 2);
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateCandidateQuadAt(resource_provider_.get(),
-                        pass->shared_quad_state_list.back(), pass.get(), rect);
-  pass->shared_quad_state_list.back()->content_to_target_transform.Scale(2.0f,
-                                                                         1.0f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowNotTopIfNotOccluded) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateCheckeredQuadAt(resource_provider_.get(),
-                        pass->shared_quad_state_list.back(),
-                        pass.get(),
-                        kOverlayTopLeftRect);
-  CreateCandidateQuadAt(resource_provider_.get(),
-                        pass->shared_quad_state_list.back(),
-                        pass.get(),
-                        kOverlayBottomRightRect);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowTransparentOnTop) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->opacity = 0.f;
-  CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
-                         kOverlayBottomRightRect);
-  shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->opacity = 1.f;
-  CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
-                        kOverlayBottomRightRect);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowTransparentColorOnTop) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateSolidColorQuadAt(pass->shared_quad_state_list.back(),
-                         SK_ColorTRANSPARENT, pass.get(),
-                         kOverlayBottomRightRect);
-  CreateCandidateQuadAt(resource_provider_.get(),
-                        pass->shared_quad_state_list.back(), pass.get(),
-                        kOverlayBottomRightRect);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectOpaqueColorOnTop) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->opacity = 0.5f;
-  CreateSolidColorQuadAt(shared_state, SK_ColorBLACK, pass.get(),
-                         kOverlayBottomRightRect);
-  shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->opacity = 1.f;
-  CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
-                        kOverlayBottomRightRect);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectTransparentColorOnTopWithoutBlending) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  CreateSolidColorQuadAt(shared_state, SK_ColorTRANSPARENT, pass.get(),
-                         kOverlayBottomRightRect)->opaque_rect =
-      kOverlayBottomRightRect;
-  CreateCandidateQuadAt(resource_provider_.get(), shared_state, pass.get(),
-                        kOverlayBottomRightRect);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  RenderPassList original_pass_list;
-  RenderPass::CopyAll(pass_list, &original_pass_list);
-
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  EXPECT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, RejectVideoSwapTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
-                                     pass->shared_quad_state_list.back(),
-                                     pass.get(), kSwapTransform);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(0U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowVideoXMirrorTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
-                                     pass->shared_quad_state_list.back(),
-                                     pass.get(), kXMirrorTransform);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowVideoBothMirrorTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
-                                     pass->shared_quad_state_list.back(),
-                                     pass.get(), kBothMirrorTransform);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowVideoNormalTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
-                                     pass->shared_quad_state_list.back(),
-                                     pass.get(), kNormalTransform);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-TEST_F(SingleOverlayOnTopTest, AllowVideoYMirrorTransform) {
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  CreateFullscreenCandidateVideoQuad(resource_provider_.get(),
-                                     pass->shared_quad_state_list.back(),
-                                     pass.get(), kYMirrorTransform);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-  OverlayCandidateList candidate_list;
-  overlay_processor_->ProcessForOverlays(&pass_list, &candidate_list);
-  ASSERT_EQ(1U, pass_list.size());
-  EXPECT_EQ(2U, candidate_list.size());
-}
-
-class OverlayInfoRendererGL : public GLRenderer {
- public:
-  OverlayInfoRendererGL(RendererClient* client,
-                        const RendererSettings* settings,
-                        OutputSurface* output_surface,
-                        ResourceProvider* resource_provider)
-      : GLRenderer(client,
-                   settings,
-                   output_surface,
-                   resource_provider,
-                   NULL,
-                   0),
-        expect_overlays_(false) {}
-
-  MOCK_METHOD3(DoDrawQuad,
-               void(DrawingFrame* frame,
-                    const DrawQuad* quad,
-                    const gfx::QuadF* draw_region));
-
-  using GLRenderer::BeginDrawingFrame;
-
-  void FinishDrawingFrame(DrawingFrame* frame) override {
-    GLRenderer::FinishDrawingFrame(frame);
-
-    if (!expect_overlays_) {
-      EXPECT_EQ(0U, frame->overlay_list.size());
-      return;
-    }
-
-    ASSERT_EQ(2U, frame->overlay_list.size());
-    EXPECT_NE(0U, frame->overlay_list.back().resource_id);
-  }
-
-  void set_expect_overlays(bool expect_overlays) {
-    expect_overlays_ = expect_overlays;
-  }
-
- private:
-  bool expect_overlays_;
-};
-
-class FakeRendererClient : public RendererClient {
- public:
-  // RendererClient methods.
-  void SetFullRootLayerDamage() override {}
-};
-
-class MockOverlayScheduler {
- public:
-  MOCK_METHOD5(Schedule,
-               void(int plane_z_order,
-                    gfx::OverlayTransform plane_transform,
-                    unsigned overlay_texture_id,
-                    const gfx::Rect& display_bounds,
-                    const gfx::RectF& uv_rect));
-};
-
-class GLRendererWithOverlaysTest : public testing::Test {
- protected:
-  GLRendererWithOverlaysTest() {
-    provider_ = TestContextProvider::Create();
-    output_surface_.reset(new OverlayOutputSurface(provider_));
-    CHECK(output_surface_->BindToClient(&output_surface_client_));
-    resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
-
-    provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind(
-        &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_)));
-  }
-
-  void Init(bool use_validator) {
-    if (use_validator)
-      output_surface_->InitWithSingleOverlayValidator();
-
-    renderer_ =
-        make_scoped_ptr(new OverlayInfoRendererGL(&renderer_client_,
-                                                  &settings_,
-                                                  output_surface_.get(),
-                                                  resource_provider_.get()));
-  }
-
-  void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); }
-
-  RendererSettings settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_ptr<OverlayOutputSurface> output_surface_;
-  FakeRendererClient renderer_client_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<OverlayInfoRendererGL> renderer_;
-  scoped_refptr<TestContextProvider> provider_;
-  MockOverlayScheduler scheduler_;
-};
-
-TEST_F(GLRendererWithOverlaysTest, OverlayQuadNotDrawn) {
-  bool use_validator = true;
-  Init(use_validator);
-  renderer_->set_expect_overlays(true);
-  gfx::Rect viewport_rect(16, 16);
-
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  // Candidate pass was taken out and extra skipped pass added,
-  // so only draw 2 quads.
-  EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(2);
-  EXPECT_CALL(scheduler_,
-              Schedule(1,
-                       gfx::OVERLAY_TRANSFORM_NONE,
-                       _,
-                       kOverlayRect,
-                       BoundingRect(kUVTopLeft, kUVBottomRight))).Times(1);
-  renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
-
-  SwapBuffers();
-
-  Mock::VerifyAndClearExpectations(renderer_.get());
-  Mock::VerifyAndClearExpectations(&scheduler_);
-}
-
-TEST_F(GLRendererWithOverlaysTest, OccludedQuadDrawn) {
-  bool use_validator = true;
-  Init(use_validator);
-  renderer_->set_expect_overlays(false);
-  gfx::Rect viewport_rect(16, 16);
-
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  // 3 quads in the pass, all should draw.
-  EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
-  renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
-
-  SwapBuffers();
-
-  Mock::VerifyAndClearExpectations(renderer_.get());
-  Mock::VerifyAndClearExpectations(&scheduler_);
-}
-
-TEST_F(GLRendererWithOverlaysTest, NoValidatorNoOverlay) {
-  bool use_validator = false;
-  Init(use_validator);
-  renderer_->set_expect_overlays(false);
-  gfx::Rect viewport_rect(16, 16);
-
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-
-  CreateFullscreenCandidateQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-  CreateFullscreenCheckeredQuad(resource_provider_.get(),
-                                pass->shared_quad_state_list.back(),
-                                pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  // Should see no overlays.
-  EXPECT_CALL(*renderer_, DoDrawQuad(_, _, _)).Times(3);
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
-  renderer_->DrawFrame(&pass_list, 1.f, viewport_rect, viewport_rect, false);
-
-  SwapBuffers();
-
-  Mock::VerifyAndClearExpectations(renderer_.get());
-  Mock::VerifyAndClearExpectations(&scheduler_);
-}
-
-TEST_F(GLRendererWithOverlaysTest, ResourcesExportedAndReturned) {
-  bool use_validator = true;
-  Init(use_validator);
-  renderer_->set_expect_overlays(true);
-
-  ResourceProvider::ResourceId resource1 =
-      CreateResource(resource_provider_.get());
-  ResourceProvider::ResourceId resource2 =
-      CreateResource(resource_provider_.get());
-
-  scoped_ptr<RenderPass> pass = CreateRenderPass();
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  DirectRenderer::DrawingFrame frame1;
-  frame1.render_passes_in_draw_order = &pass_list;
-  frame1.overlay_list.resize(2);
-  OverlayCandidate& overlay1 = frame1.overlay_list.back();
-  overlay1.resource_id = resource1;
-  overlay1.plane_z_order = 1;
-
-  DirectRenderer::DrawingFrame frame2;
-  frame2.render_passes_in_draw_order = &pass_list;
-  frame2.overlay_list.resize(2);
-  OverlayCandidate& overlay2 = frame2.overlay_list.back();
-  overlay2.resource_id = resource2;
-  overlay2.plane_z_order = 1;
-
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
-  renderer_->BeginDrawingFrame(&frame1);
-  renderer_->FinishDrawingFrame(&frame1);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
-  SwapBuffers();
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
-  renderer_->BeginDrawingFrame(&frame2);
-  renderer_->FinishDrawingFrame(&frame2);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
-  SwapBuffers();
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
-  renderer_->BeginDrawingFrame(&frame1);
-  renderer_->FinishDrawingFrame(&frame1);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource2));
-  SwapBuffers();
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  // No overlays, release the resource.
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
-  DirectRenderer::DrawingFrame frame3;
-  frame3.render_passes_in_draw_order = &pass_list;
-  renderer_->set_expect_overlays(false);
-  renderer_->BeginDrawingFrame(&frame3);
-  renderer_->FinishDrawingFrame(&frame3);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource2));
-  SwapBuffers();
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  // Use the same buffer twice.
-  renderer_->set_expect_overlays(true);
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
-  renderer_->BeginDrawingFrame(&frame1);
-  renderer_->FinishDrawingFrame(&frame1);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffers();
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(1);
-  renderer_->BeginDrawingFrame(&frame1);
-  renderer_->FinishDrawingFrame(&frame1);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffers();
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  Mock::VerifyAndClearExpectations(&scheduler_);
-
-  EXPECT_CALL(scheduler_, Schedule(_, _, _, _, _)).Times(0);
-  renderer_->set_expect_overlays(false);
-  renderer_->BeginDrawingFrame(&frame3);
-  renderer_->FinishDrawingFrame(&frame3);
-  EXPECT_TRUE(resource_provider_->InUseByConsumer(resource1));
-  SwapBuffers();
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(resource1));
-  Mock::VerifyAndClearExpectations(&scheduler_);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/program_binding.cc b/cc/output/program_binding.cc
deleted file mode 100644
index 7809e10..0000000
--- a/cc/output/program_binding.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/output/program_binding.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/output/geometry_binding.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-ProgramBindingBase::ProgramBindingBase()
-    : program_(0),
-      vertex_shader_id_(0),
-      fragment_shader_id_(0),
-      initialized_(false) {}
-
-ProgramBindingBase::~ProgramBindingBase() {
-  // If you hit these asserts, you initialized but forgot to call Cleanup().
-  DCHECK(!program_);
-  DCHECK(!vertex_shader_id_);
-  DCHECK(!fragment_shader_id_);
-  DCHECK(!initialized_);
-}
-
-bool ProgramBindingBase::Init(GLES2Interface* context,
-                              const std::string& vertex_shader,
-                              const std::string& fragment_shader) {
-  TRACE_EVENT0("cc", "ProgramBindingBase::init");
-  vertex_shader_id_ = LoadShader(context, GL_VERTEX_SHADER, vertex_shader);
-  if (!vertex_shader_id_)
-    return false;
-
-  fragment_shader_id_ =
-      LoadShader(context, GL_FRAGMENT_SHADER, fragment_shader);
-  if (!fragment_shader_id_) {
-    context->DeleteShader(vertex_shader_id_);
-    vertex_shader_id_ = 0;
-    return false;
-  }
-
-  program_ =
-      CreateShaderProgram(context, vertex_shader_id_, fragment_shader_id_);
-  return !!program_;
-}
-
-bool ProgramBindingBase::Link(GLES2Interface* context) {
-  context->LinkProgram(program_);
-  CleanupShaders(context);
-  if (!program_)
-    return false;
-#ifndef NDEBUG
-  int linked = 0;
-  context->GetProgramiv(program_, GL_LINK_STATUS, &linked);
-  if (!linked)
-    return false;
-#endif
-  return true;
-}
-
-void ProgramBindingBase::Cleanup(GLES2Interface* context) {
-  initialized_ = false;
-  if (!program_)
-    return;
-
-  DCHECK(context);
-  context->DeleteProgram(program_);
-  program_ = 0;
-
-  CleanupShaders(context);
-}
-
-unsigned ProgramBindingBase::LoadShader(GLES2Interface* context,
-                                        unsigned type,
-                                        const std::string& shader_source) {
-  unsigned shader = context->CreateShader(type);
-  if (!shader)
-    return 0u;
-
-  const char* shader_source_str[] = { shader_source.data() };
-  int shader_length[] = { static_cast<int>(shader_source.length()) };
-  context->ShaderSource(
-      shader, 1,
-      shader_source_str,
-      shader_length);
-  context->CompileShader(shader);
-#ifndef NDEBUG
-  int compiled = 0;
-  context->GetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
-  if (!compiled)
-    return 0u;
-#endif
-  return shader;
-}
-
-unsigned ProgramBindingBase::CreateShaderProgram(GLES2Interface* context,
-                                                 unsigned vertex_shader,
-                                                 unsigned fragment_shader) {
-  unsigned program_object = context->CreateProgram();
-  if (!program_object)
-    return 0;
-
-  context->AttachShader(program_object, vertex_shader);
-  context->AttachShader(program_object, fragment_shader);
-
-  // Bind the common attrib locations.
-  context->BindAttribLocation(
-      program_object, GeometryBinding::PositionAttribLocation(), "a_position");
-  context->BindAttribLocation(
-      program_object, GeometryBinding::TexCoordAttribLocation(), "a_texCoord");
-  context->BindAttribLocation(program_object,
-                              GeometryBinding::TriangleIndexAttribLocation(),
-                              "a_index");
-
-  return program_object;
-}
-
-void ProgramBindingBase::CleanupShaders(GLES2Interface* context) {
-  if (vertex_shader_id_) {
-    context->DeleteShader(vertex_shader_id_);
-    vertex_shader_id_ = 0;
-  }
-  if (fragment_shader_id_) {
-    context->DeleteShader(fragment_shader_id_);
-    fragment_shader_id_ = 0;
-  }
-}
-
-}  // namespace cc
diff --git a/cc/output/program_binding.h b/cc/output/program_binding.h
deleted file mode 100644
index 1d5132b..0000000
--- a/cc/output/program_binding.h
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_OUTPUT_PROGRAM_BINDING_H_
-#define CC_OUTPUT_PROGRAM_BINDING_H_
-
-#include <string>
-
-#include "base/logging.h"
-#include "cc/output/context_provider.h"
-#include "cc/output/shader.h"
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace cc {
-
-class ProgramBindingBase {
- public:
-  ProgramBindingBase();
-  ~ProgramBindingBase();
-
-  bool Init(gpu::gles2::GLES2Interface* context,
-            const std::string& vertex_shader,
-            const std::string& fragment_shader);
-  bool Link(gpu::gles2::GLES2Interface* context);
-  void Cleanup(gpu::gles2::GLES2Interface* context);
-
-  unsigned program() const { return program_; }
-  bool initialized() const { return initialized_; }
-
- protected:
-  unsigned LoadShader(gpu::gles2::GLES2Interface* context,
-                      unsigned type,
-                      const std::string& shader_source);
-  unsigned CreateShaderProgram(gpu::gles2::GLES2Interface* context,
-                               unsigned vertex_shader,
-                               unsigned fragment_shader);
-  void CleanupShaders(gpu::gles2::GLES2Interface* context);
-
-  unsigned program_;
-  unsigned vertex_shader_id_;
-  unsigned fragment_shader_id_;
-  bool initialized_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ProgramBindingBase);
-};
-
-template <class VertexShader, class FragmentShader>
-class ProgramBinding : public ProgramBindingBase {
- public:
-  ProgramBinding() {}
-
-  void Initialize(ContextProvider* context_provider,
-                  TexCoordPrecision precision,
-                  SamplerType sampler) {
-    return Initialize(
-        context_provider, precision, sampler, BLEND_MODE_NONE, false);
-  }
-
-  void Initialize(ContextProvider* context_provider,
-                  TexCoordPrecision precision,
-                  SamplerType sampler,
-                  BlendMode blend_mode) {
-    return Initialize(
-        context_provider, precision, sampler, blend_mode, false);
-  }
-
-  void Initialize(ContextProvider* context_provider,
-                  TexCoordPrecision precision,
-                  SamplerType sampler,
-                  BlendMode blend_mode,
-                  bool mask_for_background) {
-    DCHECK(context_provider);
-    DCHECK(!initialized_);
-
-    if (context_provider->IsContextLost())
-      return;
-
-    fragment_shader_.set_blend_mode(blend_mode);
-    fragment_shader_.set_mask_for_background(mask_for_background);
-
-    if (!ProgramBindingBase::Init(
-            context_provider->ContextGL(),
-            vertex_shader_.GetShaderString(),
-            fragment_shader_.GetShaderString(precision, sampler))) {
-      DCHECK(context_provider->IsContextLost());
-      return;
-    }
-
-    int base_uniform_index = 0;
-    vertex_shader_.Init(context_provider->ContextGL(),
-                        program_, &base_uniform_index);
-    fragment_shader_.Init(context_provider->ContextGL(),
-                          program_, &base_uniform_index);
-
-    // Link after binding uniforms
-    if (!Link(context_provider->ContextGL())) {
-      DCHECK(context_provider->IsContextLost());
-      return;
-    }
-
-    initialized_ = true;
-  }
-
-  const VertexShader& vertex_shader() const { return vertex_shader_; }
-  const FragmentShader& fragment_shader() const { return fragment_shader_; }
-
- private:
-  VertexShader vertex_shader_;
-  FragmentShader fragment_shader_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProgramBinding);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_PROGRAM_BINDING_H_
diff --git a/cc/output/render_surface_filters.cc b/cc/output/render_surface_filters.cc
deleted file mode 100644
index 7cccb24..0000000
--- a/cc/output/render_surface_filters.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/render_surface_filters.h"
-
-#include <algorithm>
-
-#include "cc/output/filter_operation.h"
-#include "cc/output/filter_operations.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "third_party/skia/include/effects/SkAlphaThresholdFilter.h"
-#include "third_party/skia/include/effects/SkBlurImageFilter.h"
-#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
-#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "third_party/skia/include/effects/SkComposeImageFilter.h"
-#include "third_party/skia/include/effects/SkDropShadowImageFilter.h"
-#include "third_party/skia/include/effects/SkMagnifierImageFilter.h"
-#include "third_party/skia/include/effects/SkRectShaderImageFilter.h"
-#include "ui/gfx/geometry/size_f.h"
-
-namespace cc {
-
-namespace {
-
-void GetBrightnessMatrix(float amount, SkScalar matrix[20]) {
-  // Spec implementation
-  // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
-  // <feFunc[R|G|B] type="linear" slope="[amount]">
-  memset(matrix, 0, 20 * sizeof(SkScalar));
-  matrix[0] = matrix[6] = matrix[12] = amount;
-  matrix[18] = 1.f;
-}
-
-void GetSaturatingBrightnessMatrix(float amount, SkScalar matrix[20]) {
-  // Legacy implementation used by internal clients.
-  // <feFunc[R|G|B] type="linear" intercept="[amount]"/>
-  memset(matrix, 0, 20 * sizeof(SkScalar));
-  matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
-  matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
-}
-
-void GetContrastMatrix(float amount, SkScalar matrix[20]) {
-  memset(matrix, 0, 20 * sizeof(SkScalar));
-  matrix[0] = matrix[6] = matrix[12] = amount;
-  matrix[4] = matrix[9] = matrix[14] = (-0.5f * amount + 0.5f) * 255.f;
-  matrix[18] = 1.f;
-}
-
-void GetSaturateMatrix(float amount, SkScalar matrix[20]) {
-  // Note, these values are computed to ensure MatrixNeedsClamping is false
-  // for amount in [0..1]
-  matrix[0] = 0.213f + 0.787f * amount;
-  matrix[1] = 0.715f - 0.715f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = matrix[4] = 0.f;
-  matrix[5] = 0.213f - 0.213f * amount;
-  matrix[6] = 0.715f + 0.285f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = matrix[9] = 0.f;
-  matrix[10] = 0.213f - 0.213f * amount;
-  matrix[11] = 0.715f - 0.715f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = matrix[14] = 0.f;
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
-  matrix[18] = 1.f;
-}
-
-void GetHueRotateMatrix(float hue, SkScalar matrix[20]) {
-  const float kPi = 3.1415926535897932384626433832795f;
-
-  float cos_hue = cosf(hue * kPi / 180.f);
-  float sin_hue = sinf(hue * kPi / 180.f);
-  matrix[0] = 0.213f + cos_hue * 0.787f - sin_hue * 0.213f;
-  matrix[1] = 0.715f - cos_hue * 0.715f - sin_hue * 0.715f;
-  matrix[2] = 0.072f - cos_hue * 0.072f + sin_hue * 0.928f;
-  matrix[3] = matrix[4] = 0.f;
-  matrix[5] = 0.213f - cos_hue * 0.213f + sin_hue * 0.143f;
-  matrix[6] = 0.715f + cos_hue * 0.285f + sin_hue * 0.140f;
-  matrix[7] = 0.072f - cos_hue * 0.072f - sin_hue * 0.283f;
-  matrix[8] = matrix[9] = 0.f;
-  matrix[10] = 0.213f - cos_hue * 0.213f - sin_hue * 0.787f;
-  matrix[11] = 0.715f - cos_hue * 0.715f + sin_hue * 0.715f;
-  matrix[12] = 0.072f + cos_hue * 0.928f + sin_hue * 0.072f;
-  matrix[13] = matrix[14] = 0.f;
-  matrix[15] = matrix[16] = matrix[17] = 0.f;
-  matrix[18] = 1.f;
-  matrix[19] = 0.f;
-}
-
-void GetInvertMatrix(float amount, SkScalar matrix[20]) {
-  memset(matrix, 0, 20 * sizeof(SkScalar));
-  matrix[0] = matrix[6] = matrix[12] = 1.f - 2.f * amount;
-  matrix[4] = matrix[9] = matrix[14] = amount * 255.f;
-  matrix[18] = 1.f;
-}
-
-void GetOpacityMatrix(float amount, SkScalar matrix[20]) {
-  memset(matrix, 0, 20 * sizeof(SkScalar));
-  matrix[0] = matrix[6] = matrix[12] = 1.f;
-  matrix[18] = amount;
-}
-
-void GetGrayscaleMatrix(float amount, SkScalar matrix[20]) {
-  // Note, these values are computed to ensure MatrixNeedsClamping is false
-  // for amount in [0..1]
-  matrix[0] = 0.2126f + 0.7874f * amount;
-  matrix[1] = 0.7152f - 0.7152f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = matrix[4] = 0.f;
-
-  matrix[5] = 0.2126f - 0.2126f * amount;
-  matrix[6] = 0.7152f + 0.2848f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = matrix[9] = 0.f;
-
-  matrix[10] = 0.2126f - 0.2126f * amount;
-  matrix[11] = 0.7152f - 0.7152f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = matrix[14] = 0.f;
-
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
-  matrix[18] = 1.f;
-}
-
-void GetSepiaMatrix(float amount, SkScalar matrix[20]) {
-  matrix[0] = 0.393f + 0.607f * amount;
-  matrix[1] = 0.769f - 0.769f * amount;
-  matrix[2] = 0.189f - 0.189f * amount;
-  matrix[3] = matrix[4] = 0.f;
-
-  matrix[5] = 0.349f - 0.349f * amount;
-  matrix[6] = 0.686f + 0.314f * amount;
-  matrix[7] = 0.168f - 0.168f * amount;
-  matrix[8] = matrix[9] = 0.f;
-
-  matrix[10] = 0.272f - 0.272f * amount;
-  matrix[11] = 0.534f - 0.534f * amount;
-  matrix[12] = 0.131f + 0.869f * amount;
-  matrix[13] = matrix[14] = 0.f;
-
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
-  matrix[18] = 1.f;
-}
-
-skia::RefPtr<SkImageFilter> CreateMatrixImageFilter(
-    const SkScalar matrix[20],
-    const skia::RefPtr<SkImageFilter>& input) {
-  skia::RefPtr<SkColorFilter> color_filter =
-      skia::AdoptRef(SkColorMatrixFilter::Create(matrix));
-  return skia::AdoptRef(
-      SkColorFilterImageFilter::Create(color_filter.get(), input.get()));
-}
-
-}  // namespace
-
-skia::RefPtr<SkImageFilter> RenderSurfaceFilters::BuildImageFilter(
-    const FilterOperations& filters,
-    const gfx::SizeF& size) {
-  skia::RefPtr<SkImageFilter> image_filter;
-  SkScalar matrix[20];
-  for (size_t i = 0; i < filters.size(); ++i) {
-    const FilterOperation& op = filters.at(i);
-    switch (op.type()) {
-      case FilterOperation::GRAYSCALE:
-        GetGrayscaleMatrix(1.f - op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::SEPIA:
-        GetSepiaMatrix(1.f - op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::SATURATE:
-        GetSaturateMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::HUE_ROTATE:
-        GetHueRotateMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::INVERT:
-        GetInvertMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::OPACITY:
-        GetOpacityMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::BRIGHTNESS:
-        GetBrightnessMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::CONTRAST:
-        GetContrastMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::BLUR:
-        image_filter = skia::AdoptRef(SkBlurImageFilter::Create(
-            op.amount(), op.amount(), image_filter.get()));
-        break;
-      case FilterOperation::DROP_SHADOW:
-        image_filter = skia::AdoptRef(SkDropShadowImageFilter::Create(
-            SkIntToScalar(op.drop_shadow_offset().x()),
-            SkIntToScalar(op.drop_shadow_offset().y()),
-            SkIntToScalar(op.amount()),
-            SkIntToScalar(op.amount()),
-            op.drop_shadow_color(),
-            SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode,
-            image_filter.get()));
-        break;
-      case FilterOperation::COLOR_MATRIX:
-        image_filter = CreateMatrixImageFilter(op.matrix(), image_filter);
-        break;
-      case FilterOperation::ZOOM: {
-        skia::RefPtr<SkImageFilter> zoom_filter =
-            skia::AdoptRef(SkMagnifierImageFilter::Create(
-                SkRect::MakeXYWH(
-                    (size.width() - (size.width() / op.amount())) / 2.f,
-                    (size.height() - (size.height() / op.amount())) / 2.f,
-                    size.width() / op.amount(),
-                    size.height() / op.amount()),
-                op.zoom_inset()));
-        if (image_filter.get()) {
-          // TODO(ajuma): When there's a 1-input version of
-          // SkMagnifierImageFilter, use that to handle the input filter
-          // instead of using an SkComposeImageFilter.
-          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
-              zoom_filter.get(), image_filter.get()));
-        } else {
-          image_filter = zoom_filter;
-        }
-        break;
-      }
-      case FilterOperation::SATURATING_BRIGHTNESS:
-        GetSaturatingBrightnessMatrix(op.amount(), matrix);
-        image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        break;
-      case FilterOperation::REFERENCE: {
-        if (!op.image_filter())
-          break;
-
-        skia::RefPtr<SkColorFilter> cf;
-
-        {
-          SkColorFilter* colorfilter_rawptr = NULL;
-          op.image_filter()->asColorFilter(&colorfilter_rawptr);
-          cf = skia::AdoptRef(colorfilter_rawptr);
-        }
-
-        if (cf && cf->asColorMatrix(matrix) &&
-            !op.image_filter()->getInput(0)) {
-          image_filter = CreateMatrixImageFilter(matrix, image_filter);
-        } else if (image_filter) {
-          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
-              op.image_filter().get(), image_filter.get()));
-        } else {
-          image_filter = op.image_filter();
-        }
-        break;
-      }
-      case FilterOperation::ALPHA_THRESHOLD: {
-        skia::RefPtr<SkImageFilter> alpha_filter = skia::AdoptRef(
-            SkAlphaThresholdFilter::Create(
-                op.region(), op.amount(), op.outer_threshold()));
-        if (image_filter.get()) {
-          image_filter = skia::AdoptRef(SkComposeImageFilter::Create(
-              alpha_filter.get(), image_filter.get()));
-        } else {
-          image_filter = alpha_filter;
-        }
-        break;
-      }
-    }
-  }
-  return image_filter;
-}
-
-}  // namespace cc
diff --git a/cc/output/render_surface_filters.h b/cc/output/render_surface_filters.h
deleted file mode 100644
index 22c9363..0000000
--- a/cc/output/render_surface_filters.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 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.
-
-
-#ifndef CC_OUTPUT_RENDER_SURFACE_FILTERS_H_
-#define CC_OUTPUT_RENDER_SURFACE_FILTERS_H_
-
-#include "base/basictypes.h"
-#include "skia/ext/refptr.h"
-
-class GrContext;
-class SkBitmap;
-class SkImageFilter;
-
-namespace gfx {
-class SizeF;
-}
-
-namespace cc {
-
-class FilterOperations;
-
-class RenderSurfaceFilters {
- public:
-  static SkBitmap Apply(const FilterOperations& filters,
-                        unsigned texture_id,
-                        const gfx::SizeF& size,
-                        GrContext* gr_context);
-  static FilterOperations Optimize(const FilterOperations& filters);
-
-  static skia::RefPtr<SkImageFilter> BuildImageFilter(
-      const FilterOperations& filters,
-      const gfx::SizeF& size);
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(RenderSurfaceFilters);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_RENDER_SURFACE_FILTERS_H_
diff --git a/cc/output/renderer.cc b/cc/output/renderer.cc
deleted file mode 100644
index 7be8075..0000000
--- a/cc/output/renderer.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/renderer.h"
-
-#include "cc/quads/render_pass_id.h"
-
-namespace cc {
-
-bool Renderer::HasAllocatedResourcesForTesting(RenderPassId id) const {
-  return false;
-}
-
-void Renderer::SetVisible(bool visible) {
-  if (visible_ == visible)
-    return;
-
-  visible_ = visible;
-  DidChangeVisibility();
-}
-
-RendererCapabilitiesImpl::RendererCapabilitiesImpl()
-    : best_texture_format(RGBA_8888),
-      allow_partial_texture_updates(false),
-      max_texture_size(0),
-      using_shared_memory_resources(false),
-      using_partial_swap(false),
-      using_egl_image(false),
-      using_image(false),
-      using_discard_framebuffer(false),
-      allow_rasterize_on_demand(false) {
-}
-
-RendererCapabilitiesImpl::~RendererCapabilitiesImpl() {}
-
-RendererCapabilities RendererCapabilitiesImpl::MainThreadCapabilities() const {
-  return RendererCapabilities(best_texture_format,
-                              allow_partial_texture_updates,
-                              max_texture_size,
-                              using_shared_memory_resources);
-}
-
-}  // namespace cc
diff --git a/cc/output/renderer.h b/cc/output/renderer.h
deleted file mode 100644
index 7d1097c..0000000
--- a/cc/output/renderer.h
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_RENDERER_H_
-#define CC_OUTPUT_RENDERER_H_
-
-#include "base/basictypes.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/renderer_capabilities.h"
-#include "cc/output/renderer_settings.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-class CompositorFrameAck;
-class CompositorFrameMetadata;
-class RenderPass;
-class RenderPassId;
-class ScopedResource;
-class Task;
-
-typedef ScopedPtrVector<RenderPass> RenderPassList;
-
-struct RendererCapabilitiesImpl {
-  RendererCapabilitiesImpl();
-  ~RendererCapabilitiesImpl();
-
-  // Capabilities copied to main thread.
-  ResourceFormat best_texture_format;
-  bool allow_partial_texture_updates;
-  int max_texture_size;
-  bool using_shared_memory_resources;
-
-  // Capabilities used on compositor thread only.
-  bool using_partial_swap;
-  bool using_egl_image;
-  bool using_image;
-  bool using_discard_framebuffer;
-  bool allow_rasterize_on_demand;
-
-  RendererCapabilities MainThreadCapabilities() const;
-};
-
-class RendererClient {
- public:
-  virtual void SetFullRootLayerDamage() = 0;
-};
-
-class Renderer {
- public:
-  virtual ~Renderer() {}
-
-  virtual const RendererCapabilitiesImpl& Capabilities() const = 0;
-
-  virtual void DecideRenderPassAllocationsForFrame(
-      const RenderPassList& render_passes_in_draw_order) {}
-  virtual bool HasAllocatedResourcesForTesting(RenderPassId id) const;
-
-  // This passes ownership of the render passes to the renderer. It should
-  // consume them, and empty the list. The parameters here may change from frame
-  // to frame and should not be cached.
-  // The |device_viewport_rect| and |device_clip_rect| are in non-y-flipped
-  // window space.
-  virtual void DrawFrame(RenderPassList* render_passes_in_draw_order,
-                         float device_scale_factor,
-                         const gfx::Rect& device_viewport_rect,
-                         const gfx::Rect& device_clip_rect,
-                         bool disable_picture_quad_image_filtering) = 0;
-
-  // Waits for rendering to finish.
-  virtual void Finish() = 0;
-
-  virtual void DoNoOp() {}
-
-  // Puts backbuffer onscreen.
-  virtual void SwapBuffers(const CompositorFrameMetadata& metadata) = 0;
-  virtual void ReceiveSwapBuffersAck(const CompositorFrameAck& ack) {}
-
-  bool visible() const { return visible_; }
-  void SetVisible(bool visible);
-
- protected:
-  Renderer(RendererClient* client, const RendererSettings* settings)
-      : client_(client), settings_(settings), visible_(true) {}
-
-  virtual void DidChangeVisibility() = 0;
-
-  RendererClient* client_;
-  const RendererSettings* settings_;
-  bool visible_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Renderer);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_RENDERER_H_
diff --git a/cc/output/renderer_capabilities.cc b/cc/output/renderer_capabilities.cc
deleted file mode 100644
index 36e012b..0000000
--- a/cc/output/renderer_capabilities.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-#include "cc/output/renderer_capabilities.h"
-
-namespace cc {
-
-RendererCapabilities::RendererCapabilities(ResourceFormat best_texture_format,
-                                           bool allow_partial_texture_updates,
-                                           int max_texture_size,
-                                           bool using_shared_memory_resources)
-    : best_texture_format(best_texture_format),
-      allow_partial_texture_updates(allow_partial_texture_updates),
-      max_texture_size(max_texture_size),
-      using_shared_memory_resources(using_shared_memory_resources) {
-}
-
-RendererCapabilities::RendererCapabilities()
-    : best_texture_format(RGBA_8888),
-      allow_partial_texture_updates(false),
-      max_texture_size(0),
-      using_shared_memory_resources(false) {
-}
-
-RendererCapabilities::~RendererCapabilities() {
-}
-
-}  // namespace cc
diff --git a/cc/output/renderer_capabilities.h b/cc/output/renderer_capabilities.h
deleted file mode 100644
index 4b98281..0000000
--- a/cc/output/renderer_capabilities.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-#ifndef CC_OUTPUT_RENDERER_CAPABILITIES_H_
-#define CC_OUTPUT_RENDERER_CAPABILITIES_H_
-
-#include "cc/resources/resource_format.h"
-
-namespace cc {
-
-// Represents the set of capabilities that a particular Renderer has.
-struct RendererCapabilities {
-  RendererCapabilities(ResourceFormat best_texture_format,
-                       bool allow_partial_texture_updates,
-                       int max_texture_size,
-                       bool using_shared_memory_resources);
-
-  RendererCapabilities();
-  ~RendererCapabilities();
-
-  // Duplicate any modification to this list to RendererCapabilitiesImpl.
-  ResourceFormat best_texture_format;
-  bool allow_partial_texture_updates;
-  int max_texture_size;
-  bool using_shared_memory_resources;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_RENDERER_CAPABILITIES_H_
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
deleted file mode 100644
index 9166ea8..0000000
--- a/cc/output/renderer_pixeltest.cc
+++ /dev/null
@@ -1,2673 +0,0 @@
-// Copyright 2012 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.
-
-#include "base/message_loop/message_loop.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/picture_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/resources/video_resource_updater.h"
-#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/pixel_test.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/skia/include/core/SkColorPriv.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
-#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-namespace {
-
-#if !defined(OS_ANDROID)
-scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPassId id,
-                                                const gfx::Rect& rect) {
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  const gfx::Rect output_rect = rect;
-  const gfx::Rect damage_rect = rect;
-  const gfx::Transform transform_to_root_target;
-  pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
-  return pass.Pass();
-}
-
-scoped_ptr<RenderPass> CreateTestRenderPass(
-    RenderPassId id,
-    const gfx::Rect& rect,
-    const gfx::Transform& transform_to_root_target) {
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  const gfx::Rect output_rect = rect;
-  const gfx::Rect damage_rect = rect;
-  pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
-  return pass.Pass();
-}
-
-SharedQuadState* CreateTestSharedQuadState(
-    gfx::Transform content_to_target_transform,
-    const gfx::Rect& rect,
-    RenderPass* render_pass) {
-  const gfx::Size content_bounds = rect.size();
-  const gfx::Rect visible_content_rect = rect;
-  const gfx::Rect clip_rect = rect;
-  const bool is_clipped = false;
-  const float opacity = 1.0f;
-  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  int sorting_context_id = 0;
-  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(content_to_target_transform,
-                       content_bounds,
-                       visible_content_rect,
-                       clip_rect,
-                       is_clipped,
-                       opacity,
-                       blend_mode,
-                       sorting_context_id);
-  return shared_state;
-}
-
-SharedQuadState* CreateTestSharedQuadStateClipped(
-    gfx::Transform content_to_target_transform,
-    const gfx::Rect& rect,
-    const gfx::Rect& clip_rect,
-    RenderPass* render_pass) {
-  const gfx::Size content_bounds = rect.size();
-  const gfx::Rect visible_content_rect = clip_rect;
-  const bool is_clipped = true;
-  const float opacity = 1.0f;
-  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  int sorting_context_id = 0;
-  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(content_to_target_transform,
-                       content_bounds,
-                       visible_content_rect,
-                       clip_rect,
-                       is_clipped,
-                       opacity,
-                       blend_mode,
-                       sorting_context_id);
-  return shared_state;
-}
-
-void CreateTestRenderPassDrawQuad(const SharedQuadState* shared_state,
-                                  const gfx::Rect& rect,
-                                  RenderPassId pass_id,
-                                  RenderPass* render_pass) {
-  RenderPassDrawQuad* quad =
-      render_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  quad->SetNew(shared_state,
-               rect,
-               rect,
-               pass_id,
-               0,                    // mask_resource_id
-               gfx::Vector2dF(),     // mask_uv_scale
-               gfx::Size(),          // mask_texture_size
-               FilterOperations(),   // foreground filters
-               gfx::Vector2dF(),     // filters scale
-               FilterOperations());  // background filters
-}
-
-void CreateTestTwoColoredTextureDrawQuad(const gfx::Rect& rect,
-                                         SkColor texel_color,
-                                         SkColor texel_stripe_color,
-                                         SkColor background_color,
-                                         bool premultiplied_alpha,
-                                         const SharedQuadState* shared_state,
-                                         ResourceProvider* resource_provider,
-                                         RenderPass* render_pass) {
-  SkPMColor pixel_color = premultiplied_alpha
-                              ? SkPreMultiplyColor(texel_color)
-                              : SkPackARGB32NoCheck(SkColorGetA(texel_color),
-                                                    SkColorGetR(texel_color),
-                                                    SkColorGetG(texel_color),
-                                                    SkColorGetB(texel_color));
-  SkPMColor pixel_stripe_color =
-      premultiplied_alpha
-          ? SkPreMultiplyColor(texel_stripe_color)
-          : SkPackARGB32NoCheck(SkColorGetA(texel_stripe_color),
-                                SkColorGetR(texel_stripe_color),
-                                SkColorGetG(texel_stripe_color),
-                                SkColorGetB(texel_stripe_color));
-  std::vector<uint32_t> pixels(rect.size().GetArea(), pixel_color);
-  for (int i = rect.height() / 4; i < (rect.height() * 3 / 4); ++i) {
-    for (int k = rect.width() / 4; k < (rect.width() * 3 / 4); ++k) {
-      pixels[i * rect.width() + k] = pixel_stripe_color;
-    }
-  }
-  ResourceProvider::ResourceId resource = resource_provider->CreateResource(
-      rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      RGBA_8888);
-  resource_provider->SetPixels(resource,
-                               reinterpret_cast<uint8_t*>(&pixels.front()),
-                               rect, rect, gfx::Vector2d());
-
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  const gfx::PointF uv_top_left(0.0f, 0.0f);
-  const gfx::PointF uv_bottom_right(1.0f, 1.0f);
-  const bool flipped = false;
-  const bool nearest_neighbor = false;
-  TextureDrawQuad* quad =
-      render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
-               premultiplied_alpha, uv_top_left, uv_bottom_right,
-               background_color, vertex_opacity, flipped, nearest_neighbor);
-}
-
-void CreateTestTextureDrawQuad(const gfx::Rect& rect,
-                               SkColor texel_color,
-                               SkColor background_color,
-                               bool premultiplied_alpha,
-                               const SharedQuadState* shared_state,
-                               ResourceProvider* resource_provider,
-                               RenderPass* render_pass) {
-  SkPMColor pixel_color = premultiplied_alpha ?
-      SkPreMultiplyColor(texel_color) :
-      SkPackARGB32NoCheck(SkColorGetA(texel_color),
-                          SkColorGetR(texel_color),
-                          SkColorGetG(texel_color),
-                          SkColorGetB(texel_color));
-  size_t num_pixels = static_cast<size_t>(rect.width()) * rect.height();
-  std::vector<uint32_t> pixels(num_pixels, pixel_color);
-
-  ResourceProvider::ResourceId resource = resource_provider->CreateResource(
-      rect.size(), GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      RGBA_8888);
-  resource_provider->CopyToResource(
-      resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size());
-
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
-  const gfx::PointF uv_top_left(0.0f, 0.0f);
-  const gfx::PointF uv_bottom_right(1.0f, 1.0f);
-  const bool flipped = false;
-  const bool nearest_neighbor = false;
-  TextureDrawQuad* quad =
-      render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  quad->SetNew(shared_state, rect, gfx::Rect(), rect, resource,
-               premultiplied_alpha, uv_top_left, uv_bottom_right,
-               background_color, vertex_opacity, flipped, nearest_neighbor);
-}
-
-void CreateTestYUVVideoDrawQuad_FromVideoFrame(
-    const SharedQuadState* shared_state,
-    scoped_refptr<media::VideoFrame> video_frame,
-    uint8 alpha_value,
-    const gfx::RectF& tex_coord_rect,
-    RenderPass* render_pass,
-    VideoResourceUpdater* video_resource_updater,
-    const gfx::Rect& rect,
-    const gfx::Rect& visible_rect,
-    ResourceProvider* resource_provider) {
-  const bool with_alpha = (video_frame->format() == media::VideoFrame::YV12A);
-  const YUVVideoDrawQuad::ColorSpace color_space =
-      (video_frame->format() == media::VideoFrame::YV12J
-           ? YUVVideoDrawQuad::JPEG
-           : YUVVideoDrawQuad::REC_601);
-  const gfx::Rect opaque_rect(0, 0, 0, 0);
-
-  if (with_alpha) {
-    memset(video_frame->data(media::VideoFrame::kAPlane), alpha_value,
-           video_frame->stride(media::VideoFrame::kAPlane) *
-               video_frame->rows(media::VideoFrame::kAPlane));
-  }
-
-  VideoFrameExternalResources resources =
-      video_resource_updater->CreateExternalResourcesFromVideoFrame(
-          video_frame);
-
-  EXPECT_EQ(VideoFrameExternalResources::YUV_RESOURCE, resources.type);
-  EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
-            resources.mailboxes.size());
-  EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
-            resources.release_callbacks.size());
-
-  ResourceProvider::ResourceId y_resource =
-      resource_provider->CreateResourceFromTextureMailbox(
-          resources.mailboxes[media::VideoFrame::kYPlane],
-          SingleReleaseCallbackImpl::Create(
-              resources.release_callbacks[media::VideoFrame::kYPlane]));
-  ResourceProvider::ResourceId u_resource =
-      resource_provider->CreateResourceFromTextureMailbox(
-          resources.mailboxes[media::VideoFrame::kUPlane],
-          SingleReleaseCallbackImpl::Create(
-              resources.release_callbacks[media::VideoFrame::kUPlane]));
-  ResourceProvider::ResourceId v_resource =
-      resource_provider->CreateResourceFromTextureMailbox(
-          resources.mailboxes[media::VideoFrame::kVPlane],
-          SingleReleaseCallbackImpl::Create(
-              resources.release_callbacks[media::VideoFrame::kVPlane]));
-  ResourceProvider::ResourceId a_resource = 0;
-  if (with_alpha) {
-    a_resource = resource_provider->CreateResourceFromTextureMailbox(
-        resources.mailboxes[media::VideoFrame::kAPlane],
-        SingleReleaseCallbackImpl::Create(
-            resources.release_callbacks[media::VideoFrame::kAPlane]));
-  }
-
-  YUVVideoDrawQuad* yuv_quad =
-      render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
-  yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
-                   tex_coord_rect, video_frame->coded_size(), y_resource,
-                   u_resource, v_resource, a_resource, color_space);
-}
-
-void CreateTestYUVVideoDrawQuad_Striped(
-    const SharedQuadState* shared_state,
-    media::VideoFrame::Format format,
-    bool is_transparent,
-    const gfx::RectF& tex_coord_rect,
-    RenderPass* render_pass,
-    VideoResourceUpdater* video_resource_updater,
-    const gfx::Rect& rect,
-    const gfx::Rect& visible_rect,
-    ResourceProvider* resource_provider) {
-  scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
-      format, rect.size(), rect, rect.size(), base::TimeDelta());
-
-  // YUV values representing a striped pattern, for validating texture
-  // coordinates for sampling.
-  uint8_t y_value = 0;
-  uint8_t u_value = 0;
-  uint8_t v_value = 0;
-  for (int i = 0; i < video_frame->rows(media::VideoFrame::kYPlane); ++i) {
-    uint8_t* y_row = video_frame->data(media::VideoFrame::kYPlane) +
-                     video_frame->stride(media::VideoFrame::kYPlane) * i;
-    for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kYPlane);
-         ++j) {
-      y_row[j] = (y_value += 1);
-    }
-  }
-  for (int i = 0; i < video_frame->rows(media::VideoFrame::kUPlane); ++i) {
-    uint8_t* u_row = video_frame->data(media::VideoFrame::kUPlane) +
-                     video_frame->stride(media::VideoFrame::kUPlane) * i;
-    uint8_t* v_row = video_frame->data(media::VideoFrame::kVPlane) +
-                     video_frame->stride(media::VideoFrame::kVPlane) * i;
-    for (int j = 0; j < video_frame->row_bytes(media::VideoFrame::kUPlane);
-         ++j) {
-      u_row[j] = (u_value += 3);
-      v_row[j] = (v_value += 5);
-    }
-  }
-  uint8 alpha_value = is_transparent ? 0 : 128;
-  CreateTestYUVVideoDrawQuad_FromVideoFrame(
-      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
-      video_resource_updater, rect, visible_rect, resource_provider);
-}
-
-// Creates a video frame of size background_size filled with yuv_background,
-// and then draws a foreground rectangle in a different color on top of
-// that. The foreground rectangle must have coordinates that are divisible
-// by 2 because YUV is a block format.
-void CreateTestYUVVideoDrawQuad_TwoColor(
-    const SharedQuadState* shared_state,
-    media::VideoFrame::Format format,
-    bool is_transparent,
-    const gfx::RectF& tex_coord_rect,
-    const gfx::Size& background_size,
-    const gfx::Rect& visible_rect,
-    uint8 y_background,
-    uint8 u_background,
-    uint8 v_background,
-    const gfx::Rect& foreground_rect,
-    uint8 y_foreground,
-    uint8 u_foreground,
-    uint8 v_foreground,
-    RenderPass* render_pass,
-    VideoResourceUpdater* video_resource_updater,
-    ResourceProvider* resource_provider) {
-  const gfx::Rect rect(background_size);
-
-  scoped_refptr<media::VideoFrame> video_frame =
-      media::VideoFrame::CreateFrame(format, background_size, foreground_rect,
-                                     foreground_rect.size(), base::TimeDelta());
-
-  int planes[] = {media::VideoFrame::kYPlane,
-                  media::VideoFrame::kUPlane,
-                  media::VideoFrame::kVPlane};
-  uint8 yuv_background[] = {y_background, u_background, v_background};
-  uint8 yuv_foreground[] = {y_foreground, u_foreground, v_foreground};
-  int sample_size[] = {1, 2, 2};
-
-  for (int i = 0; i < 3; ++i) {
-    memset(video_frame->data(planes[i]), yuv_background[i],
-           video_frame->stride(planes[i]) * video_frame->rows(planes[i]));
-  }
-
-  for (int i = 0; i < 3; ++i) {
-    // Since yuv encoding uses block encoding, widths have to be divisible
-    // by the sample size in order for this function to behave properly.
-    DCHECK_EQ(foreground_rect.x() % sample_size[i], 0);
-    DCHECK_EQ(foreground_rect.y() % sample_size[i], 0);
-    DCHECK_EQ(foreground_rect.width() % sample_size[i], 0);
-    DCHECK_EQ(foreground_rect.height() % sample_size[i], 0);
-
-    gfx::Rect sample_rect(foreground_rect.x() / sample_size[i],
-                          foreground_rect.y() / sample_size[i],
-                          foreground_rect.width() / sample_size[i],
-                          foreground_rect.height() / sample_size[i]);
-    for (int y = sample_rect.y(); y < sample_rect.bottom(); ++y) {
-      for (int x = sample_rect.x(); x < sample_rect.right(); ++x) {
-        size_t offset = y * video_frame->stride(planes[i]) + x;
-        video_frame->data(planes[i])[offset] = yuv_foreground[i];
-      }
-    }
-  }
-
-  uint8 alpha_value = 255;
-  CreateTestYUVVideoDrawQuad_FromVideoFrame(
-      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
-      video_resource_updater, rect, visible_rect, resource_provider);
-}
-
-void CreateTestYUVVideoDrawQuad_Solid(
-    const SharedQuadState* shared_state,
-    media::VideoFrame::Format format,
-    bool is_transparent,
-    const gfx::RectF& tex_coord_rect,
-    uint8 y,
-    uint8 u,
-    uint8 v,
-    RenderPass* render_pass,
-    VideoResourceUpdater* video_resource_updater,
-    const gfx::Rect& rect,
-    const gfx::Rect& visible_rect,
-    ResourceProvider* resource_provider) {
-  scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
-      format, rect.size(), rect, rect.size(), base::TimeDelta());
-
-  // YUV values of a solid, constant, color. Useful for testing that color
-  // space/color range are being handled properly.
-  memset(video_frame->data(media::VideoFrame::kYPlane), y,
-         video_frame->stride(media::VideoFrame::kYPlane) *
-             video_frame->rows(media::VideoFrame::kYPlane));
-  memset(video_frame->data(media::VideoFrame::kUPlane), u,
-         video_frame->stride(media::VideoFrame::kUPlane) *
-             video_frame->rows(media::VideoFrame::kUPlane));
-  memset(video_frame->data(media::VideoFrame::kVPlane), v,
-         video_frame->stride(media::VideoFrame::kVPlane) *
-             video_frame->rows(media::VideoFrame::kVPlane));
-
-  uint8 alpha_value = is_transparent ? 0 : 128;
-  CreateTestYUVVideoDrawQuad_FromVideoFrame(
-      shared_state, video_frame, alpha_value, tex_coord_rect, render_pass,
-      video_resource_updater, rect, visible_rect, resource_provider);
-}
-
-typedef ::testing::Types<GLRenderer,
-                         SoftwareRenderer,
-                         GLRendererWithExpandedViewport,
-                         SoftwareRendererWithExpandedViewport> RendererTypes;
-TYPED_TEST_CASE(RendererPixelTest, RendererTypes);
-
-template <typename RendererType>
-class SoftwareRendererPixelTest : public RendererPixelTest<RendererType> {};
-
-typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
-    SoftwareRendererTypes;
-TYPED_TEST_CASE(SoftwareRendererPixelTest, SoftwareRendererTypes);
-
-template <typename RendererType>
-class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator {
- public:
-  explicit FuzzyForSoftwareOnlyPixelComparator(bool discard_alpha)
-      : fuzzy_(discard_alpha), exact_(discard_alpha) {}
-
-  bool Compare(const SkBitmap& actual_bmp,
-               const SkBitmap& expected_bmp) const override;
-
- private:
-  FuzzyPixelOffByOneComparator fuzzy_;
-  ExactPixelComparator exact_;
-};
-
-template<>
-bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare(
-    const SkBitmap& actual_bmp,
-    const SkBitmap& expected_bmp) const {
-  return fuzzy_.Compare(actual_bmp, expected_bmp);
-}
-
-template <>
-bool FuzzyForSoftwareOnlyPixelComparator<
-    SoftwareRendererWithExpandedViewport>::Compare(
-    const SkBitmap& actual_bmp,
-    const SkBitmap& expected_bmp) const {
-  return fuzzy_.Compare(actual_bmp, expected_bmp);
-}
-
-template<typename RendererType>
-bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare(
-    const SkBitmap& actual_bmp,
-    const SkBitmap& expected_bmp) const {
-  return exact_.Compare(actual_bmp, expected_bmp);
-}
-
-TYPED_TEST(RendererPixelTest, SimpleGreenRect) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(shared_state, rect, rect, SK_ColorGREEN, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
-  gfx::Rect rect(this->device_viewport_size_);
-  gfx::Rect small_rect(100, 100);
-
-  RenderPassId child_id(2, 1);
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_id, small_rect, gfx::Transform());
-
-  SharedQuadState* child_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), small_rect, child_pass.get());
-
-  SolidColorDrawQuad* color_quad =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(child_shared_state, rect, rect, SK_ColorGREEN, false);
-
-  RenderPassId root_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRenderPass(root_id, rect, gfx::Transform());
-
-  SharedQuadState* root_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, root_pass.get());
-
-  CreateTestRenderPassDrawQuad(
-      root_shared_state, small_rect, child_id, root_pass.get());
-
-  RenderPass* child_pass_ptr = child_pass.get();
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
-      &pass_list,
-      child_pass_ptr,
-      base::FilePath(FILE_PATH_LITERAL("green_small.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, PremultipliedTextureWithoutBackground) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-
-  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
-                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-                            SK_ColorTRANSPARENT,  // Background color.
-                            true,                 // Premultiplied alpha.
-                            shared_state,
-                            this->resource_provider_.get(),
-                            pass.get());
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* texture_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  texture_quad_state->opacity = 0.8f;
-
-  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
-                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-                            SK_ColorGREEN,  // Background color.
-                            true,           // Premultiplied alpha.
-                            texture_quad_state,
-                            this->resource_provider_.get(),
-                            pass.get());
-
-  SharedQuadState* color_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-template <typename QuadType>
-static const base::FilePath::CharType* IntersectingQuadImage() {
-  return FILE_PATH_LITERAL("intersecting_blue_green_squares.png");
-}
-template <>
-const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() {
-  return FILE_PATH_LITERAL("intersecting_blue_green.png");
-}
-template <>
-const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() {
-  return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png");
-}
-
-template <typename TypeParam>
-class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> {
- protected:
-  void SetupQuadStateAndRenderPass() {
-    // This sets up a pair of draw quads. They are both rotated
-    // relative to the root plane, they are also rotated relative to each other.
-    // The intersect in the middle at a non-perpendicular angle so that any
-    // errors are hopefully magnified.
-    // The quads should intersect correctly, as in the front quad should only
-    // be partially in front of the back quad, and partially behind.
-
-    viewport_rect_ = gfx::Rect(this->device_viewport_size_);
-    quad_rect_ = gfx::Rect(0, 0, this->device_viewport_size_.width(),
-                           this->device_viewport_size_.height() / 2.0);
-
-    RenderPassId id(1, 1);
-    render_pass_ = CreateTestRootRenderPass(id, viewport_rect_);
-
-    // Create the front quad rotated on the Z and Y axis.
-    gfx::Transform trans;
-    trans.Translate3d(0, 0, 0.707 * this->device_viewport_size_.width() / 2.0);
-    trans.RotateAboutZAxis(45.0);
-    trans.RotateAboutYAxis(45.0);
-    front_quad_state_ =
-        CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
-    front_quad_state_->clip_rect = quad_rect_;
-    // Make sure they end up in a 3d sorting context.
-    front_quad_state_->sorting_context_id = 1;
-
-    // Create the back quad, and rotate on just the y axis. This will intersect
-    // the first quad partially.
-    trans = gfx::Transform();
-    trans.Translate3d(0, 0, -0.707 * this->device_viewport_size_.width() / 2.0);
-    trans.RotateAboutYAxis(-45.0);
-    back_quad_state_ =
-        CreateTestSharedQuadState(trans, viewport_rect_, render_pass_.get());
-    back_quad_state_->sorting_context_id = 1;
-    back_quad_state_->clip_rect = quad_rect_;
-  }
-  template <typename T>
-  void AppendBackgroundAndRunTest(const PixelComparator& comparator) {
-    SharedQuadState* background_quad_state = CreateTestSharedQuadState(
-        gfx::Transform(), viewport_rect_, render_pass_.get());
-    SolidColorDrawQuad* background_quad =
-        render_pass_->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    background_quad->SetNew(background_quad_state, viewport_rect_,
-                            viewport_rect_, SK_ColorWHITE, false);
-    pass_list_.push_back(render_pass_.Pass());
-    const base::FilePath::CharType* fileName = IntersectingQuadImage<T>();
-    EXPECT_TRUE(
-        this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator));
-  }
-  template <typename T>
-  T* CreateAndAppendDrawQuad() {
-    return render_pass_->CreateAndAppendDrawQuad<T>();
-  }
-
-  scoped_ptr<RenderPass> render_pass_;
-  gfx::Rect viewport_rect_;
-  SharedQuadState* front_quad_state_;
-  SharedQuadState* back_quad_state_;
-  gfx::Rect quad_rect_;
-  RenderPassList pass_list_;
-};
-
-template <typename TypeParam>
-class IntersectingQuadGLPixelTest
-    : public IntersectingQuadPixelTest<TypeParam> {
- public:
-  void SetUp() override {
-    IntersectingQuadPixelTest<TypeParam>::SetUp();
-    video_resource_updater_.reset(
-        new VideoResourceUpdater(this->output_surface_->context_provider(),
-                                 this->resource_provider_.get()));
-    video_resource_updater2_.reset(
-        new VideoResourceUpdater(this->output_surface_->context_provider(),
-                                 this->resource_provider_.get()));
-  }
-
- protected:
-  scoped_ptr<VideoResourceUpdater> video_resource_updater_;
-  scoped_ptr<VideoResourceUpdater> video_resource_updater2_;
-};
-
-template <typename TypeParam>
-class IntersectingQuadSoftwareTest
-    : public IntersectingQuadPixelTest<TypeParam> {};
-
-typedef ::testing::Types<SoftwareRenderer, SoftwareRendererWithExpandedViewport>
-    SoftwareRendererTypes;
-typedef ::testing::Types<GLRenderer, GLRendererWithExpandedViewport>
-    GLRendererTypes;
-
-TYPED_TEST_CASE(IntersectingQuadPixelTest, RendererTypes);
-TYPED_TEST_CASE(IntersectingQuadGLPixelTest, GLRendererTypes);
-TYPED_TEST_CASE(IntersectingQuadSoftwareTest, SoftwareRendererTypes);
-
-TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) {
-  this->SetupQuadStateAndRenderPass();
-
-  SolidColorDrawQuad* quad =
-      this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  SolidColorDrawQuad* quad2 =
-      this->template CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-
-  quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
-               SK_ColorBLUE, false);
-  quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
-                SK_ColorGREEN, false);
-  SCOPED_TRACE("IntersectingSolidColorQuads");
-  this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>(
-      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
-}
-
-template <typename TypeParam>
-SkColor GetColor(const SkColor& color) {
-  return color;
-}
-
-template <>
-SkColor GetColor<GLRenderer>(const SkColor& color) {
-  return SkColorSetARGB(SkColorGetA(color), SkColorGetB(color),
-                        SkColorGetG(color), SkColorGetR(color));
-}
-template <>
-SkColor GetColor<GLRendererWithExpandedViewport>(const SkColor& color) {
-  return GetColor<GLRenderer>(color);
-}
-
-TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) {
-  this->SetupQuadStateAndRenderPass();
-  CreateTestTwoColoredTextureDrawQuad(
-      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
-      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
-      true, this->front_quad_state_, this->resource_provider_.get(),
-      this->render_pass_.get());
-  CreateTestTwoColoredTextureDrawQuad(
-      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
-      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
-      true, this->back_quad_state_, this->resource_provider_.get(),
-      this->render_pass_.get());
-
-  SCOPED_TRACE("IntersectingTexturedQuads");
-  this->template AppendBackgroundAndRunTest<TextureDrawQuad>(
-      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
-}
-
-TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) {
-  this->SetupQuadStateAndRenderPass();
-  gfx::RectF outer_rect(this->quad_rect_);
-  gfx::RectF inner_rect(this->quad_rect_.x() + (this->quad_rect_.width() / 4),
-                        this->quad_rect_.y() + (this->quad_rect_.height() / 4),
-                        this->quad_rect_.width() / 2,
-                        this->quad_rect_.height() / 2);
-
-  SkPaint black_paint;
-  black_paint.setColor(SK_ColorBLACK);
-  SkPaint blue_paint;
-  blue_paint.setColor(SK_ColorBLUE);
-  SkPaint green_paint;
-  green_paint.setColor(SK_ColorGREEN);
-
-  scoped_ptr<FakePicturePile> blue_recording =
-      FakePicturePile::CreateFilledPile(gfx::Size(1000, 1000),
-                                        this->quad_rect_.size());
-  blue_recording->add_draw_rect_with_paint(outer_rect, black_paint);
-  blue_recording->add_draw_rect_with_paint(inner_rect, blue_paint);
-  blue_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> blue_pile =
-      FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
-
-  PictureDrawQuad* blue_quad =
-      this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
-
-  blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, gfx::Rect(),
-                    this->quad_rect_, this->quad_rect_, this->quad_rect_.size(),
-                    false, RGBA_8888, this->quad_rect_, 1.f, blue_pile);
-
-  scoped_ptr<FakePicturePile> green_recording =
-      FakePicturePile::CreateFilledPile(this->quad_rect_.size(),
-                                        this->quad_rect_.size());
-  green_recording->add_draw_rect_with_paint(outer_rect, green_paint);
-  green_recording->add_draw_rect_with_paint(inner_rect, black_paint);
-  green_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> green_pile =
-      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
-
-  PictureDrawQuad* green_quad =
-      this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad->SetNew(this->back_quad_state_, this->quad_rect_, gfx::Rect(),
-                     this->quad_rect_, this->quad_rect_,
-                     this->quad_rect_.size(), false, RGBA_8888,
-                     this->quad_rect_, 1.f, green_pile);
-  SCOPED_TRACE("IntersectingPictureQuadsPass");
-  this->template AppendBackgroundAndRunTest<PictureDrawQuad>(
-      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
-}
-
-TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) {
-  this->SetupQuadStateAndRenderPass();
-  RenderPassId child_pass_id1(2, 2);
-  RenderPassId child_pass_id2(2, 3);
-  scoped_ptr<RenderPass> child_pass1 =
-      CreateTestRenderPass(child_pass_id1, this->quad_rect_, gfx::Transform());
-  SharedQuadState* child1_quad_state = CreateTestSharedQuadState(
-      gfx::Transform(), this->quad_rect_, child_pass1.get());
-  scoped_ptr<RenderPass> child_pass2 =
-      CreateTestRenderPass(child_pass_id2, this->quad_rect_, gfx::Transform());
-  SharedQuadState* child2_quad_state = CreateTestSharedQuadState(
-      gfx::Transform(), this->quad_rect_, child_pass2.get());
-
-  CreateTestTwoColoredTextureDrawQuad(
-      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)),
-      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 255)), SK_ColorTRANSPARENT,
-      true, child1_quad_state, this->resource_provider_.get(),
-      child_pass1.get());
-  CreateTestTwoColoredTextureDrawQuad(
-      this->quad_rect_, GetColor<TypeParam>(SkColorSetARGB(255, 0, 255, 0)),
-      GetColor<TypeParam>(SkColorSetARGB(255, 0, 0, 0)), SK_ColorTRANSPARENT,
-      true, child2_quad_state, this->resource_provider_.get(),
-      child_pass2.get());
-
-  CreateTestRenderPassDrawQuad(this->front_quad_state_, this->quad_rect_,
-                               child_pass_id1, this->render_pass_.get());
-  CreateTestRenderPassDrawQuad(this->back_quad_state_, this->quad_rect_,
-                               child_pass_id2, this->render_pass_.get());
-
-  this->pass_list_.push_back(child_pass1.Pass());
-  this->pass_list_.push_back(child_pass2.Pass());
-  SCOPED_TRACE("IntersectingRenderQuadsPass");
-  this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>(
-      FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f));
-}
-
-TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) {
-  this->SetupQuadStateAndRenderPass();
-  gfx::Rect inner_rect(
-      ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF),
-      ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF),
-      (this->quad_rect_.width() / 2) & ~0xF,
-      (this->quad_rect_.height() / 2) & ~0xF);
-
-  CreateTestYUVVideoDrawQuad_TwoColor(
-      this->front_quad_state_, media::VideoFrame::YV12J, false,
-      gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
-      this->quad_rect_, 0, 128, 128, inner_rect, 29, 255, 107,
-      this->render_pass_.get(), this->video_resource_updater_.get(),
-      this->resource_provider_.get());
-
-  CreateTestYUVVideoDrawQuad_TwoColor(
-      this->back_quad_state_, media::VideoFrame::YV12J, false,
-      gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), this->quad_rect_.size(),
-      this->quad_rect_, 149, 43, 21, inner_rect, 0, 128, 128,
-      this->render_pass_.get(), this->video_resource_updater2_.get(),
-      this->resource_provider_.get());
-
-  SCOPED_TRACE("IntersectingVideoQuads");
-  this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>(
-      FuzzyPixelOffByOneComparator(false));
-}
-
-// TODO(skaslev): The software renderer does not support non-premultplied alpha.
-TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithoutBackground) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-
-  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
-                            SkColorSetARGB(128, 0, 255, 0),  // Texel color.
-                            SK_ColorTRANSPARENT,  // Background color.
-                            false,                // Premultiplied alpha.
-                            shared_state,
-                            this->resource_provider_.get(),
-                            pass.get());
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(shared_state, rect, rect, SK_ColorWHITE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-// TODO(skaslev): The software renderer does not support non-premultplied alpha.
-TEST_F(GLRendererPixelTest, NonPremultipliedTextureWithBackground) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* texture_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  texture_quad_state->opacity = 0.8f;
-
-  CreateTestTextureDrawQuad(gfx::Rect(this->device_viewport_size_),
-                            SkColorSetARGB(204, 120, 255, 120),  // Texel color.
-                            SK_ColorGREEN,  // Background color.
-                            false,          // Premultiplied alpha.
-                            texture_quad_state,
-                            this->resource_provider_.get(),
-                            pass.get());
-
-  SharedQuadState* color_quad_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(color_quad_state, rect, rect, SK_ColorWHITE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-  shared_state->opacity = 0.5f;
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* blank_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  SolidColorDrawQuad* white =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  white->SetNew(
-      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-
-  SkScalar matrix[20];
-  float amount = 0.5f;
-  matrix[0] = 0.213f + 0.787f * amount;
-  matrix[1] = 0.715f - 0.715f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = matrix[4] = 0;
-  matrix[5] = 0.213f - 0.213f * amount;
-  matrix[6] = 0.715f + 0.285f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = matrix[9] = 0;
-  matrix[10] = 0.213f - 0.213f * amount;
-  matrix[11] = 0.715f - 0.715f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = matrix[14] = 0;
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
-  matrix[18] = 1;
-  skia::RefPtr<SkColorFilter> colorFilter(
-      skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
-  skia::RefPtr<SkImageFilter> filter =
-      skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateReferenceFilter(filter));
-
-  RenderPassDrawQuad* render_pass_quad =
-      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  render_pass_quad->SetNew(pass_shared_state,
-                           pass_rect,
-                           pass_rect,
-                           child_pass_id,
-                           0,
-                           gfx::Vector2dF(),
-                           gfx::Size(),
-                           filters,
-                           gfx::Vector2dF(),
-                           FilterOperations());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
-  // renderer so use a fuzzy comparator.
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
-      FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
-}
-
-TYPED_TEST(RendererPixelTest, FastPassSaturateFilter) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-  shared_state->opacity = 0.5f;
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* blank_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  SolidColorDrawQuad* white =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  white->SetNew(
-      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateSaturateFilter(0.5f));
-
-  RenderPassDrawQuad* render_pass_quad =
-      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  render_pass_quad->SetNew(pass_shared_state,
-                           pass_rect,
-                           pass_rect,
-                           child_pass_id,
-                           0,
-                           gfx::Vector2dF(),
-                           gfx::Size(),
-                           filters,
-                           gfx::Vector2dF(),
-                           FilterOperations());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, FastPassFilterChain) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-  shared_state->opacity = 0.5f;
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* blank_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  SolidColorDrawQuad* white =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  white->SetNew(
-      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateGrayscaleFilter(1.f));
-  filters.Append(FilterOperation::CreateBrightnessFilter(0.5f));
-
-  RenderPassDrawQuad* render_pass_quad =
-      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  render_pass_quad->SetNew(pass_shared_state,
-                           pass_rect,
-                           pass_rect,
-                           child_pass_id,
-                           0,
-                           gfx::Vector2dF(),
-                           gfx::Size(),
-                           filters,
-                           gfx::Vector2dF(),
-                           FilterOperations());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, FastPassColorFilterAlphaTranslation) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-  shared_state->opacity = 0.5f;
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* blank_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  SolidColorDrawQuad* white =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  white->SetNew(
-      blank_state, viewport_rect, viewport_rect, SK_ColorWHITE, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-
-  SkScalar matrix[20];
-  float amount = 0.5f;
-  matrix[0] = 0.213f + 0.787f * amount;
-  matrix[1] = 0.715f - 0.715f * amount;
-  matrix[2] = 1.f - (matrix[0] + matrix[1]);
-  matrix[3] = 0;
-  matrix[4] = 20.f;
-  matrix[5] = 0.213f - 0.213f * amount;
-  matrix[6] = 0.715f + 0.285f * amount;
-  matrix[7] = 1.f - (matrix[5] + matrix[6]);
-  matrix[8] = 0;
-  matrix[9] = 200.f;
-  matrix[10] = 0.213f - 0.213f * amount;
-  matrix[11] = 0.715f - 0.715f * amount;
-  matrix[12] = 1.f - (matrix[10] + matrix[11]);
-  matrix[13] = 0;
-  matrix[14] = 1.5f;
-  matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
-  matrix[18] = 1;
-  skia::RefPtr<SkColorFilter> colorFilter(
-      skia::AdoptRef(SkColorMatrixFilter::Create(matrix)));
-  skia::RefPtr<SkImageFilter> filter =
-      skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateReferenceFilter(filter));
-
-  RenderPassDrawQuad* render_pass_quad =
-      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  render_pass_quad->SetNew(pass_shared_state,
-                           pass_rect,
-                           pass_rect,
-                           child_pass_id,
-                           0,
-                           gfx::Vector2dF(),
-                           gfx::Size(),
-                           filters,
-                           gfx::Vector2dF(),
-                           FilterOperations());
-
-  RenderPassList pass_list;
-
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  // This test has alpha=254 for the software renderer vs. alpha=255 for the gl
-  // renderer so use a fuzzy comparator.
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
-      FuzzyForSoftwareOnlyPixelComparator<TypeParam>(false)));
-}
-
-TYPED_TEST(RendererPixelTest, EnlargedRenderPassTexture) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  gfx::Transform aa_transform;
-  aa_transform.Translate(0.5, 0.0);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(aa_transform, pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-
-  SharedQuadState* root_shared_state = CreateTestSharedQuadState(
-      gfx::Transform(), viewport_rect, root_pass.get());
-  SolidColorDrawQuad* background =
-      root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  background->SetNew(root_shared_state,
-                     gfx::Rect(this->device_viewport_size_),
-                     gfx::Rect(this->device_viewport_size_),
-                     SK_ColorWHITE,
-                     false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  this->renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_anti_aliasing.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-// This tests the case where we have a RenderPass with a mask, but the quad
-// for the masked surface does not include the full surface texture.
-TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-  SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
-      gfx::Transform(), viewport_rect, root_pass.get());
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
-  SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
-      gfx::Transform(), viewport_rect, child_pass.get());
-
-  // The child render pass is just a green box.
-  static const SkColor kCSSGreen = 0xff008000;
-  SolidColorDrawQuad* green =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  green->SetNew(
-      child_pass_shared_state, viewport_rect, viewport_rect, kCSSGreen, false);
-
-  // Make a mask.
-  gfx::Rect mask_rect = viewport_rect;
-  SkBitmap bitmap;
-  bitmap.allocPixels(
-      SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
-  SkCanvas canvas(bitmap);
-  SkPaint paint;
-  paint.setStyle(SkPaint::kStroke_Style);
-  paint.setStrokeWidth(SkIntToScalar(4));
-  paint.setColor(SK_ColorWHITE);
-  canvas.clear(SK_ColorTRANSPARENT);
-  gfx::Rect rect = mask_rect;
-  while (!rect.IsEmpty()) {
-    rect.Inset(6, 6, 4, 4);
-    canvas.drawRect(
-        SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
-        paint);
-    rect.Inset(6, 6, 4, 4);
-  }
-
-  ResourceProvider::ResourceId mask_resource_id =
-      this->resource_provider_->CreateResource(
-          mask_rect.size(), GL_CLAMP_TO_EDGE,
-          ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
-        mask_rect.size());
-  }
-
-  // This RenderPassDrawQuad does not include the full |viewport_rect| which is
-  // the size of the child render pass.
-  gfx::Rect sub_rect = gfx::Rect(50, 50, 200, 100);
-  EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
-  EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
-  EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
-  EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
-
-  // Set up a mask on the RenderPassDrawQuad.
-  RenderPassDrawQuad* mask_quad =
-      root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  mask_quad->SetNew(root_pass_shared_state,
-                    sub_rect,
-                    sub_rect,
-                    child_pass_id,
-                    mask_resource_id,
-                    gfx::Vector2dF(2.f, 1.f),     // mask_uv_scale
-                    gfx::Size(mask_rect.size()),  // mask_texture_size
-                    FilterOperations(),           // foreground filters
-                    gfx::Vector2dF(),             // filters scale
-                    FilterOperations());          // background filters
-
-  // White background behind the masked render pass.
-  SolidColorDrawQuad* white =
-      root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  white->SetNew(root_pass_shared_state,
-                viewport_rect,
-                viewport_rect,
-                SK_ColorWHITE,
-                false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("mask_bottom_right.png")),
-      ExactPixelComparator(true)));
-}
-
-template <typename RendererType>
-class RendererPixelTestWithBackgroundFilter
-    : public RendererPixelTest<RendererType> {
- protected:
-  void SetUpRenderPassList() {
-    gfx::Rect device_viewport_rect(this->device_viewport_size_);
-
-    RenderPassId root_id(1, 1);
-    scoped_ptr<RenderPass> root_pass =
-        CreateTestRootRenderPass(root_id, device_viewport_rect);
-    root_pass->has_transparent_background = false;
-
-    gfx::Transform identity_content_to_target_transform;
-
-    RenderPassId filter_pass_id(2, 1);
-    gfx::Transform transform_to_root;
-    scoped_ptr<RenderPass> filter_pass =
-        CreateTestRenderPass(filter_pass_id,
-                             filter_pass_content_rect_,
-                             transform_to_root);
-
-    // A non-visible quad in the filtering render pass.
-    {
-      SharedQuadState* shared_state =
-          CreateTestSharedQuadState(identity_content_to_target_transform,
-                                    filter_pass_content_rect_,
-                                    filter_pass.get());
-      SolidColorDrawQuad* color_quad =
-          filter_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-      color_quad->SetNew(shared_state,
-                         filter_pass_content_rect_,
-                         filter_pass_content_rect_,
-                         SK_ColorTRANSPARENT,
-                         false);
-    }
-
-    {
-      SharedQuadState* shared_state =
-          CreateTestSharedQuadState(filter_pass_to_target_transform_,
-                                    filter_pass_content_rect_,
-                                    filter_pass.get());
-      RenderPassDrawQuad* filter_pass_quad =
-          root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-      filter_pass_quad->SetNew(shared_state,
-                               filter_pass_content_rect_,
-                               filter_pass_content_rect_,
-                               filter_pass_id,
-                               0,                   // mask_resource_id
-                               gfx::Vector2dF(),    // mask_uv_scale
-                               gfx::Size(),         // mask_texture_size
-                               FilterOperations(),  // filters
-                               gfx::Vector2dF(),    // filters_scale
-                               this->background_filters_);
-    }
-
-    const int kColumnWidth = device_viewport_rect.width() / 3;
-
-    gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
-    for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
-      SharedQuadState* shared_state = CreateTestSharedQuadState(
-          identity_content_to_target_transform, left_rect, root_pass.get());
-      SolidColorDrawQuad* color_quad =
-          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-      color_quad->SetNew(
-          shared_state, left_rect, left_rect, SK_ColorGREEN, false);
-      left_rect += gfx::Vector2d(0, left_rect.height() + 1);
-    }
-
-    gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
-    for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
-      SharedQuadState* shared_state = CreateTestSharedQuadState(
-          identity_content_to_target_transform, middle_rect, root_pass.get());
-      SolidColorDrawQuad* color_quad =
-          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-      color_quad->SetNew(
-          shared_state, middle_rect, middle_rect, SK_ColorRED, false);
-      middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
-    }
-
-    gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
-    for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
-      SharedQuadState* shared_state = CreateTestSharedQuadState(
-          identity_content_to_target_transform, right_rect, root_pass.get());
-      SolidColorDrawQuad* color_quad =
-          root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-      color_quad->SetNew(
-          shared_state, right_rect, right_rect, SK_ColorBLUE, false);
-      right_rect += gfx::Vector2d(0, right_rect.height() + 1);
-    }
-
-    SharedQuadState* shared_state =
-        CreateTestSharedQuadState(identity_content_to_target_transform,
-                                  device_viewport_rect,
-                                  root_pass.get());
-    SolidColorDrawQuad* background_quad =
-        root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    background_quad->SetNew(shared_state,
-                            device_viewport_rect,
-                            device_viewport_rect,
-                            SK_ColorWHITE,
-                            false);
-
-    pass_list_.push_back(filter_pass.Pass());
-    pass_list_.push_back(root_pass.Pass());
-  }
-
-  RenderPassList pass_list_;
-  FilterOperations background_filters_;
-  gfx::Transform filter_pass_to_target_transform_;
-  gfx::Rect filter_pass_content_rect_;
-};
-
-typedef ::testing::Types<GLRenderer, SoftwareRenderer>
-    BackgroundFilterRendererTypes;
-TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter,
-                BackgroundFilterRendererTypes);
-
-typedef RendererPixelTestWithBackgroundFilter<GLRenderer>
-GLRendererPixelTestWithBackgroundFilter;
-
-// TODO(skaslev): The software renderer does not support filters yet.
-TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
-  this->background_filters_.Append(
-      FilterOperation::CreateInvertFilter(1.f));
-
-  this->filter_pass_content_rect_ = gfx::Rect(this->device_viewport_size_);
-  this->filter_pass_content_rect_.Inset(12, 14, 16, 18);
-
-  this->SetUpRenderPassList();
-  EXPECT_TRUE(this->RunPixelTest(
-      &this->pass_list_,
-      base::FilePath(FILE_PATH_LITERAL("background_filter.png")),
-      ExactPixelComparator(true)));
-}
-
-class ExternalStencilPixelTest : public GLRendererPixelTest {
- protected:
-  void ClearBackgroundToGreen() {
-    GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
-    output_surface_->EnsureBackbuffer();
-    output_surface_->Reshape(device_viewport_size_, 1);
-    gl->ClearColor(0.f, 1.f, 0.f, 1.f);
-    gl->Clear(GL_COLOR_BUFFER_BIT);
-  }
-
-  void PopulateStencilBuffer() {
-    // Set two quadrants of the stencil buffer to 1.
-    GLES2Interface* gl = output_surface_->context_provider()->ContextGL();
-    output_surface_->EnsureBackbuffer();
-    output_surface_->Reshape(device_viewport_size_, 1);
-    gl->ClearStencil(0);
-    gl->Clear(GL_STENCIL_BUFFER_BIT);
-    gl->Enable(GL_SCISSOR_TEST);
-    gl->ClearStencil(1);
-    gl->Scissor(0,
-                0,
-                device_viewport_size_.width() / 2,
-                device_viewport_size_.height() / 2);
-    gl->Clear(GL_STENCIL_BUFFER_BIT);
-    gl->Scissor(device_viewport_size_.width() / 2,
-                device_viewport_size_.height() / 2,
-                device_viewport_size_.width(),
-                device_viewport_size_.height());
-    gl->Clear(GL_STENCIL_BUFFER_BIT);
-  }
-};
-
-TEST_F(ExternalStencilPixelTest, StencilTestEnabled) {
-  ClearBackgroundToGreen();
-  PopulateStencilBuffer();
-  this->EnableExternalStencilTest();
-
-  // Draw a blue quad that covers the entire device viewport. It should be
-  // clipped to the bottom left and top right corners by the external stencil.
-  gfx::Rect rect(this->device_viewport_size_);
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  SharedQuadState* blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* blue =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
-  pass->has_transparent_background = false;
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-TEST_F(ExternalStencilPixelTest, StencilTestDisabled) {
-  PopulateStencilBuffer();
-
-  // Draw a green quad that covers the entire device viewport. The stencil
-  // buffer should be ignored.
-  gfx::Rect rect(this->device_viewport_size_);
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  SharedQuadState* green_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* green =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green.png")),
-      ExactPixelComparator(true)));
-}
-
-TEST_F(ExternalStencilPixelTest, RenderSurfacesIgnoreStencil) {
-  // The stencil test should apply only to the final render pass.
-  ClearBackgroundToGreen();
-  PopulateStencilBuffer();
-  this->EnableExternalStencilTest();
-
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-  root_pass->has_transparent_background = false;
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height());
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-TEST_F(ExternalStencilPixelTest, DeviceClip) {
-  ClearBackgroundToGreen();
-  gfx::Rect clip_rect(gfx::Point(150, 150), gfx::Size(50, 50));
-  this->ForceDeviceClip(clip_rect);
-
-  // Draw a blue quad that covers the entire device viewport. It should be
-  // clipped to the bottom right corner by the device clip.
-  gfx::Rect rect(this->device_viewport_size_);
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-  SharedQuadState* blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* blue =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
-      ExactPixelComparator(true)));
-}
-
-// Software renderer does not support anti-aliased edges.
-TEST_F(GLRendererPixelTest, AntiAliasing) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  gfx::Transform red_content_to_target_transform;
-  red_content_to_target_transform.Rotate(10);
-  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
-      red_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
-
-  gfx::Transform yellow_content_to_target_transform;
-  yellow_content_to_target_transform.Rotate(5);
-  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
-      yellow_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* yellow =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
-
-  gfx::Transform blue_content_to_target_transform;
-  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
-      blue_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* blue =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-// This test tests that anti-aliasing works for axis aligned quads.
-// Anti-aliasing is only supported in the gl renderer.
-TEST_F(GLRendererPixelTest, AxisAligned) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, rect, transform_to_root);
-
-  gfx::Transform red_content_to_target_transform;
-  red_content_to_target_transform.Translate(50, 50);
-  red_content_to_target_transform.Scale(
-      0.5f + 1.0f / (rect.width() * 2.0f),
-      0.5f + 1.0f / (rect.height() * 2.0f));
-  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
-      red_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  red->SetNew(red_shared_state, rect, rect, SK_ColorRED, false);
-
-  gfx::Transform yellow_content_to_target_transform;
-  yellow_content_to_target_transform.Translate(25.5f, 25.5f);
-  yellow_content_to_target_transform.Scale(0.5f, 0.5f);
-  SharedQuadState* yellow_shared_state = CreateTestSharedQuadState(
-      yellow_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* yellow =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(yellow_shared_state, rect, rect, SK_ColorYELLOW, false);
-
-  gfx::Transform blue_content_to_target_transform;
-  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
-      blue_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* blue =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("axis_aligned.png")),
-      ExactPixelComparator(true)));
-}
-
-// This test tests that forcing anti-aliasing off works as expected.
-// Anti-aliasing is only supported in the gl renderer.
-TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, rect, transform_to_root);
-
-  gfx::Transform hole_content_to_target_transform;
-  hole_content_to_target_transform.Translate(50, 50);
-  hole_content_to_target_transform.Scale(
-      0.5f + 1.0f / (rect.width() * 2.0f),
-      0.5f + 1.0f / (rect.height() * 2.0f));
-  SharedQuadState* hole_shared_state = CreateTestSharedQuadState(
-      hole_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* hole =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  hole->SetAll(
-      hole_shared_state, rect, rect, rect, false, SK_ColorTRANSPARENT, true);
-
-  gfx::Transform green_content_to_target_transform;
-  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
-      green_content_to_target_transform, rect, pass.get());
-
-  SolidColorDrawQuad* green =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  green->SetNew(green_shared_state, rect, rect, SK_ColorGREEN, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("force_anti_aliasing_off.png")),
-      ExactPixelComparator(false)));
-}
-
-TEST_F(GLRendererPixelTest, AntiAliasingPerspective) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  scoped_ptr<RenderPass> pass =
-      CreateTestRootRenderPass(RenderPassId(1, 1), rect);
-
-  gfx::Rect red_rect(0, 0, 180, 500);
-  gfx::Transform red_content_to_target_transform(
-      1.0f,  2.4520f,  10.6206f, 19.0f,
-      0.0f,  0.3528f,  5.9737f,  9.5f,
-      0.0f, -0.2250f, -0.9744f,  0.0f,
-      0.0f,  0.0225f,  0.0974f,  1.0f);
-  SharedQuadState* red_shared_state = CreateTestSharedQuadState(
-      red_content_to_target_transform, red_rect, pass.get());
-  SolidColorDrawQuad* red = pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  red->SetNew(red_shared_state, red_rect, red_rect, SK_ColorRED, false);
-
-  gfx::Rect green_rect(19, 7, 180, 10);
-  SharedQuadState* green_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), green_rect, pass.get());
-  SolidColorDrawQuad* green =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  green->SetNew(
-      green_shared_state, green_rect, green_rect, SK_ColorGREEN, false);
-
-  SharedQuadState* blue_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-  SolidColorDrawQuad* blue =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(blue_shared_state, rect, rect, SK_ColorBLUE, false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("anti_aliasing_perspective.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
-  gfx::Size pile_tile_size(1000, 1000);
-  gfx::Rect viewport(this->device_viewport_size_);
-  // TODO(enne): the renderer should figure this out on its own.
-  ResourceFormat texture_format = RGBA_8888;
-  bool nearest_neighbor = false;
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  // One clipped blue quad in the lower right corner.  Outside the clip
-  // is red, which should not appear.
-  gfx::Rect blue_rect(gfx::Size(100, 100));
-  gfx::Rect blue_clip_rect(gfx::Point(50, 50), gfx::Size(50, 50));
-
-  scoped_ptr<FakePicturePile> blue_recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, blue_rect.size());
-  SkPaint red_paint;
-  red_paint.setColor(SK_ColorRED);
-  blue_recording->add_draw_rect_with_paint(blue_rect, red_paint);
-  SkPaint blue_paint;
-  blue_paint.setColor(SK_ColorBLUE);
-  blue_recording->add_draw_rect_with_paint(blue_clip_rect, blue_paint);
-  blue_recording->RerecordPile();
-
-  scoped_refptr<FakePicturePileImpl> blue_pile =
-      FakePicturePileImpl::CreateFromPile(blue_recording.get(), nullptr);
-
-  gfx::Transform blue_content_to_target_transform;
-  gfx::Vector2d offset(viewport.bottom_right() - blue_rect.bottom_right());
-  blue_content_to_target_transform.Translate(offset.x(), offset.y());
-  gfx::RectF blue_scissor_rect = blue_clip_rect;
-  blue_content_to_target_transform.TransformRect(&blue_scissor_rect);
-  SharedQuadState* blue_shared_state =
-      CreateTestSharedQuadStateClipped(blue_content_to_target_transform,
-                                       blue_rect,
-                                       gfx::ToEnclosingRect(blue_scissor_rect),
-                                       pass.get());
-
-  PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-
-  blue_quad->SetNew(blue_shared_state,
-                    viewport,  // Intentionally bigger than clip.
-                    gfx::Rect(), viewport, gfx::RectF(viewport),
-                    viewport.size(), nearest_neighbor, texture_format, viewport,
-                    1.f, blue_pile.get());
-
-  // One viewport-filling green quad.
-  scoped_ptr<FakePicturePile> green_recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-  SkPaint green_paint;
-  green_paint.setColor(SK_ColorGREEN);
-  green_recording->add_draw_rect_with_paint(viewport, green_paint);
-  green_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> green_pile =
-      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
-
-  gfx::Transform green_content_to_target_transform;
-  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
-      green_content_to_target_transform, viewport, pass.get());
-
-  PictureDrawQuad* green_quad =
-      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
-                     gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
-                     nearest_neighbor, texture_format, viewport, 1.f,
-                     green_pile.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_with_blue_corner.png")),
-      ExactPixelComparator(true)));
-}
-
-// Not WithSkiaGPUBackend since that path currently requires tiles for opacity.
-TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
-  gfx::Size pile_tile_size(1000, 1000);
-  gfx::Rect viewport(this->device_viewport_size_);
-  ResourceFormat texture_format = RGBA_8888;
-  bool nearest_neighbor = false;
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  // One viewport-filling 0.5-opacity green quad.
-  scoped_ptr<FakePicturePile> green_recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-  SkPaint green_paint;
-  green_paint.setColor(SK_ColorGREEN);
-  green_recording->add_draw_rect_with_paint(viewport, green_paint);
-  green_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> green_pile =
-      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
-
-  gfx::Transform green_content_to_target_transform;
-  SharedQuadState* green_shared_state = CreateTestSharedQuadState(
-      green_content_to_target_transform, viewport, pass.get());
-  green_shared_state->opacity = 0.5f;
-
-  PictureDrawQuad* green_quad =
-      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad->SetNew(green_shared_state, viewport, gfx::Rect(), viewport,
-                     gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
-                     texture_format, viewport, 1.f, green_pile.get());
-
-  // One viewport-filling white quad.
-  scoped_ptr<FakePicturePile> white_recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-  SkPaint white_paint;
-  white_paint.setColor(SK_ColorWHITE);
-  white_recording->add_draw_rect_with_paint(viewport, white_paint);
-  white_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> white_pile =
-      FakePicturePileImpl::CreateFromPile(white_recording.get(), nullptr);
-
-  gfx::Transform white_content_to_target_transform;
-  SharedQuadState* white_shared_state = CreateTestSharedQuadState(
-      white_content_to_target_transform, viewport, pass.get());
-
-  PictureDrawQuad* white_quad =
-      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  white_quad->SetNew(white_shared_state, viewport, gfx::Rect(), viewport,
-                     gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
-                     texture_format, viewport, 1.f, white_pile.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-template<typename TypeParam> bool IsSoftwareRenderer() {
-  return false;
-}
-
-template<>
-bool IsSoftwareRenderer<SoftwareRenderer>() {
-  return true;
-}
-
-template<>
-bool IsSoftwareRenderer<SoftwareRendererWithExpandedViewport>() {
-  return true;
-}
-
-// If we disable image filtering, then a 2x2 bitmap should appear as four
-// huge sharp squares.
-TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
-  // We only care about this in software mode since bilinear filtering is
-  // cheap in hardware.
-  if (!IsSoftwareRenderer<TypeParam>())
-    return;
-
-  gfx::Size pile_tile_size(1000, 1000);
-  gfx::Rect viewport(this->device_viewport_size_);
-  ResourceFormat texture_format = RGBA_8888;
-  bool nearest_neighbor = false;
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  SkBitmap bitmap;
-  bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(bitmap);
-    SkCanvas canvas(bitmap);
-    canvas.drawPoint(0, 0, SK_ColorGREEN);
-    canvas.drawPoint(0, 1, SK_ColorBLUE);
-    canvas.drawPoint(1, 0, SK_ColorBLUE);
-    canvas.drawPoint(1, 1, SK_ColorGREEN);
-  }
-
-  scoped_ptr<FakePicturePile> recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-  SkPaint paint;
-  paint.setFilterQuality(kLow_SkFilterQuality);
-  recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
-  recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> pile =
-      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport, pass.get());
-
-  PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
-               gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
-               texture_format, viewport, 1.f, pile.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  this->disable_picture_quad_image_filtering_ = true;
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-// This disables filtering by setting |nearest_neighbor| on the PictureDrawQuad.
-TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
-  gfx::Size pile_tile_size(1000, 1000);
-  gfx::Rect viewport(this->device_viewport_size_);
-  ResourceFormat texture_format = RGBA_8888;
-  bool nearest_neighbor = true;
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  SkBitmap bitmap;
-  bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(bitmap);
-    SkCanvas canvas(bitmap);
-    canvas.drawPoint(0, 0, SK_ColorGREEN);
-    canvas.drawPoint(0, 1, SK_ColorBLUE);
-    canvas.drawPoint(1, 0, SK_ColorBLUE);
-    canvas.drawPoint(1, 1, SK_ColorGREEN);
-  }
-
-  scoped_ptr<FakePicturePile> recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-  SkPaint paint;
-  paint.setFilterQuality(kLow_SkFilterQuality);
-  recording->add_draw_bitmap_with_paint(bitmap, gfx::Point(), paint);
-  recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> pile =
-      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport, pass.get());
-
-  PictureDrawQuad* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport,
-               gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
-               texture_format, viewport, 1.f, pile.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-// This disables filtering by setting |nearest_neighbor| on the TileDrawQuad.
-TYPED_TEST(RendererPixelTest, TileDrawQuadNearestNeighbor) {
-  gfx::Rect viewport(this->device_viewport_size_);
-  bool swizzle_contents = true;
-  bool nearest_neighbor = true;
-
-  SkBitmap bitmap;
-  bitmap.allocN32Pixels(2, 2);
-  {
-    SkAutoLockPixels lock(bitmap);
-    SkCanvas canvas(bitmap);
-    canvas.drawPoint(0, 0, SK_ColorGREEN);
-    canvas.drawPoint(0, 1, SK_ColorBLUE);
-    canvas.drawPoint(1, 0, SK_ColorBLUE);
-    canvas.drawPoint(1, 1, SK_ColorGREEN);
-  }
-
-  gfx::Size tile_size(2, 2);
-  ResourceProvider::ResourceId resource =
-      this->resource_provider_->CreateResource(
-          tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-          RGBA_8888);
-
-  {
-    SkAutoLockPixels lock(bitmap);
-    this->resource_provider_->CopyToResource(
-        resource, static_cast<uint8_t*>(bitmap.getPixels()), tile_size);
-  }
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport, pass.get());
-
-  TileDrawQuad* quad = pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  quad->SetNew(shared_state, viewport, gfx::Rect(), viewport, resource,
-               gfx::Rect(tile_size), tile_size, swizzle_contents,
-               nearest_neighbor);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-TYPED_TEST(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
-  gfx::Size pile_tile_size(1000, 1000);
-  gfx::Rect viewport(this->device_viewport_size_);
-  // TODO(enne): the renderer should figure this out on its own.
-  ResourceFormat texture_format = RGBA_8888;
-  bool nearest_neighbor = false;
-
-  RenderPassId id(1, 1);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> pass =
-      CreateTestRenderPass(id, viewport, transform_to_root);
-
-  // As scaling up the blue checkerboards will cause sampling on the GPU,
-  // a few extra "cleanup rects" need to be added to clobber the blending
-  // to make the output image more clean.  This will also test subrects
-  // of the layer.
-  gfx::Transform green_content_to_target_transform;
-  gfx::Rect green_rect1(gfx::Point(80, 0), gfx::Size(20, 100));
-  gfx::Rect green_rect2(gfx::Point(0, 80), gfx::Size(100, 20));
-
-  scoped_ptr<FakePicturePile> green_recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, viewport.size());
-
-  SkPaint red_paint;
-  red_paint.setColor(SK_ColorRED);
-  green_recording->add_draw_rect_with_paint(viewport, red_paint);
-  SkPaint green_paint;
-  green_paint.setColor(SK_ColorGREEN);
-  green_recording->add_draw_rect_with_paint(green_rect1, green_paint);
-  green_recording->add_draw_rect_with_paint(green_rect2, green_paint);
-  green_recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> green_pile =
-      FakePicturePileImpl::CreateFromPile(green_recording.get(), nullptr);
-
-  SharedQuadState* top_right_green_shared_quad_state =
-      CreateTestSharedQuadState(
-          green_content_to_target_transform, viewport, pass.get());
-
-  PictureDrawQuad* green_quad1 =
-      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
-                      gfx::Rect(), green_rect1, gfx::RectF(green_rect1.size()),
-                      green_rect1.size(), nearest_neighbor, texture_format,
-                      green_rect1, 1.f, green_pile.get());
-
-  PictureDrawQuad* green_quad2 =
-      pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
-                      gfx::Rect(), green_rect2, gfx::RectF(green_rect2.size()),
-                      green_rect2.size(), nearest_neighbor, texture_format,
-                      green_rect2, 1.f, green_pile.get());
-
-  // Add a green clipped checkerboard in the bottom right to help test
-  // interleaving picture quad content and solid color content.
-  gfx::Rect bottom_right_rect(
-      gfx::Point(viewport.width() / 2, viewport.height() / 2),
-      gfx::Size(viewport.width() / 2, viewport.height() / 2));
-  SharedQuadState* bottom_right_green_shared_state =
-      CreateTestSharedQuadStateClipped(green_content_to_target_transform,
-                                       viewport,
-                                       bottom_right_rect,
-                                       pass.get());
-  SolidColorDrawQuad* bottom_right_color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  bottom_right_color_quad->SetNew(bottom_right_green_shared_state,
-                                  viewport,
-                                  viewport,
-                                  SK_ColorGREEN,
-                                  false);
-
-  // Add two blue checkerboards taking up the bottom left and top right,
-  // but use content scales as content rects to make this happen.
-  // The content is at a 4x content scale.
-  gfx::Rect layer_rect(gfx::Size(20, 30));
-  float contents_scale = 4.f;
-  // Two rects that touch at their corners, arbitrarily placed in the layer.
-  gfx::RectF blue_layer_rect1(gfx::PointF(5.5f, 9.0f), gfx::SizeF(2.5f, 2.5f));
-  gfx::RectF blue_layer_rect2(gfx::PointF(8.0f, 6.5f), gfx::SizeF(2.5f, 2.5f));
-  gfx::RectF union_layer_rect = blue_layer_rect1;
-  union_layer_rect.Union(blue_layer_rect2);
-
-  // Because scaling up will cause sampling outside the rects, add one extra
-  // pixel of buffer at the final content scale.
-  float inset = -1.f / contents_scale;
-  blue_layer_rect1.Inset(inset, inset, inset, inset);
-  blue_layer_rect2.Inset(inset, inset, inset, inset);
-
-  scoped_ptr<FakePicturePile> recording =
-      FakePicturePile::CreateFilledPile(pile_tile_size, layer_rect.size());
-
-  Region outside(layer_rect);
-  outside.Subtract(gfx::ToEnclosingRect(union_layer_rect));
-  for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) {
-    recording->add_draw_rect_with_paint(iter.rect(), red_paint);
-  }
-
-  SkPaint blue_paint;
-  blue_paint.setColor(SK_ColorBLUE);
-  recording->add_draw_rect_with_paint(blue_layer_rect1, blue_paint);
-  recording->add_draw_rect_with_paint(blue_layer_rect2, blue_paint);
-  recording->RerecordPile();
-  scoped_refptr<FakePicturePileImpl> pile =
-      FakePicturePileImpl::CreateFromPile(recording.get(), nullptr);
-
-  gfx::Rect content_rect(
-      gfx::ScaleToEnclosingRect(layer_rect, contents_scale));
-  gfx::Rect content_union_rect(
-      gfx::ToEnclosingRect(gfx::ScaleRect(union_layer_rect, contents_scale)));
-
-  // At a scale of 4x the rectangles with a width of 2.5 will take up 10 pixels,
-  // so scale an additional 10x to make them 100x100.
-  gfx::Transform content_to_target_transform;
-  content_to_target_transform.Scale(10.0, 10.0);
-  gfx::Rect quad_content_rect(gfx::Size(20, 20));
-  SharedQuadState* blue_shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, quad_content_rect, pass.get());
-
-  PictureDrawQuad* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  blue_quad->SetNew(blue_shared_state, quad_content_rect, gfx::Rect(),
-                    quad_content_rect, gfx::RectF(quad_content_rect),
-                    content_union_rect.size(), nearest_neighbor, texture_format,
-                    content_union_rect, contents_scale, pile.get());
-
-  // Fill left half of viewport with green.
-  gfx::Transform half_green_content_to_target_transform;
-  gfx::Rect half_green_rect(gfx::Size(viewport.width() / 2, viewport.height()));
-  SharedQuadState* half_green_shared_state = CreateTestSharedQuadState(
-      half_green_content_to_target_transform, half_green_rect, pass.get());
-  SolidColorDrawQuad* half_color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  half_color_quad->SetNew(half_green_shared_state,
-                          half_green_rect,
-                          half_green_rect,
-                          SK_ColorGREEN,
-                          false);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      ExactPixelComparator(true)));
-}
-
-typedef RendererPixelTest<GLRendererWithFlippedSurface>
-    GLRendererPixelTestWithFlippedOutputSurface;
-
-TEST_F(GLRendererPixelTestWithFlippedOutputSurface, ExplicitFlipTest) {
-  // This draws a blue rect above a yellow rect with an inverted output surface.
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")),
-      ExactPixelComparator(true)));
-}
-
-TEST_F(GLRendererPixelTestWithFlippedOutputSurface, CheckChildPassUnflipped) {
-  // This draws a blue rect above a yellow rect with an inverted output surface.
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  gfx::Rect blue_rect(0,
-                      0,
-                      this->device_viewport_size_.width(),
-                      this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect yellow_rect(0,
-                        this->device_viewport_size_.height() / 2,
-                        this->device_viewport_size_.width(),
-                        this->device_viewport_size_.height() / 2);
-  SolidColorDrawQuad* yellow =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  yellow->SetNew(shared_state, yellow_rect, yellow_rect, SK_ColorYELLOW, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  // Check that the child pass remains unflipped.
-  EXPECT_TRUE(this->RunPixelTestWithReadbackTarget(
-      &pass_list,
-      pass_list.front(),
-      base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
-      ExactPixelComparator(true)));
-}
-
-TEST_F(GLRendererPixelTest, CheckReadbackSubset) {
-  gfx::Rect viewport_rect(this->device_viewport_size_);
-
-  RenderPassId root_pass_id(1, 1);
-  scoped_ptr<RenderPass> root_pass =
-      CreateTestRootRenderPass(root_pass_id, viewport_rect);
-
-  RenderPassId child_pass_id(2, 2);
-  gfx::Rect pass_rect(this->device_viewport_size_);
-  gfx::Transform transform_to_root;
-  scoped_ptr<RenderPass> child_pass =
-      CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
-
-  gfx::Transform content_to_target_transform;
-  SharedQuadState* shared_state = CreateTestSharedQuadState(
-      content_to_target_transform, viewport_rect, child_pass.get());
-
-  // Draw a green quad full-size with a blue quad in the lower-right corner.
-  gfx::Rect blue_rect(this->device_viewport_size_.width() * 3 / 4,
-                      this->device_viewport_size_.height() * 3 / 4,
-                      this->device_viewport_size_.width() * 3 / 4,
-                      this->device_viewport_size_.height() * 3 / 4);
-  SolidColorDrawQuad* blue =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  blue->SetNew(shared_state, blue_rect, blue_rect, SK_ColorBLUE, false);
-  gfx::Rect green_rect(0,
-                       0,
-                       this->device_viewport_size_.width(),
-                       this->device_viewport_size_.height());
-  SolidColorDrawQuad* green =
-      child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  green->SetNew(shared_state, green_rect, green_rect, SK_ColorGREEN, false);
-
-  SharedQuadState* pass_shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), pass_rect, root_pass.get());
-  CreateTestRenderPassDrawQuad(
-      pass_shared_state, pass_rect, child_pass_id, root_pass.get());
-
-  RenderPassList pass_list;
-  pass_list.push_back(child_pass.Pass());
-  pass_list.push_back(root_pass.Pass());
-
-  // Check that the child pass remains unflipped.
-  gfx::Rect capture_rect(this->device_viewport_size_.width() / 2,
-                         this->device_viewport_size_.height() / 2,
-                         this->device_viewport_size_.width() / 2,
-                         this->device_viewport_size_.height() / 2);
-  EXPECT_TRUE(this->RunPixelTestWithReadbackTargetAndArea(
-      &pass_list,
-      pass_list.front(),
-      base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")),
-      ExactPixelComparator(true),
-      &capture_rect));
-}
-
-TYPED_TEST(RendererPixelTest, WrapModeRepeat) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-
-  gfx::Size texture_size(4, 4);
-  SkPMColor colors[4] = {
-    SkPreMultiplyColor(SkColorSetARGB(255, 0, 255, 0)),
-    SkPreMultiplyColor(SkColorSetARGB(255, 0, 128, 0)),
-    SkPreMultiplyColor(SkColorSetARGB(255, 0,  64, 0)),
-    SkPreMultiplyColor(SkColorSetARGB(255, 0,   0, 0)),
-  };
-  uint32_t pixels[16] = {
-    colors[0], colors[0], colors[1], colors[1],
-    colors[0], colors[0], colors[1], colors[1],
-    colors[2], colors[2], colors[3], colors[3],
-    colors[2], colors[2], colors[3], colors[3],
-  };
-  ResourceProvider::ResourceId resource =
-      this->resource_provider_->CreateResource(
-          texture_size, GL_REPEAT, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-          RGBA_8888);
-  this->resource_provider_->CopyToResource(
-      resource, reinterpret_cast<uint8_t*>(pixels), texture_size);
-
-  float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  TextureDrawQuad* texture_quad =
-      pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  texture_quad->SetNew(
-      shared_state, gfx::Rect(this->device_viewport_size_), gfx::Rect(),
-      gfx::Rect(this->device_viewport_size_), resource,
-      true,                     // premultiplied_alpha
-      gfx::PointF(0.0f, 0.0f),  // uv_top_left
-      gfx::PointF(              // uv_bottom_right
-          this->device_viewport_size_.width() / texture_size.width(),
-          this->device_viewport_size_.height() / texture_size.height()),
-      SK_ColorWHITE, vertex_opacity,
-      false,   // flipped
-      false);  // nearest_neighbor
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list,
-      base::FilePath(FILE_PATH_LITERAL("wrap_mode_repeat.png")),
-      FuzzyPixelOffByOneComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, Checkerboards) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
-
-  // The color's alpha value is not used.
-  SkColor color1 = SK_ColorGREEN;
-  color1 = SkColorSetA(color1, 0);
-  SkColor color2 = SK_ColorBLUE;
-  color2 = SkColorSetA(color2, 0);
-
-  gfx::Rect content_rect(rect);
-
-  gfx::Rect top_left(content_rect);
-  gfx::Rect top_right(content_rect);
-  gfx::Rect bottom_left(content_rect);
-  gfx::Rect bottom_right(content_rect);
-  // The format is Inset(left, top, right, bottom).
-  top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
-  top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
-  bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
-  bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
-
-  // Appends checkerboard quads with a scale of 1.
-  CheckerboardDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, top_left, top_left, color1, 1.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, top_right, top_right, color2, 1.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, bottom_left, bottom_left, color2, 1.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, bottom_right, bottom_right, color1, 1.f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  base::FilePath::StringType path =
-      IsSoftwareRenderer<TypeParam>()
-          ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
-          : FILE_PATH_LITERAL("checkers.png");
-  EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
-                                 ExactPixelComparator(true)));
-}
-
-TYPED_TEST(RendererPixelTest, CheckerboardsScaled) {
-  gfx::Rect rect(this->device_viewport_size_);
-
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
-
-  gfx::Transform scale;
-  scale.Scale(2.f, 2.f);
-
-  SharedQuadState* shared_state =
-      CreateTestSharedQuadState(scale, rect, pass.get());
-
-  // The color's alpha value is not used.
-  SkColor color1 = SK_ColorGREEN;
-  color1 = SkColorSetA(color1, 0);
-  SkColor color2 = SK_ColorBLUE;
-  color2 = SkColorSetA(color2, 0);
-
-  gfx::Rect content_rect(rect);
-  content_rect.Inset(0, 0, rect.width() / 2, rect.height() / 2);
-
-  gfx::Rect top_left(content_rect);
-  gfx::Rect top_right(content_rect);
-  gfx::Rect bottom_left(content_rect);
-  gfx::Rect bottom_right(content_rect);
-  // The format is Inset(left, top, right, bottom).
-  top_left.Inset(0, 0, content_rect.width() / 2, content_rect.height() / 2);
-  top_right.Inset(content_rect.width() / 2, 0, 0, content_rect.height() / 2);
-  bottom_left.Inset(0, content_rect.height() / 2, content_rect.width() / 2, 0);
-  bottom_right.Inset(content_rect.width() / 2, content_rect.height() / 2, 0, 0);
-
-  // Appends checkerboard quads with a scale of 2, and a shared quad state
-  // with a scale of 2. The checkers should be scaled by 2 * 2 = 4.
-  CheckerboardDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, top_left, top_left, color1, 2.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, top_right, top_right, color2, 2.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, bottom_left, bottom_left, color2, 2.f);
-  quad = pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  quad->SetNew(shared_state, bottom_right, bottom_right, color1, 2.f);
-
-  RenderPassList pass_list;
-  pass_list.push_back(pass.Pass());
-
-  base::FilePath::StringType path =
-      IsSoftwareRenderer<TypeParam>()
-          ? FILE_PATH_LITERAL("four_blue_green_checkers.png")
-          : FILE_PATH_LITERAL("checkers_big.png");
-  EXPECT_TRUE(this->RunPixelTest(&pass_list, base::FilePath(path),
-                                 ExactPixelComparator(true)));
-}
-
-#endif  // !defined(OS_ANDROID)
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/renderer_settings.cc b/cc/output/renderer_settings.cc
deleted file mode 100644
index 2277af3..0000000
--- a/cc/output/renderer_settings.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/renderer_settings.h"
-
-#include <limits>
-
-#include "base/logging.h"
-
-namespace cc {
-
-RendererSettings::RendererSettings()
-    : allow_antialiasing(true),
-      force_antialiasing(false),
-      force_blending_with_shaders(false),
-      partial_swap_enabled(false),
-      finish_rendering_on_resize(false),
-      should_clear_root_render_pass(true),
-      refresh_rate(60.0),
-      highp_threshold_min(0),
-      use_rgba_4444_textures(false),
-      texture_id_allocation_chunk_size(64) {
-}
-
-RendererSettings::~RendererSettings() {
-}
-
-}  // namespace cc
diff --git a/cc/output/renderer_settings.h b/cc/output/renderer_settings.h
deleted file mode 100644
index 5abc928..0000000
--- a/cc/output/renderer_settings.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_RENDERER_SETTINGS_H_
-#define CC_OUTPUT_RENDERER_SETTINGS_H_
-
-#include "base/basictypes.h"
-
-namespace cc {
-
-class RendererSettings {
- public:
-  RendererSettings();
-  ~RendererSettings();
-
-  bool allow_antialiasing;
-  bool force_antialiasing;
-  bool force_blending_with_shaders;
-  bool partial_swap_enabled;
-  bool finish_rendering_on_resize;
-  bool should_clear_root_render_pass;
-  double refresh_rate;
-  int highp_threshold_min;
-  bool use_rgba_4444_textures;
-  size_t texture_id_allocation_chunk_size;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_RENDERER_SETTINGS_H_
diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc
deleted file mode 100644
index a8f09ff..0000000
--- a/cc/output/renderer_unittest.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/delegating_renderer.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_renderer_client.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class TestOutputSurface : public OutputSurface {
- public:
-  explicit TestOutputSurface(
-      const scoped_refptr<ContextProvider>& context_provider);
-  ~TestOutputSurface() override;
-
-  // OutputSurface implementation
-  void SwapBuffers(CompositorFrame* frame) override;
-};
-
-TestOutputSurface::TestOutputSurface(
-    const scoped_refptr<ContextProvider>& context_provider)
-    : OutputSurface(context_provider) {
-}
-
-TestOutputSurface::~TestOutputSurface() {
-}
-
-void TestOutputSurface::SwapBuffers(CompositorFrame* frame) {
-  client_->DidSwapBuffers();
-  client_->DidSwapBuffersComplete();
-}
-
-class MockContextProvider : public TestContextProvider {
- public:
-  explicit MockContextProvider(scoped_ptr<TestWebGraphicsContext3D> context)
-      : TestContextProvider(context.Pass()) {}
-  MOCK_METHOD0(DeleteCachedResources, void());
-
- protected:
-  ~MockContextProvider() {}
-};
-
-template <class T>
-scoped_ptr<Renderer> CreateRenderer(RendererClient* client,
-                                    const RendererSettings* settings,
-                                    OutputSurface* output_surface,
-                                    ResourceProvider* resource_provider);
-
-template <>
-scoped_ptr<Renderer> CreateRenderer<DelegatingRenderer>(
-    RendererClient* client,
-    const RendererSettings* settings,
-    OutputSurface* output_surface,
-    ResourceProvider* resource_provider) {
-  return DelegatingRenderer::Create(
-      client, settings, output_surface, resource_provider);
-}
-
-template <>
-scoped_ptr<Renderer> CreateRenderer<GLRenderer>(
-    RendererClient* client,
-    const RendererSettings* settings,
-    OutputSurface* output_surface,
-    ResourceProvider* resource_provider) {
-  return GLRenderer::Create(
-      client, settings, output_surface, resource_provider, NULL, 0);
-}
-
-template <typename T>
-class RendererTest : public ::testing::Test {
- protected:
-  virtual void SetUp() {
-    context_provider_ =
-        new MockContextProvider(TestWebGraphicsContext3D::Create());
-    output_surface_.reset(new TestOutputSurface(context_provider_));
-    output_surface_->BindToClient(&output_surface_client_);
-    resource_provider_ = ResourceProvider::Create(
-        output_surface_.get(), NULL, NULL, NULL, 0, false, 1);
-    renderer_ = CreateRenderer<T>(&renderer_client_,
-                                  &tree_settings_,
-                                  output_surface_.get(),
-                                  resource_provider_.get());
-  }
-
-  FakeRendererClient renderer_client_;
-  RendererSettings tree_settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_refptr<MockContextProvider> context_provider_;
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<Renderer> renderer_;
-};
-
-typedef ::testing::Types<DelegatingRenderer, GLRenderer> RendererTypes;
-TYPED_TEST_CASE(RendererTest, RendererTypes);
-
-TYPED_TEST(RendererTest, ContextPurgedWhenRendererBecomesInvisible) {
-  EXPECT_CALL(*(this->context_provider_.get()), DeleteCachedResources())
-      .Times(1);
-
-  EXPECT_TRUE(this->renderer_->visible());
-  this->renderer_->SetVisible(false);
-  EXPECT_FALSE(this->renderer_->visible());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
deleted file mode 100644
index 883b683..0000000
--- a/cc/output/shader.cc
+++ /dev/null
@@ -1,2291 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/output/shader.h"
-
-#include <algorithm>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "gpu/command_buffer/client/gles2_interface.h"
-
-template <size_t size>
-std::string StripLambda(const char(&shader)[size]) {
-  // Must contain at least "[]() {}" and trailing null (included in size).
-  static_assert(size >= 8,
-                "String passed to StripLambda must be at least 8 characters");
-  DCHECK_EQ(strncmp("[]() {", shader, 6), 0);
-  DCHECK_EQ(shader[size - 2], '}');
-  return std::string(shader + 6, shader + size - 2);
-}
-
-// Shaders are passed in with lambda syntax, which tricks clang-format into
-// handling them correctly. StipLambda removes this.
-#define SHADER0(Src) StripLambda(#Src)
-#define VERTEX_SHADER(Head, Body) SetVertexTexCoordPrecision(Head + Body)
-#define FRAGMENT_SHADER(Head, Body) \
-  SetFragmentTexCoordPrecision(     \
-      precision,                    \
-      SetFragmentSamplerType(sampler, SetBlendModeFunctions(Head + Body)))
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-namespace {
-
-static void GetProgramUniformLocations(GLES2Interface* context,
-                                       unsigned program,
-                                       size_t count,
-                                       const char** uniforms,
-                                       int* locations,
-                                       int* base_uniform_index) {
-  for (size_t i = 0; i < count; i++) {
-    locations[i] = (*base_uniform_index)++;
-    context->BindUniformLocationCHROMIUM(program, locations[i], uniforms[i]);
-  }
-}
-
-static std::string SetFragmentTexCoordPrecision(
-    TexCoordPrecision requested_precision,
-    std::string shader_string) {
-  switch (requested_precision) {
-    case TEX_COORD_PRECISION_HIGH:
-      DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
-      return "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
-             "  #define TexCoordPrecision highp\n"
-             "#else\n"
-             "  #define TexCoordPrecision mediump\n"
-             "#endif\n" +
-             shader_string;
-    case TEX_COORD_PRECISION_MEDIUM:
-      DCHECK_NE(shader_string.find("TexCoordPrecision"), std::string::npos);
-      return "#define TexCoordPrecision mediump\n" + shader_string;
-    case TEX_COORD_PRECISION_NA:
-      DCHECK_EQ(shader_string.find("TexCoordPrecision"), std::string::npos);
-      DCHECK_EQ(shader_string.find("texture2D"), std::string::npos);
-      DCHECK_EQ(shader_string.find("texture2DRect"), std::string::npos);
-      return shader_string;
-    default:
-      NOTREACHED();
-      break;
-  }
-  return shader_string;
-}
-
-static std::string SetVertexTexCoordPrecision(
-    const std::string& shader_string) {
-  // We unconditionally use highp in the vertex shader since
-  // we are unlikely to be vertex shader bound when drawing large quads.
-  // Also, some vertex shaders mutate the texture coordinate in such a
-  // way that the effective precision might be lower than expected.
-  return "#define TexCoordPrecision highp\n" + shader_string;
-}
-
-TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
-                                            int* highp_threshold_cache,
-                                            int highp_threshold_min,
-                                            int x,
-                                            int y) {
-  if (*highp_threshold_cache == 0) {
-    // Initialize range and precision with minimum spec values for when
-    // GetShaderPrecisionFormat is a test stub.
-    // TODO(brianderson): Implement better stubs of GetShaderPrecisionFormat
-    // everywhere.
-    GLint range[2] = {14, 14};
-    GLint precision = 10;
-    GLC(context,
-        context->GetShaderPrecisionFormat(
-            GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT, range, &precision));
-    *highp_threshold_cache = 1 << precision;
-  }
-
-  int highp_threshold = std::max(*highp_threshold_cache, highp_threshold_min);
-  if (x > highp_threshold || y > highp_threshold)
-    return TEX_COORD_PRECISION_HIGH;
-  return TEX_COORD_PRECISION_MEDIUM;
-}
-
-static std::string SetFragmentSamplerType(SamplerType requested_type,
-                                          std::string shader_string) {
-  switch (requested_type) {
-    case SAMPLER_TYPE_2D:
-      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
-      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
-      return "#define SamplerType sampler2D\n"
-             "#define TextureLookup texture2D\n" +
-             shader_string;
-    case SAMPLER_TYPE_2D_RECT:
-      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
-      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
-      return "#extension GL_ARB_texture_rectangle : require\n"
-             "#define SamplerType sampler2DRect\n"
-             "#define TextureLookup texture2DRect\n" +
-             shader_string;
-    case SAMPLER_TYPE_EXTERNAL_OES:
-      DCHECK_NE(shader_string.find("SamplerType"), std::string::npos);
-      DCHECK_NE(shader_string.find("TextureLookup"), std::string::npos);
-      return "#extension GL_OES_EGL_image_external : require\n"
-             "#define SamplerType samplerExternalOES\n"
-             "#define TextureLookup texture2D\n" +
-             shader_string;
-    case SAMPLER_TYPE_NA:
-      DCHECK_EQ(shader_string.find("SamplerType"), std::string::npos);
-      DCHECK_EQ(shader_string.find("TextureLookup"), std::string::npos);
-      return shader_string;
-    default:
-      NOTREACHED();
-      break;
-  }
-  return shader_string;
-}
-
-}  // namespace
-
-ShaderLocations::ShaderLocations() {
-}
-
-TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
-                                            int* highp_threshold_cache,
-                                            int highp_threshold_min,
-                                            const gfx::Point& max_coordinate) {
-  return TexCoordPrecisionRequired(context,
-                                   highp_threshold_cache,
-                                   highp_threshold_min,
-                                   max_coordinate.x(),
-                                   max_coordinate.y());
-}
-
-TexCoordPrecision TexCoordPrecisionRequired(GLES2Interface* context,
-                                            int* highp_threshold_cache,
-                                            int highp_threshold_min,
-                                            const gfx::Size& max_size) {
-  return TexCoordPrecisionRequired(context,
-                                   highp_threshold_cache,
-                                   highp_threshold_min,
-                                   max_size.width(),
-                                   max_size.height());
-}
-
-VertexShaderPosTex::VertexShaderPosTex() : matrix_location_(-1) {
-}
-
-void VertexShaderPosTex::Init(GLES2Interface* context,
-                              unsigned program,
-                              int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-}
-
-std::string VertexShaderPosTex::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderPosTex::GetShaderHead() {
-  return SHADER0([]() {
-    attribute vec4 a_position;
-    attribute TexCoordPrecision vec2 a_texCoord;
-    uniform mat4 matrix;
-    varying TexCoordPrecision vec2 v_texCoord;
-  });
-}
-
-std::string VertexShaderPosTex::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      gl_Position = matrix * a_position;
-      v_texCoord = a_texCoord;
-    }
-  });
-}
-
-VertexShaderPosTexYUVStretchOffset::VertexShaderPosTexYUVStretchOffset()
-    : matrix_location_(-1), tex_scale_location_(-1), tex_offset_location_(-1) {
-}
-
-void VertexShaderPosTexYUVStretchOffset::Init(GLES2Interface* context,
-                                              unsigned program,
-                                              int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "texScale", "texOffset",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  tex_scale_location_ = locations[1];
-  tex_offset_location_ = locations[2];
-}
-
-std::string VertexShaderPosTexYUVStretchOffset::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderPosTexYUVStretchOffset::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    attribute vec4 a_position;
-    attribute TexCoordPrecision vec2 a_texCoord;
-    uniform mat4 matrix;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform TexCoordPrecision vec2 texScale;
-    uniform TexCoordPrecision vec2 texOffset;
-  });
-}
-
-std::string VertexShaderPosTexYUVStretchOffset::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      gl_Position = matrix * a_position;
-      v_texCoord = a_texCoord * texScale + texOffset;
-    }
-  });
-}
-
-VertexShaderPos::VertexShaderPos() : matrix_location_(-1) {
-}
-
-void VertexShaderPos::Init(GLES2Interface* context,
-                           unsigned program,
-                           int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-}
-
-std::string VertexShaderPos::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderPos::GetShaderHead() {
-  return SHADER0([]() {
-    attribute vec4 a_position;
-    uniform mat4 matrix;
-  });
-}
-
-std::string VertexShaderPos::GetShaderBody() {
-  return SHADER0([]() {
-    void main() { gl_Position = matrix * a_position; }
-  });
-}
-
-VertexShaderPosTexTransform::VertexShaderPosTexTransform()
-    : matrix_location_(-1),
-      tex_transform_location_(-1),
-      vertex_opacity_location_(-1) {
-}
-
-void VertexShaderPosTexTransform::Init(GLES2Interface* context,
-                                       unsigned program,
-                                       int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "texTransform", "opacity",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  tex_transform_location_ = locations[1];
-  vertex_opacity_location_ = locations[2];
-}
-
-std::string VertexShaderPosTexTransform::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderPosTexTransform::GetShaderHead() {
-  return SHADER0([]() {
-    attribute vec4 a_position;
-    attribute TexCoordPrecision vec2 a_texCoord;
-    attribute float a_index;
-    uniform mat4 matrix[8];
-    uniform TexCoordPrecision vec4 texTransform[8];
-    uniform float opacity[32];
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_alpha;
-  });
-}
-
-std::string VertexShaderPosTexTransform::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      int quad_index = int(a_index * 0.25);  // NOLINT
-      gl_Position = matrix[quad_index] * a_position;
-      TexCoordPrecision vec4 texTrans = texTransform[quad_index];
-      v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
-      v_alpha = opacity[int(a_index)];  // NOLINT
-    }
-  });
-}
-
-void VertexShaderPosTexTransform::FillLocations(
-    ShaderLocations* locations) const {
-  locations->matrix = matrix_location();
-  locations->tex_transform = tex_transform_location();
-}
-
-std::string VertexShaderPosTexIdentity::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderPosTexIdentity::GetShaderHead() {
-  return SHADER0([]() {
-    attribute vec4 a_position;
-    varying TexCoordPrecision vec2 v_texCoord;
-  });
-}
-
-std::string VertexShaderPosTexIdentity::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      gl_Position = a_position;
-      v_texCoord = (a_position.xy + vec2(1.0)) * 0.5;
-    }
-  });
-}
-
-VertexShaderQuad::VertexShaderQuad()
-    : matrix_location_(-1), quad_location_(-1) {
-}
-
-void VertexShaderQuad::Init(GLES2Interface* context,
-                            unsigned program,
-                            int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "quad",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  quad_location_ = locations[1];
-}
-
-std::string VertexShaderQuad::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderQuad::GetShaderHead() {
-#if defined(OS_ANDROID)
-  // TODO(epenner): Find the cause of this 'quad' uniform
-  // being missing if we don't add dummy variables.
-  // http://crbug.com/240602
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform TexCoordPrecision vec2 quad[4];
-    uniform TexCoordPrecision vec2 dummy_uniform;
-    varying TexCoordPrecision vec2 dummy_varying;
-  });
-#else
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform TexCoordPrecision vec2 quad[4];
-  });
-#endif
-}
-
-std::string VertexShaderQuad::GetShaderBody() {
-#if defined(OS_ANDROID)
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-      dummy_varying = dummy_uniform;
-    }
-  });
-#else
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-    }
-  });
-#endif
-}
-
-VertexShaderQuadAA::VertexShaderQuadAA()
-    : matrix_location_(-1),
-      viewport_location_(-1),
-      quad_location_(-1),
-      edge_location_(-1) {
-}
-
-void VertexShaderQuadAA::Init(GLES2Interface* context,
-                              unsigned program,
-                              int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "viewport", "quad", "edge",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  viewport_location_ = locations[1];
-  quad_location_ = locations[2];
-  edge_location_ = locations[3];
-}
-
-std::string VertexShaderQuadAA::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderQuadAA::GetShaderHead() {
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform vec4 viewport;
-    uniform TexCoordPrecision vec2 quad[4];
-    uniform TexCoordPrecision vec3 edge[8];
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string VertexShaderQuadAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-      vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
-      vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
-      edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
-                          dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
-                     gl_Position.w;
-      edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
-                          dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
-                     gl_Position.w;
-    }
-  });
-}
-
-VertexShaderQuadTexTransformAA::VertexShaderQuadTexTransformAA()
-    : matrix_location_(-1),
-      viewport_location_(-1),
-      quad_location_(-1),
-      edge_location_(-1),
-      tex_transform_location_(-1) {
-}
-
-void VertexShaderQuadTexTransformAA::Init(GLES2Interface* context,
-                                          unsigned program,
-                                          int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "viewport", "quad", "edge", "texTrans",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  viewport_location_ = locations[1];
-  quad_location_ = locations[2];
-  edge_location_ = locations[3];
-  tex_transform_location_ = locations[4];
-}
-
-std::string VertexShaderQuadTexTransformAA::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderQuadTexTransformAA::GetShaderHead() {
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform vec4 viewport;
-    uniform TexCoordPrecision vec2 quad[4];
-    uniform TexCoordPrecision vec3 edge[8];
-    uniform TexCoordPrecision vec4 texTrans;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string VertexShaderQuadTexTransformAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-      vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
-      vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
-      edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
-                          dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
-                     gl_Position.w;
-      edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
-                          dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
-                     gl_Position.w;
-      v_texCoord = (pos.xy + vec2(0.5)) * texTrans.zw + texTrans.xy;
-    }
-  });
-}
-
-void VertexShaderQuadTexTransformAA::FillLocations(
-    ShaderLocations* locations) const {
-  locations->quad = quad_location();
-  locations->edge = edge_location();
-  locations->viewport = viewport_location();
-  locations->matrix = matrix_location();
-  locations->tex_transform = tex_transform_location();
-}
-
-
-VertexShaderTile::VertexShaderTile()
-    : matrix_location_(-1),
-      quad_location_(-1),
-      vertex_tex_transform_location_(-1) {
-}
-
-void VertexShaderTile::Init(GLES2Interface* context,
-                            unsigned program,
-                            int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "quad", "vertexTexTransform",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  quad_location_ = locations[1];
-  vertex_tex_transform_location_ = locations[2];
-}
-
-std::string VertexShaderTile::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderTile::GetShaderHead() {
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute TexCoordPrecision vec2 a_texCoord;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform TexCoordPrecision vec2 quad[4];
-    uniform TexCoordPrecision vec4 vertexTexTransform;
-    varying TexCoordPrecision vec2 v_texCoord;
-  });
-}
-
-std::string VertexShaderTile::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-      v_texCoord = a_texCoord * vertexTexTransform.zw + vertexTexTransform.xy;
-    }
-  });
-}
-
-VertexShaderTileAA::VertexShaderTileAA()
-    : matrix_location_(-1),
-      viewport_location_(-1),
-      quad_location_(-1),
-      edge_location_(-1),
-      vertex_tex_transform_location_(-1) {
-}
-
-void VertexShaderTileAA::Init(GLES2Interface* context,
-                              unsigned program,
-                              int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "viewport", "quad", "edge", "vertexTexTransform",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  viewport_location_ = locations[1];
-  quad_location_ = locations[2];
-  edge_location_ = locations[3];
-  vertex_tex_transform_location_ = locations[4];
-}
-
-std::string VertexShaderTileAA::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderTileAA::GetShaderHead() {
-  return SHADER0([]() {
-    attribute TexCoordPrecision vec4 a_position;
-    attribute float a_index;
-    uniform mat4 matrix;
-    uniform vec4 viewport;
-    uniform TexCoordPrecision vec2 quad[4];
-    uniform TexCoordPrecision vec3 edge[8];
-    uniform TexCoordPrecision vec4 vertexTexTransform;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string VertexShaderTileAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 pos = quad[int(a_index)];  // NOLINT
-      gl_Position = matrix * vec4(pos, a_position.z, a_position.w);
-      vec2 ndc_pos = 0.5 * (1.0 + gl_Position.xy / gl_Position.w);
-      vec3 screen_pos = vec3(viewport.xy + viewport.zw * ndc_pos, 1.0);
-      edge_dist[0] = vec4(dot(edge[0], screen_pos), dot(edge[1], screen_pos),
-                          dot(edge[2], screen_pos), dot(edge[3], screen_pos)) *
-                     gl_Position.w;
-      edge_dist[1] = vec4(dot(edge[4], screen_pos), dot(edge[5], screen_pos),
-                          dot(edge[6], screen_pos), dot(edge[7], screen_pos)) *
-                     gl_Position.w;
-      v_texCoord = pos.xy * vertexTexTransform.zw + vertexTexTransform.xy;
-    }
-  });
-}
-
-VertexShaderVideoTransform::VertexShaderVideoTransform()
-    : matrix_location_(-1), tex_matrix_location_(-1) {
-}
-
-void VertexShaderVideoTransform::Init(GLES2Interface* context,
-                                      unsigned program,
-                                      int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "matrix", "texMatrix",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  matrix_location_ = locations[0];
-  tex_matrix_location_ = locations[1];
-}
-
-std::string VertexShaderVideoTransform::GetShaderString() const {
-  return VERTEX_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string VertexShaderVideoTransform::GetShaderHead() {
-  return SHADER0([]() {
-    attribute vec4 a_position;
-    attribute TexCoordPrecision vec2 a_texCoord;
-    uniform mat4 matrix;
-    uniform TexCoordPrecision mat4 texMatrix;
-    varying TexCoordPrecision vec2 v_texCoord;
-  });
-}
-
-std::string VertexShaderVideoTransform::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      gl_Position = matrix * a_position;
-      v_texCoord =
-          vec2(texMatrix * vec4(a_texCoord.x, 1.0 - a_texCoord.y, 0.0, 1.0));
-    }
-  });
-}
-
-#define BLEND_MODE_UNIFORMS "s_backdropTexture", \
-                            "s_originalBackdropTexture", \
-                            "backdropRect"
-#define UNUSED_BLEND_MODE_UNIFORMS (!has_blend_mode() ? 3 : 0)
-#define BLEND_MODE_SET_LOCATIONS(X, POS)                   \
-  if (has_blend_mode()) {                                  \
-    DCHECK_LT(static_cast<size_t>(POS) + 2, arraysize(X)); \
-    backdrop_location_ = locations[POS];                   \
-    original_backdrop_location_ = locations[POS + 1];      \
-    backdrop_rect_location_ = locations[POS + 2];          \
-  }
-
-FragmentTexBlendMode::FragmentTexBlendMode()
-    : backdrop_location_(-1),
-      original_backdrop_location_(-1),
-      backdrop_rect_location_(-1),
-      blend_mode_(BLEND_MODE_NONE),
-      mask_for_background_(false) {
-}
-
-std::string FragmentTexBlendMode::SetBlendModeFunctions(
-    std::string shader_string) const {
-  if (shader_string.find("ApplyBlendMode") == std::string::npos)
-    return shader_string;
-
-  if (!has_blend_mode()) {
-    return "#define ApplyBlendMode(X, Y) (X)\n" + shader_string;
-  }
-
-  static const std::string kUniforms = SHADER0([]() {
-    uniform sampler2D s_backdropTexture;
-    uniform sampler2D s_originalBackdropTexture;
-    uniform TexCoordPrecision vec4 backdropRect;
-  });
-
-  std::string mixFunction;
-  if (mask_for_background()) {
-    mixFunction = SHADER0([]() {
-      vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) {
-        vec4 backdrop = texture2D(s_backdropTexture, bgTexCoord);
-        vec4 original_backdrop =
-            texture2D(s_originalBackdropTexture, bgTexCoord);
-        return mix(original_backdrop, backdrop, mask);
-      }
-    });
-  } else {
-    mixFunction = SHADER0([]() {
-      vec4 MixBackdrop(TexCoordPrecision vec2 bgTexCoord, float mask) {
-        return texture2D(s_backdropTexture, bgTexCoord);
-      }
-    });
-  }
-
-  static const std::string kFunctionApplyBlendMode = SHADER0([]() {
-    vec4 GetBackdropColor(float mask) {
-      TexCoordPrecision vec2 bgTexCoord = gl_FragCoord.xy - backdropRect.xy;
-      bgTexCoord.x /= backdropRect.z;
-      bgTexCoord.y /= backdropRect.w;
-      return MixBackdrop(bgTexCoord, mask);
-    }
-
-    vec4 ApplyBlendMode(vec4 src, float mask) {
-      vec4 dst = GetBackdropColor(mask);
-      return Blend(src, dst);
-    }
-  });
-
-  return "precision mediump float;" + GetHelperFunctions() +
-         GetBlendFunction() + kUniforms + mixFunction +
-         kFunctionApplyBlendMode + shader_string;
-}
-
-std::string FragmentTexBlendMode::GetHelperFunctions() const {
-  static const std::string kFunctionHardLight = SHADER0([]() {
-    vec3 hardLight(vec4 src, vec4 dst) {
-      vec3 result;
-      result.r =
-          (2.0 * src.r <= src.a)
-              ? (2.0 * src.r * dst.r)
-              : (src.a * dst.a - 2.0 * (dst.a - dst.r) * (src.a - src.r));
-      result.g =
-          (2.0 * src.g <= src.a)
-              ? (2.0 * src.g * dst.g)
-              : (src.a * dst.a - 2.0 * (dst.a - dst.g) * (src.a - src.g));
-      result.b =
-          (2.0 * src.b <= src.a)
-              ? (2.0 * src.b * dst.b)
-              : (src.a * dst.a - 2.0 * (dst.a - dst.b) * (src.a - src.b));
-      result.rgb += src.rgb * (1.0 - dst.a) + dst.rgb * (1.0 - src.a);
-      return result;
-    }
-  });
-
-  static const std::string kFunctionColorDodgeComponent = SHADER0([]() {
-    float getColorDodgeComponent(float srcc, float srca, float dstc,
-                                 float dsta) {
-      if (0.0 == dstc)
-        return srcc * (1.0 - dsta);
-      float d = srca - srcc;
-      if (0.0 == d)
-        return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
-      d = min(dsta, dstc * srca / d);
-      return d * srca + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
-    }
-  });
-
-  static const std::string kFunctionColorBurnComponent = SHADER0([]() {
-    float getColorBurnComponent(float srcc, float srca, float dstc,
-                                float dsta) {
-      if (dsta == dstc)
-        return srca * dsta + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
-      if (0.0 == srcc)
-        return dstc * (1.0 - srca);
-      float d = max(0.0, dsta - (dsta - dstc) * srca / srcc);
-      return srca * d + srcc * (1.0 - dsta) + dstc * (1.0 - srca);
-    }
-  });
-
-  static const std::string kFunctionSoftLightComponentPosDstAlpha =
-      SHADER0([]() {
-        float getSoftLightComponent(float srcc, float srca, float dstc,
-                                    float dsta) {
-          if (2.0 * srcc <= srca) {
-            return (dstc * dstc * (srca - 2.0 * srcc)) / dsta +
-                   (1.0 - dsta) * srcc + dstc * (-srca + 2.0 * srcc + 1.0);
-          } else if (4.0 * dstc <= dsta) {
-            float DSqd = dstc * dstc;
-            float DCub = DSqd * dstc;
-            float DaSqd = dsta * dsta;
-            float DaCub = DaSqd * dsta;
-            return (-DaCub * srcc +
-                    DaSqd * (srcc - dstc * (3.0 * srca - 6.0 * srcc - 1.0)) +
-                    12.0 * dsta * DSqd * (srca - 2.0 * srcc) -
-                    16.0 * DCub * (srca - 2.0 * srcc)) /
-                   DaSqd;
-          } else {
-            return -sqrt(dsta * dstc) * (srca - 2.0 * srcc) - dsta * srcc +
-                   dstc * (srca - 2.0 * srcc + 1.0) + srcc;
-          }
-        }
-      });
-
-  static const std::string kFunctionLum = SHADER0([]() {
-    float luminance(vec3 color) { return dot(vec3(0.3, 0.59, 0.11), color); }
-
-    vec3 set_luminance(vec3 hueSat, float alpha, vec3 lumColor) {
-      float diff = luminance(lumColor - hueSat);
-      vec3 outColor = hueSat + diff;
-      float outLum = luminance(outColor);
-      float minComp = min(min(outColor.r, outColor.g), outColor.b);
-      float maxComp = max(max(outColor.r, outColor.g), outColor.b);
-      if (minComp < 0.0 && outLum != minComp) {
-        outColor = outLum +
-                   ((outColor - vec3(outLum, outLum, outLum)) * outLum) /
-                       (outLum - minComp);
-      }
-      if (maxComp > alpha && maxComp != outLum) {
-        outColor =
-            outLum +
-            ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) /
-                (maxComp - outLum);
-      }
-      return outColor;
-    }
-  });
-
-  static const std::string kFunctionSat = SHADER0([]() {
-    float saturation(vec3 color) {
-      return max(max(color.r, color.g), color.b) -
-             min(min(color.r, color.g), color.b);
-    }
-
-    vec3 set_saturation_helper(float minComp, float midComp, float maxComp,
-                               float sat) {
-      if (minComp < maxComp) {
-        vec3 result;
-        result.r = 0.0;
-        result.g = sat * (midComp - minComp) / (maxComp - minComp);
-        result.b = sat;
-        return result;
-      } else {
-        return vec3(0, 0, 0);
-      }
-    }
-
-    vec3 set_saturation(vec3 hueLumColor, vec3 satColor) {
-      float sat = saturation(satColor);
-      if (hueLumColor.r <= hueLumColor.g) {
-        if (hueLumColor.g <= hueLumColor.b) {
-          hueLumColor.rgb = set_saturation_helper(hueLumColor.r, hueLumColor.g,
-                                                  hueLumColor.b, sat);
-        } else if (hueLumColor.r <= hueLumColor.b) {
-          hueLumColor.rbg = set_saturation_helper(hueLumColor.r, hueLumColor.b,
-                                                  hueLumColor.g, sat);
-        } else {
-          hueLumColor.brg = set_saturation_helper(hueLumColor.b, hueLumColor.r,
-                                                  hueLumColor.g, sat);
-        }
-      } else if (hueLumColor.r <= hueLumColor.b) {
-        hueLumColor.grb = set_saturation_helper(hueLumColor.g, hueLumColor.r,
-                                                hueLumColor.b, sat);
-      } else if (hueLumColor.g <= hueLumColor.b) {
-        hueLumColor.gbr = set_saturation_helper(hueLumColor.g, hueLumColor.b,
-                                                hueLumColor.r, sat);
-      } else {
-        hueLumColor.bgr = set_saturation_helper(hueLumColor.b, hueLumColor.g,
-                                                hueLumColor.r, sat);
-      }
-      return hueLumColor;
-    }
-  });
-
-  switch (blend_mode_) {
-    case BLEND_MODE_OVERLAY:
-    case BLEND_MODE_HARD_LIGHT:
-      return kFunctionHardLight;
-    case BLEND_MODE_COLOR_DODGE:
-      return kFunctionColorDodgeComponent;
-    case BLEND_MODE_COLOR_BURN:
-      return kFunctionColorBurnComponent;
-    case BLEND_MODE_SOFT_LIGHT:
-      return kFunctionSoftLightComponentPosDstAlpha;
-    case BLEND_MODE_HUE:
-    case BLEND_MODE_SATURATION:
-      return kFunctionLum + kFunctionSat;
-    case BLEND_MODE_COLOR:
-    case BLEND_MODE_LUMINOSITY:
-      return kFunctionLum;
-    default:
-      return std::string();
-  }
-}
-
-std::string FragmentTexBlendMode::GetBlendFunction() const {
-  return "vec4 Blend(vec4 src, vec4 dst) {"
-         "    vec4 result;"
-         "    result.a = src.a + (1.0 - src.a) * dst.a;" +
-         GetBlendFunctionBodyForRGB() +
-         "    return result;"
-         "}";
-}
-
-std::string FragmentTexBlendMode::GetBlendFunctionBodyForRGB() const {
-  switch (blend_mode_) {
-    case BLEND_MODE_NORMAL:
-      return "result.rgb = src.rgb + dst.rgb * (1.0 - src.a);";
-    case BLEND_MODE_SCREEN:
-      return "result.rgb = src.rgb + (1.0 - src.rgb) * dst.rgb;";
-    case BLEND_MODE_LIGHTEN:
-      return "result.rgb = max((1.0 - src.a) * dst.rgb + src.rgb,"
-             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
-    case BLEND_MODE_OVERLAY:
-      return "result.rgb = hardLight(dst, src);";
-    case BLEND_MODE_DARKEN:
-      return "result.rgb = min((1.0 - src.a) * dst.rgb + src.rgb,"
-             "                 (1.0 - dst.a) * src.rgb + dst.rgb);";
-    case BLEND_MODE_COLOR_DODGE:
-      return "result.r = getColorDodgeComponent(src.r, src.a, dst.r, dst.a);"
-             "result.g = getColorDodgeComponent(src.g, src.a, dst.g, dst.a);"
-             "result.b = getColorDodgeComponent(src.b, src.a, dst.b, dst.a);";
-    case BLEND_MODE_COLOR_BURN:
-      return "result.r = getColorBurnComponent(src.r, src.a, dst.r, dst.a);"
-             "result.g = getColorBurnComponent(src.g, src.a, dst.g, dst.a);"
-             "result.b = getColorBurnComponent(src.b, src.a, dst.b, dst.a);";
-    case BLEND_MODE_HARD_LIGHT:
-      return "result.rgb = hardLight(src, dst);";
-    case BLEND_MODE_SOFT_LIGHT:
-      return "if (0.0 == dst.a) {"
-             "  result.rgb = src.rgb;"
-             "} else {"
-             "  result.r = getSoftLightComponent(src.r, src.a, dst.r, dst.a);"
-             "  result.g = getSoftLightComponent(src.g, src.a, dst.g, dst.a);"
-             "  result.b = getSoftLightComponent(src.b, src.a, dst.b, dst.a);"
-             "}";
-    case BLEND_MODE_DIFFERENCE:
-      return "result.rgb = src.rgb + dst.rgb -"
-             "    2.0 * min(src.rgb * dst.a, dst.rgb * src.a);";
-    case BLEND_MODE_EXCLUSION:
-      return "result.rgb = dst.rgb + src.rgb - 2.0 * dst.rgb * src.rgb;";
-    case BLEND_MODE_MULTIPLY:
-      return "result.rgb = (1.0 - src.a) * dst.rgb +"
-             "    (1.0 - dst.a) * src.rgb + src.rgb * dst.rgb;";
-    case BLEND_MODE_HUE:
-      return "vec4 dstSrcAlpha = dst * src.a;"
-             "result.rgb ="
-             "    set_luminance(set_saturation(src.rgb * dst.a,"
-             "                                 dstSrcAlpha.rgb),"
-             "                  dstSrcAlpha.a,"
-             "                  dstSrcAlpha.rgb);"
-             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
-    case BLEND_MODE_SATURATION:
-      return "vec4 dstSrcAlpha = dst * src.a;"
-             "result.rgb = set_luminance(set_saturation(dstSrcAlpha.rgb,"
-             "                                          src.rgb * dst.a),"
-             "                           dstSrcAlpha.a,"
-             "                           dstSrcAlpha.rgb);"
-             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
-    case BLEND_MODE_COLOR:
-      return "vec4 srcDstAlpha = src * dst.a;"
-             "result.rgb = set_luminance(srcDstAlpha.rgb,"
-             "                           srcDstAlpha.a,"
-             "                           dst.rgb * src.a);"
-             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
-    case BLEND_MODE_LUMINOSITY:
-      return "vec4 srcDstAlpha = src * dst.a;"
-             "result.rgb = set_luminance(dst.rgb * src.a,"
-             "                           srcDstAlpha.a,"
-             "                           srcDstAlpha.rgb);"
-             "result.rgb += (1.0 - src.a) * dst.rgb + (1.0 - dst.a) * src.rgb;";
-    case BLEND_MODE_NONE:
-      NOTREACHED();
-  }
-  return "result = vec4(1.0, 0.0, 0.0, 1.0);";
-}
-
-FragmentTexAlphaBinding::FragmentTexAlphaBinding()
-    : sampler_location_(-1), alpha_location_(-1) {
-}
-
-void FragmentTexAlphaBinding::Init(GLES2Interface* context,
-                                   unsigned program,
-                                   int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  alpha_location_ = locations[1];
-  BLEND_MODE_SET_LOCATIONS(locations, 2);
-}
-
-FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
-    : sampler_location_(-1),
-      alpha_location_(-1),
-      color_matrix_location_(-1),
-      color_offset_location_(-1) {
-}
-
-void FragmentTexColorMatrixAlphaBinding::Init(GLES2Interface* context,
-                                              unsigned program,
-                                              int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  alpha_location_ = locations[1];
-  color_matrix_location_ = locations[2];
-  color_offset_location_ = locations[3];
-  BLEND_MODE_SET_LOCATIONS(locations, 4);
-}
-
-FragmentTexOpaqueBinding::FragmentTexOpaqueBinding() : sampler_location_(-1) {
-}
-
-void FragmentTexOpaqueBinding::Init(GLES2Interface* context,
-                                    unsigned program,
-                                    int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-}
-
-std::string FragmentShaderRGBATexAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-  });
-}
-
-std::string FragmentShaderRGBATexAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlpha::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->alpha = alpha_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-}
-
-std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-    uniform mat4 colorMatrix;
-    uniform vec4 colorOffset;
-  });
-}
-
-std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      float nonZeroAlpha = max(texColor.a, 0.00001);
-      texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
-      texColor = colorMatrix * texColor + colorOffset;
-      texColor.rgb *= texColor.a;
-      texColor = clamp(texColor, 0.0, 1.0);
-      gl_FragColor = ApplyBlendMode(texColor * alpha, 0.0);
-    }
-  });
-}
-
-void FragmentShaderRGBATexColorMatrixAlpha::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->alpha = alpha_location();
-  locations->color_matrix = color_matrix_location();
-  locations->color_offset = color_offset_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-}
-
-std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexVaryingAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_alpha;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderRGBATexVaryingAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      gl_FragColor = texColor * v_alpha;
-    }
-  });
-}
-
-std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_alpha;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      texColor.rgb *= texColor.a;
-      gl_FragColor = texColor * v_alpha;
-    }
-  });
-}
-
-FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
-    : background_color_location_(-1), sampler_location_(-1) {
-}
-
-void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
-                                        unsigned program,
-                                        int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "background_color",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-
-  sampler_location_ = locations[0];
-  DCHECK_NE(sampler_location_, -1);
-
-  background_color_location_ = locations[1];
-  DCHECK_NE(background_color_location_, -1);
-}
-
-std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_alpha;
-    uniform vec4 background_color;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      texColor += background_color * (1.0 - texColor.a);
-      gl_FragColor = texColor * v_alpha;
-    }
-  });
-}
-
-std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_alpha;
-    uniform vec4 background_color;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderTexBackgroundPremultiplyAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      texColor.rgb *= texColor.a;
-      texColor += background_color * (1.0 - texColor.a);
-      gl_FragColor = texColor * v_alpha;
-    }
-  });
-}
-
-std::string FragmentShaderRGBATexOpaque::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexOpaque::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderRGBATexOpaque::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      gl_FragColor = vec4(texColor.rgb, 1.0);
-    }
-  });
-}
-
-std::string FragmentShaderRGBATex::GetShaderString(TexCoordPrecision precision,
-                                                   SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATex::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderRGBATex::GetShaderBody() {
-  return SHADER0([]() {
-    void main() { gl_FragColor = TextureLookup(s_texture, v_texCoord); }
-  });
-}
-
-std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-  });
-}
-
-std::string FragmentShaderRGBATexSwizzleAlpha::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      gl_FragColor =
-          vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha;
-    }
-  });
-}
-
-std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-  });
-}
-
-std::string FragmentShaderRGBATexSwizzleOpaque::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      gl_FragColor = vec4(texColor.z, texColor.y, texColor.x, 1.0);
-    }
-  });
-}
-
-FragmentShaderRGBATexAlphaAA::FragmentShaderRGBATexAlphaAA()
-    : sampler_location_(-1), alpha_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaAA::Init(GLES2Interface* context,
-                                        unsigned program,
-                                        int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "alpha", BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  alpha_location_ = locations[1];
-  BLEND_MODE_SET_LOCATIONS(locations, 2);
-}
-
-std::string FragmentShaderRGBATexAlphaAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaAA::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->alpha = alpha_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-}
-
-FragmentTexClampAlphaAABinding::FragmentTexClampAlphaAABinding()
-    : sampler_location_(-1),
-      alpha_location_(-1),
-      fragment_tex_transform_location_(-1) {
-}
-
-void FragmentTexClampAlphaAABinding::Init(GLES2Interface* context,
-                                          unsigned program,
-                                          int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "alpha", "fragmentTexTransform",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  alpha_location_ = locations[1];
-  fragment_tex_transform_location_ = locations[2];
-}
-
-std::string FragmentShaderRGBATexClampAlphaAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexClampAlphaAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-    uniform TexCoordPrecision vec4 fragmentTexTransform;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexClampAlphaAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      TexCoordPrecision vec2 texCoord =
-          clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
-          fragmentTexTransform.xy;
-      vec4 texColor = TextureLookup(s_texture, texCoord);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = texColor * alpha * aa;
-    }
-  });
-}
-
-std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-    uniform TexCoordPrecision vec4 fragmentTexTransform;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexClampSwizzleAlphaAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      TexCoordPrecision vec2 texCoord =
-          clamp(v_texCoord, 0.0, 1.0) * fragmentTexTransform.zw +
-          fragmentTexTransform.xy;
-      vec4 texColor = TextureLookup(s_texture, texCoord);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor =
-          vec4(texColor.z, texColor.y, texColor.x, texColor.w) * alpha * aa;
-    }
-  });
-}
-
-FragmentShaderRGBATexAlphaMask::FragmentShaderRGBATexAlphaMask()
-    : sampler_location_(-1),
-      mask_sampler_location_(-1),
-      alpha_location_(-1),
-      mask_tex_coord_scale_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaMask::Init(GLES2Interface* context,
-                                          unsigned program,
-                                          int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture",
-      "s_mask",
-      "alpha",
-      "maskTexCoordScale",
-      "maskTexCoordOffset",
-      BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  mask_sampler_location_ = locations[1];
-  alpha_location_ = locations[2];
-  mask_tex_coord_scale_location_ = locations[3];
-  mask_tex_coord_offset_location_ = locations[4];
-  BLEND_MODE_SET_LOCATIONS(locations, 5);
-}
-
-std::string FragmentShaderRGBATexAlphaMask::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaMask::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform sampler2D s_texture;
-    uniform SamplerType s_mask;
-    uniform TexCoordPrecision vec2 maskTexCoordScale;
-    uniform TexCoordPrecision vec2 maskTexCoordOffset;
-    uniform float alpha;
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaMask::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = texture2D(s_texture, v_texCoord);
-      TexCoordPrecision vec2 maskTexCoord =
-          vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
-               maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
-      vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-      gl_FragColor = ApplyBlendMode(
-          texColor * alpha * maskColor.w, maskColor.w);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaMask::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->mask_sampler = mask_sampler_location();
-  locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
-  locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
-  locations->alpha = alpha_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-  if (mask_for_background())
-    locations->original_backdrop = original_backdrop_location();
-}
-
-FragmentShaderRGBATexAlphaMaskAA::FragmentShaderRGBATexAlphaMaskAA()
-    : sampler_location_(-1),
-      mask_sampler_location_(-1),
-      alpha_location_(-1),
-      mask_tex_coord_scale_location_(-1),
-      mask_tex_coord_offset_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaMaskAA::Init(GLES2Interface* context,
-                                            unsigned program,
-                                            int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture",
-      "s_mask",
-      "alpha",
-      "maskTexCoordScale",
-      "maskTexCoordOffset",
-      BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  mask_sampler_location_ = locations[1];
-  alpha_location_ = locations[2];
-  mask_tex_coord_scale_location_ = locations[3];
-  mask_tex_coord_offset_location_ = locations[4];
-  BLEND_MODE_SET_LOCATIONS(locations, 5);
-}
-
-std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform sampler2D s_texture;
-    uniform SamplerType s_mask;
-    uniform TexCoordPrecision vec2 maskTexCoordScale;
-    uniform TexCoordPrecision vec2 maskTexCoordOffset;
-    uniform float alpha;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = texture2D(s_texture, v_texCoord);
-      TexCoordPrecision vec2 maskTexCoord =
-          vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
-               maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
-      vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = ApplyBlendMode(
-          texColor * alpha * maskColor.w * aa, maskColor.w);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaMaskAA::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->mask_sampler = mask_sampler_location();
-  locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
-  locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
-  locations->alpha = alpha_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-  if (mask_for_background())
-    locations->original_backdrop = original_backdrop_location();
-}
-
-FragmentShaderRGBATexAlphaMaskColorMatrixAA::
-    FragmentShaderRGBATexAlphaMaskColorMatrixAA()
-    : sampler_location_(-1),
-      mask_sampler_location_(-1),
-      alpha_location_(-1),
-      mask_tex_coord_scale_location_(-1),
-      color_matrix_location_(-1),
-      color_offset_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
-    GLES2Interface* context,
-    unsigned program,
-    int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture",
-      "s_mask",
-      "alpha",
-      "maskTexCoordScale",
-      "maskTexCoordOffset",
-      "colorMatrix",
-      "colorOffset",
-      BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  mask_sampler_location_ = locations[1];
-  alpha_location_ = locations[2];
-  mask_tex_coord_scale_location_ = locations[3];
-  mask_tex_coord_offset_location_ = locations[4];
-  color_matrix_location_ = locations[5];
-  color_offset_location_ = locations[6];
-  BLEND_MODE_SET_LOCATIONS(locations, 7);
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform sampler2D s_texture;
-    uniform SamplerType s_mask;
-    uniform vec2 maskTexCoordScale;
-    uniform vec2 maskTexCoordOffset;
-    uniform mat4 colorMatrix;
-    uniform vec4 colorOffset;
-    uniform float alpha;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = texture2D(s_texture, v_texCoord);
-      float nonZeroAlpha = max(texColor.a, 0.00001);
-      texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
-      texColor = colorMatrix * texColor + colorOffset;
-      texColor.rgb *= texColor.a;
-      texColor = clamp(texColor, 0.0, 1.0);
-      TexCoordPrecision vec2 maskTexCoord =
-          vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
-               maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
-      vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = ApplyBlendMode(
-          texColor * alpha * maskColor.w * aa, maskColor.w);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaMaskColorMatrixAA::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->alpha = alpha_location();
-  locations->mask_sampler = mask_sampler_location();
-  locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
-  locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
-  locations->color_matrix = color_matrix_location();
-  locations->color_offset = color_offset_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-  if (mask_for_background())
-    locations->original_backdrop = original_backdrop_location();
-}
-
-FragmentShaderRGBATexAlphaColorMatrixAA::
-    FragmentShaderRGBATexAlphaColorMatrixAA()
-    : sampler_location_(-1),
-      alpha_location_(-1),
-      color_matrix_location_(-1),
-      color_offset_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaColorMatrixAA::Init(GLES2Interface* context,
-                                                   unsigned program,
-                                                   int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "alpha", "colorMatrix", "colorOffset", BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  alpha_location_ = locations[1];
-  color_matrix_location_ = locations[2];
-  color_offset_location_ = locations[3];
-  BLEND_MODE_SET_LOCATIONS(locations, 4);
-}
-
-std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform SamplerType s_texture;
-    uniform float alpha;
-    uniform mat4 colorMatrix;
-    uniform vec4 colorOffset;
-    varying TexCoordPrecision vec2 v_texCoord;
-    varying TexCoordPrecision vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = TextureLookup(s_texture, v_texCoord);
-      float nonZeroAlpha = max(texColor.a, 0.00001);
-      texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
-      texColor = colorMatrix * texColor + colorOffset;
-      texColor.rgb *= texColor.a;
-      texColor = clamp(texColor, 0.0, 1.0);
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = ApplyBlendMode(texColor * alpha * aa, 0.0);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaColorMatrixAA::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->alpha = alpha_location();
-  locations->color_matrix = color_matrix_location();
-  locations->color_offset = color_offset_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-}
-
-FragmentShaderRGBATexAlphaMaskColorMatrix::
-    FragmentShaderRGBATexAlphaMaskColorMatrix()
-    : sampler_location_(-1),
-      mask_sampler_location_(-1),
-      alpha_location_(-1),
-      mask_tex_coord_scale_location_(-1) {
-}
-
-void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(GLES2Interface* context,
-                                                     unsigned program,
-                                                     int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture",
-      "s_mask",
-      "alpha",
-      "maskTexCoordScale",
-      "maskTexCoordOffset",
-      "colorMatrix",
-      "colorOffset",
-      BLEND_MODE_UNIFORMS,
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms) - UNUSED_BLEND_MODE_UNIFORMS,
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  sampler_location_ = locations[0];
-  mask_sampler_location_ = locations[1];
-  alpha_location_ = locations[2];
-  mask_tex_coord_scale_location_ = locations[3];
-  mask_tex_coord_offset_location_ = locations[4];
-  color_matrix_location_ = locations[5];
-  color_offset_location_ = locations[6];
-  BLEND_MODE_SET_LOCATIONS(locations, 7);
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform sampler2D s_texture;
-    uniform SamplerType s_mask;
-    uniform vec2 maskTexCoordScale;
-    uniform vec2 maskTexCoordOffset;
-    uniform mat4 colorMatrix;
-    uniform vec4 colorOffset;
-    uniform float alpha;
-  });
-}
-
-std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 texColor = texture2D(s_texture, v_texCoord);
-      float nonZeroAlpha = max(texColor.a, 0.00001);
-      texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
-      texColor = colorMatrix * texColor + colorOffset;
-      texColor.rgb *= texColor.a;
-      texColor = clamp(texColor, 0.0, 1.0);
-      TexCoordPrecision vec2 maskTexCoord =
-          vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
-               maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
-      vec4 maskColor = TextureLookup(s_mask, maskTexCoord);
-      gl_FragColor = ApplyBlendMode(
-          texColor * alpha * maskColor.w, maskColor.w);
-    }
-  });
-}
-
-void FragmentShaderRGBATexAlphaMaskColorMatrix::FillLocations(
-    ShaderLocations* locations) const {
-  locations->sampler = sampler_location();
-  locations->mask_sampler = mask_sampler_location();
-  locations->mask_tex_coord_scale = mask_tex_coord_scale_location();
-  locations->mask_tex_coord_offset = mask_tex_coord_offset_location();
-  locations->alpha = alpha_location();
-  locations->color_matrix = color_matrix_location();
-  locations->color_offset = color_offset_location();
-  locations->backdrop = backdrop_location();
-  locations->backdrop_rect = backdrop_rect_location();
-  if (mask_for_background())
-    locations->original_backdrop = original_backdrop_location();
-}
-
-FragmentShaderYUVVideo::FragmentShaderYUVVideo()
-    : y_texture_location_(-1),
-      u_texture_location_(-1),
-      v_texture_location_(-1),
-      alpha_location_(-1),
-      yuv_matrix_location_(-1),
-      yuv_adj_location_(-1),
-      clamp_rect_location_(-1) {
-}
-
-void FragmentShaderYUVVideo::Init(GLES2Interface* context,
-                                  unsigned program,
-                                  int* base_uniform_index) {
-  static const char* uniforms[] = {"y_texture",
-                                   "u_texture",
-                                   "v_texture",
-                                   "alpha",
-                                   "yuv_matrix",
-                                   "yuv_adj",
-                                   "clamp_rect"};
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  y_texture_location_ = locations[0];
-  u_texture_location_ = locations[1];
-  v_texture_location_ = locations[2];
-  alpha_location_ = locations[3];
-  yuv_matrix_location_ = locations[4];
-  yuv_adj_location_ = locations[5];
-  clamp_rect_location_ = locations[6];
-}
-
-std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision,
-                                                    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderYUVVideo::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    precision mediump int;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType y_texture;
-    uniform SamplerType u_texture;
-    uniform SamplerType v_texture;
-    uniform float alpha;
-    uniform vec3 yuv_adj;
-    uniform mat3 yuv_matrix;
-    uniform vec4 clamp_rect;
-  });
-}
-
-std::string FragmentShaderYUVVideo::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord));
-      float y_raw = TextureLookup(y_texture, clamped).x;
-      float u_unsigned = TextureLookup(u_texture, clamped).x;
-      float v_unsigned = TextureLookup(v_texture, clamped).x;
-      vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
-      vec3 rgb = yuv_matrix * yuv;
-      gl_FragColor = vec4(rgb, 1.0) * alpha;
-    }
-  });
-}
-
-FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
-    : y_texture_location_(-1),
-      u_texture_location_(-1),
-      v_texture_location_(-1),
-      a_texture_location_(-1),
-      alpha_location_(-1),
-      yuv_matrix_location_(-1),
-      yuv_adj_location_(-1) {
-}
-
-void FragmentShaderYUVAVideo::Init(GLES2Interface* context,
-                                   unsigned program,
-                                   int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "y_texture",
-      "u_texture",
-      "v_texture",
-      "a_texture",
-      "alpha",
-      "cc_matrix",
-      "yuv_adj",
-      "clamp_rect",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  y_texture_location_ = locations[0];
-  u_texture_location_ = locations[1];
-  v_texture_location_ = locations[2];
-  a_texture_location_ = locations[3];
-  alpha_location_ = locations[4];
-  yuv_matrix_location_ = locations[5];
-  yuv_adj_location_ = locations[6];
-  clamp_rect_location_ = locations[7];
-}
-
-std::string FragmentShaderYUVAVideo::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderYUVAVideo::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    precision mediump int;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType y_texture;
-    uniform SamplerType u_texture;
-    uniform SamplerType v_texture;
-    uniform SamplerType a_texture;
-    uniform float alpha;
-    uniform vec3 yuv_adj;
-    uniform mat3 yuv_matrix;
-    uniform vec4 clamp_rect;
-  });
-}
-
-std::string FragmentShaderYUVAVideo::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 clamped = max(clamp_rect.xy, min(clamp_rect.zw, v_texCoord));
-      float y_raw = TextureLookup(y_texture, clamped).x;
-      float u_unsigned = TextureLookup(u_texture, clamped).x;
-      float v_unsigned = TextureLookup(v_texture, clamped).x;
-      float a_raw = TextureLookup(a_texture, clamped).x;
-      vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
-      vec3 rgb = yuv_matrix * yuv;
-      gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);
-    }
-  });
-}
-
-FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
-}
-
-void FragmentShaderColor::Init(GLES2Interface* context,
-                               unsigned program,
-                               int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "color",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  color_location_ = locations[0];
-}
-
-std::string FragmentShaderColor::GetShaderString(TexCoordPrecision precision,
-                                                 SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderColor::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform vec4 color;
-  });
-}
-
-std::string FragmentShaderColor::GetShaderBody() {
-  return SHADER0([]() {
-    void main() { gl_FragColor = color; }
-  });
-}
-
-FragmentShaderColorAA::FragmentShaderColorAA() : color_location_(-1) {
-}
-
-void FragmentShaderColorAA::Init(GLES2Interface* context,
-                                 unsigned program,
-                                 int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "color",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  color_location_ = locations[0];
-}
-
-std::string FragmentShaderColorAA::GetShaderString(TexCoordPrecision precision,
-                                                   SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderColorAA::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    uniform vec4 color;
-    varying vec4 edge_dist[2];  // 8 edge distances.
-  });
-}
-
-std::string FragmentShaderColorAA::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec4 d4 = min(edge_dist[0], edge_dist[1]);
-      vec2 d2 = min(d4.xz, d4.yw);
-      float aa = clamp(gl_FragCoord.w * min(d2.x, d2.y), 0.0, 1.0);
-      gl_FragColor = color * aa;
-    }
-  });
-}
-
-FragmentShaderCheckerboard::FragmentShaderCheckerboard()
-    : alpha_location_(-1),
-      tex_transform_location_(-1),
-      frequency_location_(-1) {
-}
-
-void FragmentShaderCheckerboard::Init(GLES2Interface* context,
-                                      unsigned program,
-                                      int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "alpha", "texTransform", "frequency", "color",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context,
-                             program,
-                             arraysize(uniforms),
-                             uniforms,
-                             locations,
-                             base_uniform_index);
-  alpha_location_ = locations[0];
-  tex_transform_location_ = locations[1];
-  frequency_location_ = locations[2];
-  color_location_ = locations[3];
-}
-
-std::string FragmentShaderCheckerboard::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderCheckerboard::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    precision mediump int;
-    varying vec2 v_texCoord;
-    uniform float alpha;
-    uniform float frequency;
-    uniform vec4 texTransform;
-    uniform vec4 color;
-  });
-}
-
-std::string FragmentShaderCheckerboard::GetShaderBody() {
-  // Shader based on Example 13-17 of "OpenGL ES 2.0 Programming Guide"
-  // by Munshi, Ginsburg, Shreiner.
-  return SHADER0([]() {
-    void main() {
-      vec4 color1 = vec4(1.0, 1.0, 1.0, 1.0);
-      vec4 color2 = color;
-      vec2 texCoord =
-          clamp(v_texCoord, 0.0, 1.0) * texTransform.zw + texTransform.xy;
-      vec2 coord = mod(floor(texCoord * frequency * 2.0), 2.0);
-      float picker = abs(coord.x - coord.y);  // NOLINT
-      gl_FragColor = mix(color1, color2, picker) * alpha;
-    }
-  });
-}
-
-}  // namespace cc
diff --git a/cc/output/shader.h b/cc/output/shader.h
deleted file mode 100644
index 5ccaa77..0000000
--- a/cc/output/shader.h
+++ /dev/null
@@ -1,887 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_OUTPUT_SHADER_H_
-#define CC_OUTPUT_SHADER_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-
-namespace gfx {
-class Point;
-class Size;
-}
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace cc {
-
-enum TexCoordPrecision {
-  TEX_COORD_PRECISION_NA = 0,
-  TEX_COORD_PRECISION_MEDIUM = 1,
-  TEX_COORD_PRECISION_HIGH = 2,
-  LAST_TEX_COORD_PRECISION = 2
-};
-
-enum SamplerType {
-  SAMPLER_TYPE_NA = 0,
-  SAMPLER_TYPE_2D = 1,
-  SAMPLER_TYPE_2D_RECT = 2,
-  SAMPLER_TYPE_EXTERNAL_OES = 3,
-  LAST_SAMPLER_TYPE = 3
-};
-
-enum BlendMode {
-  BLEND_MODE_NONE,
-  BLEND_MODE_NORMAL,
-  BLEND_MODE_SCREEN,
-  BLEND_MODE_OVERLAY,
-  BLEND_MODE_DARKEN,
-  BLEND_MODE_LIGHTEN,
-  BLEND_MODE_COLOR_DODGE,
-  BLEND_MODE_COLOR_BURN,
-  BLEND_MODE_HARD_LIGHT,
-  BLEND_MODE_SOFT_LIGHT,
-  BLEND_MODE_DIFFERENCE,
-  BLEND_MODE_EXCLUSION,
-  BLEND_MODE_MULTIPLY,
-  BLEND_MODE_HUE,
-  BLEND_MODE_SATURATION,
-  BLEND_MODE_COLOR,
-  BLEND_MODE_LUMINOSITY,
-  LAST_BLEND_MODE = BLEND_MODE_LUMINOSITY
-};
-
-enum MaskMode {
-  NO_MASK = 0,
-  HAS_MASK = 1,
-  LAST_MASK_VALUE = HAS_MASK
-};
-
-struct ShaderLocations {
-  ShaderLocations();
-
-  int sampler = -1;
-  int quad = -1;
-  int edge = -1;
-  int viewport = -1;
-  int mask_sampler = -1;
-  int mask_tex_coord_scale = -1;
-  int mask_tex_coord_offset = -1;
-  int matrix = -1;
-  int alpha = -1;
-  int color_matrix = -1;
-  int color_offset = -1;
-  int tex_transform = -1;
-  int backdrop = -1;
-  int backdrop_rect = -1;
-  int original_backdrop = -1;
-};
-
-// Note: The highp_threshold_cache must be provided by the caller to make
-// the caching multi-thread/context safe in an easy low-overhead manner.
-// The caller must make sure to clear highp_threshold_cache to 0, so it can be
-// reinitialized, if a new or different context is used.
-TexCoordPrecision TexCoordPrecisionRequired(gpu::gles2::GLES2Interface* context,
-                                            int* highp_threshold_cache,
-                                            int highp_threshold_min,
-                                            const gfx::Point& max_coordinate);
-
-TexCoordPrecision TexCoordPrecisionRequired(gpu::gles2::GLES2Interface* context,
-                                            int* highp_threshold_cache,
-                                            int highp_threshold_min,
-                                            const gfx::Size& max_size);
-
-class VertexShaderPosTex {
- public:
-  VertexShaderPosTex();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-
- private:
-  int matrix_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTex);
-};
-
-class VertexShaderPosTexYUVStretchOffset {
- public:
-  VertexShaderPosTexYUVStretchOffset();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int tex_scale_location() const { return tex_scale_location_; }
-  int tex_offset_location() const { return tex_offset_location_; }
-
- private:
-  int matrix_location_;
-  int tex_scale_location_;
-  int tex_offset_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTexYUVStretchOffset);
-};
-
-class VertexShaderPos {
- public:
-  VertexShaderPos();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-
- private:
-  int matrix_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderPos);
-};
-
-class VertexShaderPosTexIdentity {
- public:
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index) {}
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class VertexShaderPosTexTransform {
- public:
-  VertexShaderPosTexTransform();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-
-  int matrix_location() const { return matrix_location_; }
-  int tex_transform_location() const { return tex_transform_location_; }
-  int vertex_opacity_location() const { return vertex_opacity_location_; }
-
- private:
-  int matrix_location_;
-  int tex_transform_location_;
-  int vertex_opacity_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderPosTexTransform);
-};
-
-class VertexShaderQuad {
- public:
-  VertexShaderQuad();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-           unsigned program,
-           int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int viewport_location() const { return -1; }
-  int quad_location() const { return quad_location_; }
-  int edge_location() const { return -1; }
-
- private:
-  int matrix_location_;
-  int quad_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderQuad);
-};
-
-class VertexShaderQuadAA {
- public:
-  VertexShaderQuadAA();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-           unsigned program,
-           int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int viewport_location() const { return viewport_location_; }
-  int quad_location() const { return quad_location_; }
-  int edge_location() const { return edge_location_; }
-
- private:
-  int matrix_location_;
-  int viewport_location_;
-  int quad_location_;
-  int edge_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderQuadAA);
-};
-
-
-class VertexShaderQuadTexTransformAA {
- public:
-  VertexShaderQuadTexTransformAA();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-           unsigned program,
-           int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-
-  int matrix_location() const { return matrix_location_; }
-  int viewport_location() const { return viewport_location_; }
-  int quad_location() const { return quad_location_; }
-  int edge_location() const { return edge_location_; }
-  int tex_transform_location() const { return tex_transform_location_; }
-
- private:
-  int matrix_location_;
-  int viewport_location_;
-  int quad_location_;
-  int edge_location_;
-  int tex_transform_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderQuadTexTransformAA);
-};
-
-class VertexShaderTile {
- public:
-  VertexShaderTile();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int viewport_location() const { return -1; }
-  int quad_location() const { return quad_location_; }
-  int edge_location() const { return -1; }
-  int vertex_tex_transform_location() const {
-    return vertex_tex_transform_location_;
-  }
-
- private:
-  int matrix_location_;
-  int quad_location_;
-  int vertex_tex_transform_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderTile);
-};
-
-class VertexShaderTileAA {
- public:
-  VertexShaderTileAA();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int viewport_location() const { return viewport_location_; }
-  int quad_location() const { return quad_location_; }
-  int edge_location() const { return edge_location_; }
-  int vertex_tex_transform_location() const {
-    return vertex_tex_transform_location_;
-  }
-
- private:
-  int matrix_location_;
-  int viewport_location_;
-  int quad_location_;
-  int edge_location_;
-  int vertex_tex_transform_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderTileAA);
-};
-
-class VertexShaderVideoTransform {
- public:
-  VertexShaderVideoTransform();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString() const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  int matrix_location() const { return matrix_location_; }
-  int tex_matrix_location() const { return tex_matrix_location_; }
-
- private:
-  int matrix_location_;
-  int tex_matrix_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(VertexShaderVideoTransform);
-};
-
-class FragmentTexBlendMode {
- public:
-  int backdrop_location() const { return backdrop_location_; }
-  int original_backdrop_location() const { return original_backdrop_location_; }
-  int backdrop_rect_location() const { return backdrop_rect_location_; }
-
-  BlendMode blend_mode() const { return blend_mode_; }
-  void set_blend_mode(BlendMode blend_mode) { blend_mode_ = blend_mode; }
-  bool has_blend_mode() const { return blend_mode_ != BLEND_MODE_NONE; }
-  void set_mask_for_background(bool mask_for_background) {
-    mask_for_background_ = mask_for_background;
-  }
-  bool mask_for_background() const { return mask_for_background_; }
-
- protected:
-  FragmentTexBlendMode();
-
-  std::string SetBlendModeFunctions(std::string shader_string) const;
-
-  int backdrop_location_;
-  int original_backdrop_location_;
-  int backdrop_rect_location_;
-
- private:
-  BlendMode blend_mode_;
-  bool mask_for_background_;
-
-  std::string GetHelperFunctions() const;
-  std::string GetBlendFunction() const;
-  std::string GetBlendFunctionBodyForRGB() const;
-};
-
-class FragmentTexAlphaBinding : public FragmentTexBlendMode {
- public:
-  FragmentTexAlphaBinding();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int fragment_tex_transform_location() const { return -1; }
-  int sampler_location() const { return sampler_location_; }
-
- private:
-  int sampler_location_;
-  int alpha_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexAlphaBinding);
-};
-
-class FragmentTexColorMatrixAlphaBinding : public FragmentTexBlendMode {
- public:
-    FragmentTexColorMatrixAlphaBinding();
-
-    void Init(gpu::gles2::GLES2Interface* context,
-              unsigned program,
-              int* base_uniform_index);
-    int alpha_location() const { return alpha_location_; }
-    int color_matrix_location() const { return color_matrix_location_; }
-    int color_offset_location() const { return color_offset_location_; }
-    int fragment_tex_transform_location() const { return -1; }
-    int sampler_location() const { return sampler_location_; }
-
- private:
-    int sampler_location_;
-    int alpha_location_;
-    int color_matrix_location_;
-    int color_offset_location_;
-};
-
-class FragmentTexOpaqueBinding : public FragmentTexBlendMode {
- public:
-  FragmentTexOpaqueBinding();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return -1; }
-  int fragment_tex_transform_location() const { return -1; }
-  int background_color_location() const { return -1; }
-  int sampler_location() const { return sampler_location_; }
-
- private:
-  int sampler_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexOpaqueBinding);
-};
-
-class FragmentTexBackgroundBinding : public FragmentTexBlendMode {
- public:
-  FragmentTexBackgroundBinding();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int background_color_location() const { return background_color_location_; }
-  int sampler_location() const { return sampler_location_; }
-
- private:
-  int background_color_location_;
-  int sampler_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexBackgroundBinding);
-};
-
-class FragmentShaderRGBATexVaryingAlpha : public FragmentTexOpaqueBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATexPremultiplyAlpha : public FragmentTexOpaqueBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderTexBackgroundVaryingAlpha
-    : public FragmentTexBackgroundBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderTexBackgroundPremultiplyAlpha
-    : public FragmentTexBackgroundBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-};
-
-class FragmentShaderRGBATexColorMatrixAlpha
-    : public FragmentTexColorMatrixAlphaBinding {
- public:
-  std::string GetShaderString(TexCoordPrecision precision,
-                              SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-};
-
-class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATex : public FragmentTexOpaqueBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-// Swizzles the red and blue component of sampled texel with alpha.
-class FragmentShaderRGBATexSwizzleAlpha : public FragmentTexAlphaBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-// Swizzles the red and blue component of sampled texel without alpha.
-class FragmentShaderRGBATexSwizzleOpaque : public FragmentTexOpaqueBinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATexAlphaAA : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaAA();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-
- private:
-  int sampler_location_;
-  int alpha_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaAA);
-};
-
-class FragmentTexClampAlphaAABinding : public FragmentTexBlendMode {
- public:
-  FragmentTexClampAlphaAABinding();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int fragment_tex_transform_location() const {
-    return fragment_tex_transform_location_;
-  }
-
- private:
-  int sampler_location_;
-  int alpha_location_;
-  int fragment_tex_transform_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexClampAlphaAABinding);
-};
-
-class FragmentShaderRGBATexClampAlphaAA
-    : public FragmentTexClampAlphaAABinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-// Swizzles the red and blue component of sampled texel.
-class FragmentShaderRGBATexClampSwizzleAlphaAA
-    : public FragmentTexClampAlphaAABinding {
- public:
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATexAlphaMask : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaMask();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int mask_sampler_location() const { return mask_sampler_location_; }
-  int mask_tex_coord_scale_location() const {
-    return mask_tex_coord_scale_location_;
-  }
-  int mask_tex_coord_offset_location() const {
-    return mask_tex_coord_offset_location_;
-  }
-
- private:
-  int sampler_location_;
-  int mask_sampler_location_;
-  int alpha_location_;
-  int mask_tex_coord_scale_location_;
-  int mask_tex_coord_offset_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMask);
-};
-
-class FragmentShaderRGBATexAlphaMaskAA : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaMaskAA();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int mask_sampler_location() const { return mask_sampler_location_; }
-  int mask_tex_coord_scale_location() const {
-    return mask_tex_coord_scale_location_;
-  }
-  int mask_tex_coord_offset_location() const {
-    return mask_tex_coord_offset_location_;
-  }
-
- private:
-  int sampler_location_;
-  int mask_sampler_location_;
-  int alpha_location_;
-  int mask_tex_coord_scale_location_;
-  int mask_tex_coord_offset_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderRGBATexAlphaMaskAA);
-};
-
-class FragmentShaderRGBATexAlphaMaskColorMatrixAA
-    : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaMaskColorMatrixAA();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int mask_sampler_location() const { return mask_sampler_location_; }
-  int mask_tex_coord_scale_location() const {
-    return mask_tex_coord_scale_location_;
-  }
-  int mask_tex_coord_offset_location() const {
-    return mask_tex_coord_offset_location_;
-  }
-  int color_matrix_location() const { return color_matrix_location_; }
-  int color_offset_location() const { return color_offset_location_; }
-
- private:
-  int sampler_location_;
-  int mask_sampler_location_;
-  int alpha_location_;
-  int mask_tex_coord_scale_location_;
-  int mask_tex_coord_offset_location_;
-  int color_matrix_location_;
-  int color_offset_location_;
-};
-
-class FragmentShaderRGBATexAlphaColorMatrixAA : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaColorMatrixAA();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int color_matrix_location() const { return color_matrix_location_; }
-  int color_offset_location() const { return color_offset_location_; }
-
- private:
-  int sampler_location_;
-  int alpha_location_;
-  int color_matrix_location_;
-  int color_offset_location_;
-};
-
-class FragmentShaderRGBATexAlphaMaskColorMatrix : public FragmentTexBlendMode {
- public:
-  FragmentShaderRGBATexAlphaMaskColorMatrix();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-  void FillLocations(ShaderLocations* locations) const;
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int sampler_location() const { return sampler_location_; }
-  int mask_sampler_location() const { return mask_sampler_location_; }
-  int mask_tex_coord_scale_location() const {
-    return mask_tex_coord_scale_location_;
-  }
-  int mask_tex_coord_offset_location() const {
-    return mask_tex_coord_offset_location_;
-  }
-  int color_matrix_location() const { return color_matrix_location_; }
-  int color_offset_location() const { return color_offset_location_; }
-
- private:
-  int sampler_location_;
-  int mask_sampler_location_;
-  int alpha_location_;
-  int mask_tex_coord_scale_location_;
-  int mask_tex_coord_offset_location_;
-  int color_matrix_location_;
-  int color_offset_location_;
-};
-
-class FragmentShaderYUVVideo : public FragmentTexBlendMode {
- public:
-  FragmentShaderYUVVideo();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int y_texture_location() const { return y_texture_location_; }
-  int u_texture_location() const { return u_texture_location_; }
-  int v_texture_location() const { return v_texture_location_; }
-  int alpha_location() const { return alpha_location_; }
-  int yuv_matrix_location() const { return yuv_matrix_location_; }
-  int yuv_adj_location() const { return yuv_adj_location_; }
-  int clamp_rect_location() const { return clamp_rect_location_; }
-
- private:
-  int y_texture_location_;
-  int u_texture_location_;
-  int v_texture_location_;
-  int alpha_location_;
-  int yuv_matrix_location_;
-  int yuv_adj_location_;
-  int clamp_rect_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo);
-};
-
-class FragmentShaderYUVAVideo : public FragmentTexBlendMode {
- public:
-  FragmentShaderYUVAVideo();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-
-  int y_texture_location() const { return y_texture_location_; }
-  int u_texture_location() const { return u_texture_location_; }
-  int v_texture_location() const { return v_texture_location_; }
-  int a_texture_location() const { return a_texture_location_; }
-  int alpha_location() const { return alpha_location_; }
-  int yuv_matrix_location() const { return yuv_matrix_location_; }
-  int yuv_adj_location() const { return yuv_adj_location_; }
-  int clamp_rect_location() const { return clamp_rect_location_; }
-
- private:
-  int y_texture_location_;
-  int u_texture_location_;
-  int v_texture_location_;
-  int a_texture_location_;
-  int alpha_location_;
-  int yuv_matrix_location_;
-  int yuv_adj_location_;
-  int clamp_rect_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVAVideo);
-};
-
-class FragmentShaderColor : public FragmentTexBlendMode {
- public:
-  FragmentShaderColor();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int color_location() const { return color_location_; }
-
- private:
-  int color_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderColor);
-};
-
-class FragmentShaderColorAA : public FragmentTexBlendMode {
- public:
-  FragmentShaderColorAA();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int color_location() const { return color_location_; }
-
- private:
-  int color_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderColorAA);
-};
-
-class FragmentShaderCheckerboard : public FragmentTexBlendMode {
- public:
-  FragmentShaderCheckerboard();
-  std::string GetShaderString(
-      TexCoordPrecision precision, SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-
-  void Init(gpu::gles2::GLES2Interface* context,
-            unsigned program,
-            int* base_uniform_index);
-  int alpha_location() const { return alpha_location_; }
-  int tex_transform_location() const { return tex_transform_location_; }
-  int frequency_location() const { return frequency_location_; }
-  int color_location() const { return color_location_; }
-
- private:
-  int alpha_location_;
-  int tex_transform_location_;
-  int frequency_location_;
-  int color_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentShaderCheckerboard);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_SHADER_H_
diff --git a/cc/output/shader_unittest.cc b/cc/output/shader_unittest.cc
deleted file mode 100644
index 675e47f..0000000
--- a/cc/output/shader_unittest.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/shader.h"
-
-#include "cc/test/test_gles2_interface.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-TEST(ShaderTest, HighpThresholds) {
-  // The test context always uses a mediump precision of 10 bits which
-  // corresponds to a native highp threshold of 2^10 = 1024
-  scoped_ptr<TestWebGraphicsContext3D> stub_context =
-    TestWebGraphicsContext3D::Create();
-  TestGLES2Interface stub_gl(stub_context.get());
-
-  int threshold_cache = 0;
-  int threshold_min;
-  gfx::Point closePoint(512, 512);
-  gfx::Size smallSize(512, 512);
-  gfx::Point farPoint(2560, 2560);
-  gfx::Size bigSize(2560, 2560);
-
-  threshold_min = 0;
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      closePoint));
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      smallSize));
-  EXPECT_EQ(TEX_COORD_PRECISION_HIGH,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      farPoint));
-  EXPECT_EQ(TEX_COORD_PRECISION_HIGH,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      bigSize));
-
-  threshold_min = 3000;
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      closePoint));
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      smallSize));
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      farPoint));
-  EXPECT_EQ(TEX_COORD_PRECISION_MEDIUM,
-            TexCoordPrecisionRequired(&stub_gl, &threshold_cache, threshold_min,
-                                      bigSize));
-}
-
-}  // namespace cc
diff --git a/cc/output/software_frame_data.cc b/cc/output/software_frame_data.cc
deleted file mode 100644
index 7fc380e..0000000
--- a/cc/output/software_frame_data.cc
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/software_frame_data.h"
-
-namespace cc {
-
-SoftwareFrameData::SoftwareFrameData() : id(0) {}
-
-SoftwareFrameData::~SoftwareFrameData() {}
-
-}  // namespace cc
diff --git a/cc/output/software_frame_data.h b/cc/output/software_frame_data.h
deleted file mode 100644
index 59df7a9..0000000
--- a/cc/output/software_frame_data.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_OUTPUT_SOFTWARE_FRAME_DATA_H_
-#define CC_OUTPUT_SOFTWARE_FRAME_DATA_H_
-
-#include "cc/resources/shared_bitmap.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class SoftwareFrameData {
- public:
-  SoftwareFrameData();
-  ~SoftwareFrameData();
-
-  unsigned id;
-  gfx::Size size;
-  gfx::Rect damage_rect;
-  SharedBitmapId bitmap_id;
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_SOFTWARE_FRAME_DATA_H_
diff --git a/cc/output/software_output_device.cc b/cc/output/software_output_device.cc
deleted file mode 100644
index f7bc61a..0000000
--- a/cc/output/software_output_device.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/software_output_device.h"
-
-#include "base/logging.h"
-#include "cc/output/software_frame_data.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/vsync_provider.h"
-
-namespace cc {
-
-SoftwareOutputDevice::SoftwareOutputDevice() : scale_factor_(1.f) {
-}
-
-SoftwareOutputDevice::~SoftwareOutputDevice() {}
-
-void SoftwareOutputDevice::Resize(const gfx::Size& viewport_pixel_size,
-                                  float scale_factor) {
-  scale_factor_ = scale_factor;
-
-  if (viewport_pixel_size_ == viewport_pixel_size)
-    return;
-
-  SkImageInfo info = SkImageInfo::MakeN32(viewport_pixel_size.width(),
-                                          viewport_pixel_size.height(),
-                                          kOpaque_SkAlphaType);
-  viewport_pixel_size_ = viewport_pixel_size;
-  surface_ = skia::AdoptRef(SkSurface::NewRaster(info));
-}
-
-SkCanvas* SoftwareOutputDevice::BeginPaint(const gfx::Rect& damage_rect) {
-  DCHECK(surface_);
-  damage_rect_ = damage_rect;
-  return surface_->getCanvas();
-}
-
-void SoftwareOutputDevice::EndPaint(SoftwareFrameData* frame_data) {
-  DCHECK(frame_data);
-  frame_data->id = 0;
-  frame_data->size = viewport_pixel_size_;
-  frame_data->damage_rect = damage_rect_;
-}
-
-void SoftwareOutputDevice::CopyToPixels(const gfx::Rect& rect, void* pixels) {
-  DCHECK(surface_);
-  SkImageInfo info = SkImageInfo::MakeN32Premul(rect.width(), rect.height());
-  surface_->getCanvas()->readPixels(info, pixels, info.minRowBytes(), rect.x(),
-                                    rect.y());
-}
-
-void SoftwareOutputDevice::Scroll(const gfx::Vector2d& delta,
-                                  const gfx::Rect& clip_rect) {
-  NOTIMPLEMENTED();
-}
-
-void SoftwareOutputDevice::ReclaimSoftwareFrame(unsigned id) {
-  NOTIMPLEMENTED();
-}
-
-gfx::VSyncProvider* SoftwareOutputDevice::GetVSyncProvider() {
-  return vsync_provider_.get();
-}
-
-}  // namespace cc
diff --git a/cc/output/software_output_device.h b/cc/output/software_output_device.h
deleted file mode 100644
index 1176ee6..0000000
--- a/cc/output/software_output_device.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_SOFTWARE_OUTPUT_DEVICE_H_
-#define CC_OUTPUT_SOFTWARE_OUTPUT_DEVICE_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkSurface.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-class SkBitmap;
-class SkCanvas;
-
-namespace gfx {
-class VSyncProvider;
-}
-
-namespace cc {
-
-class SoftwareFrameData;
-
-// This is a "tear-off" class providing software drawing support to
-// OutputSurface, such as to a platform-provided window framebuffer.
-class SoftwareOutputDevice {
- public:
-  SoftwareOutputDevice();
-  virtual ~SoftwareOutputDevice();
-
-  // Discards any pre-existing backing buffers and allocates memory for a
-  // software device of |size|. This must be called before the
-  // |SoftwareOutputDevice| can be used in other ways.
-  virtual void Resize(const gfx::Size& pixel_size, float scale_factor);
-
-  // Called on BeginDrawingFrame. The compositor will draw into the returned
-  // SkCanvas. The |SoftwareOutputDevice| implementation needs to provide a
-  // valid SkCanvas of at least size |damage_rect|. This class retains ownership
-  // of the SkCanvas.
-  virtual SkCanvas* BeginPaint(const gfx::Rect& damage_rect);
-
-  // Called on FinishDrawingFrame. The compositor will no longer mutate the the
-  // SkCanvas instance returned by |BeginPaint| and should discard any reference
-  // that it holds to it.
-  virtual void EndPaint(SoftwareFrameData* frame_data);
-
-  // Copies pixels inside |rect| from the current software framebuffer to
-  // |pixels|. Fails if there is no current softwareframebuffer.
-  virtual void CopyToPixels(const gfx::Rect& rect, void* pixels);
-
-  // Blit the pixel content of the SoftwareOutputDevice by |delta| with the
-  // write clipped to |clip_rect|.
-  virtual void Scroll(const gfx::Vector2d& delta, const gfx::Rect& clip_rect);
-
-  // Discard the backing buffer in the surface provided by this instance.
-  virtual void DiscardBackbuffer() {}
-
-  // Ensures that there is a backing buffer available on this instance.
-  virtual void EnsureBackbuffer() {}
-
-  // TODO(skaslev) Remove this after UberCompositor lands.
-  // Called in response to receiving a SwapBuffersAck. At this point, software
-  // frame identified by id can be reused or discarded as it is no longer being
-  // displayed.
-  virtual void ReclaimSoftwareFrame(unsigned id);
-
-  // VSyncProvider used to update the timer used to schedule draws with the
-  // hardware vsync. Return NULL if a provider doesn't exist.
-  virtual gfx::VSyncProvider* GetVSyncProvider();
-
- protected:
-  gfx::Size viewport_pixel_size_;
-  float scale_factor_;
-  gfx::Rect damage_rect_;
-  skia::RefPtr<SkSurface> surface_;
-  scoped_ptr<gfx::VSyncProvider> vsync_provider_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SoftwareOutputDevice);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_SOFTWARE_OUTPUT_DEVICE_H_
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc
deleted file mode 100644
index 5d9a69c..0000000
--- a/cc/output/software_renderer.cc
+++ /dev/null
@@ -1,629 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/software_renderer.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/base/math_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/render_surface_filters.h"
-#include "cc/output/software_output_device.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "skia/ext/opacity_draw_filter.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "third_party/skia/include/core/SkMatrix.h"
-#include "third_party/skia/include/core/SkPath.h"
-#include "third_party/skia/include/core/SkPoint.h"
-#include "third_party/skia/include/core/SkShader.h"
-#include "third_party/skia/include/effects/SkLayerRasterizer.h"
-#include "ui/gfx/geometry/rect_conversions.h"
-#include "ui/gfx/skia_util.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-static inline bool IsScalarNearlyInteger(SkScalar scalar) {
-  return SkScalarNearlyZero(scalar - SkScalarRoundToScalar(scalar));
-}
-
-bool IsScaleAndIntegerTranslate(const SkMatrix& matrix) {
-  return IsScalarNearlyInteger(matrix[SkMatrix::kMTransX]) &&
-         IsScalarNearlyInteger(matrix[SkMatrix::kMTransY]) &&
-         SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) &&
-         SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) &&
-         SkScalarNearlyZero(matrix[SkMatrix::kMPersp0]) &&
-         SkScalarNearlyZero(matrix[SkMatrix::kMPersp1]) &&
-         SkScalarNearlyZero(matrix[SkMatrix::kMPersp2] - 1.0f);
-}
-
-static SkShader::TileMode WrapModeToTileMode(GLint wrap_mode) {
-  switch (wrap_mode) {
-    case GL_REPEAT:
-      return SkShader::kRepeat_TileMode;
-    case GL_CLAMP_TO_EDGE:
-      return SkShader::kClamp_TileMode;
-  }
-  NOTREACHED();
-  return SkShader::kClamp_TileMode;
-}
-
-}  // anonymous namespace
-
-scoped_ptr<SoftwareRenderer> SoftwareRenderer::Create(
-    RendererClient* client,
-    const RendererSettings* settings,
-    OutputSurface* output_surface,
-    ResourceProvider* resource_provider) {
-  return make_scoped_ptr(new SoftwareRenderer(
-      client, settings, output_surface, resource_provider));
-}
-
-SoftwareRenderer::SoftwareRenderer(RendererClient* client,
-                                   const RendererSettings* settings,
-                                   OutputSurface* output_surface,
-                                   ResourceProvider* resource_provider)
-    : DirectRenderer(client, settings, output_surface, resource_provider),
-      is_scissor_enabled_(false),
-      is_backbuffer_discarded_(false),
-      output_device_(output_surface->software_device()),
-      current_canvas_(NULL) {
-  if (resource_provider_) {
-    capabilities_.max_texture_size = resource_provider_->max_texture_size();
-    capabilities_.best_texture_format =
-        resource_provider_->best_texture_format();
-  }
-  // The updater can access bitmaps while the SoftwareRenderer is using them.
-  capabilities_.allow_partial_texture_updates = true;
-  capabilities_.using_partial_swap = true;
-
-  capabilities_.using_shared_memory_resources = true;
-
-  capabilities_.allow_rasterize_on_demand = true;
-}
-
-SoftwareRenderer::~SoftwareRenderer() {}
-
-const RendererCapabilitiesImpl& SoftwareRenderer::Capabilities() const {
-  return capabilities_;
-}
-
-void SoftwareRenderer::BeginDrawingFrame(DrawingFrame* frame) {
-  TRACE_EVENT0("cc", "SoftwareRenderer::BeginDrawingFrame");
-  root_canvas_ = output_device_->BeginPaint(
-      gfx::ToEnclosingRect(frame->root_damage_rect));
-}
-
-void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) {
-  TRACE_EVENT0("cc", "SoftwareRenderer::FinishDrawingFrame");
-  current_framebuffer_lock_ = nullptr;
-  current_framebuffer_canvas_.clear();
-  current_canvas_ = NULL;
-  root_canvas_ = NULL;
-
-  current_frame_data_.reset(new SoftwareFrameData);
-  output_device_->EndPaint(current_frame_data_.get());
-}
-
-void SoftwareRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) {
-  TRACE_EVENT0("cc,benchmark", "SoftwareRenderer::SwapBuffers");
-  CompositorFrame compositor_frame;
-  compositor_frame.metadata = metadata;
-  compositor_frame.software_frame_data = current_frame_data_.Pass();
-  output_surface_->SwapBuffers(&compositor_frame);
-}
-
-void SoftwareRenderer::ReceiveSwapBuffersAck(const CompositorFrameAck& ack) {
-  output_device_->ReclaimSoftwareFrame(ack.last_software_frame_id);
-}
-
-bool SoftwareRenderer::FlippedFramebuffer(const DrawingFrame* frame) const {
-  return false;
-}
-
-void SoftwareRenderer::EnsureScissorTestEnabled() {
-  is_scissor_enabled_ = true;
-  SetClipRect(scissor_rect_);
-}
-
-void SoftwareRenderer::EnsureScissorTestDisabled() {
-  // There is no explicit notion of enabling/disabling scissoring in software
-  // rendering, but the underlying effect we want is to clear any existing
-  // clipRect on the current SkCanvas. This is done by setting clipRect to
-  // the viewport's dimensions.
-  is_scissor_enabled_ = false;
-  SkISize size = current_canvas_->getDeviceSize();
-  SetClipRect(gfx::Rect(size.width(), size.height()));
-}
-
-void SoftwareRenderer::Finish() {}
-
-void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) {
-  DCHECK(!output_surface_->HasExternalStencilTest());
-  current_framebuffer_lock_ = nullptr;
-  current_framebuffer_canvas_.clear();
-  current_canvas_ = root_canvas_;
-}
-
-bool SoftwareRenderer::BindFramebufferToTexture(
-    DrawingFrame* frame,
-    const ScopedResource* texture,
-    const gfx::Rect& target_rect) {
-  DCHECK(texture->id());
-
-  // Explicitly release lock, otherwise we can crash when try to lock
-  // same texture again.
-  current_framebuffer_lock_ = nullptr;
-  current_framebuffer_lock_ = make_scoped_ptr(
-      new ResourceProvider::ScopedWriteLockSoftware(
-          resource_provider_, texture->id()));
-  current_framebuffer_canvas_ =
-      skia::AdoptRef(new SkCanvas(current_framebuffer_lock_->sk_bitmap()));
-  current_canvas_ = current_framebuffer_canvas_.get();
-  return true;
-}
-
-void SoftwareRenderer::SetScissorTestRect(const gfx::Rect& scissor_rect) {
-  is_scissor_enabled_ = true;
-  scissor_rect_ = scissor_rect;
-  SetClipRect(scissor_rect);
-}
-
-void SoftwareRenderer::SetClipRect(const gfx::Rect& rect) {
-  // Skia applies the current matrix to clip rects so we reset it temporary.
-  SkMatrix current_matrix = current_canvas_->getTotalMatrix();
-  current_canvas_->resetMatrix();
-  current_canvas_->clipRect(gfx::RectToSkRect(rect), SkRegion::kReplace_Op);
-  current_canvas_->setMatrix(current_matrix);
-}
-
-void SoftwareRenderer::ClearCanvas(SkColor color) {
-  // SkCanvas::clear doesn't respect the current clipping region
-  // so we SkCanvas::drawColor instead if scissoring is active.
-  if (is_scissor_enabled_)
-    current_canvas_->drawColor(color, SkXfermode::kSrc_Mode);
-  else
-    current_canvas_->clear(color);
-}
-
-void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) {
-  if (frame->current_render_pass->has_transparent_background) {
-    ClearCanvas(SkColorSetARGB(0, 0, 0, 0));
-  } else {
-#ifndef NDEBUG
-    // On DEBUG builds, opaque render passes are cleared to blue
-    // to easily see regions that were not drawn on the screen.
-    ClearCanvas(SkColorSetARGB(255, 0, 0, 255));
-#endif
-  }
-}
-
-void SoftwareRenderer::PrepareSurfaceForPass(
-    DrawingFrame* frame,
-    SurfaceInitializationMode initialization_mode,
-    const gfx::Rect& render_pass_scissor) {
-  switch (initialization_mode) {
-    case SURFACE_INITIALIZATION_MODE_PRESERVE:
-      EnsureScissorTestDisabled();
-      return;
-    case SURFACE_INITIALIZATION_MODE_FULL_SURFACE_CLEAR:
-      EnsureScissorTestDisabled();
-      ClearFramebuffer(frame);
-      break;
-    case SURFACE_INITIALIZATION_MODE_SCISSORED_CLEAR:
-      SetScissorTestRect(render_pass_scissor);
-      ClearFramebuffer(frame);
-      break;
-  }
-}
-
-void SoftwareRenderer::SetDrawViewport(
-    const gfx::Rect& window_space_viewport) {}
-
-bool SoftwareRenderer::IsSoftwareResource(
-    ResourceProvider::ResourceId resource_id) const {
-  switch (resource_provider_->GetResourceType(resource_id)) {
-    case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE:
-      return false;
-    case ResourceProvider::RESOURCE_TYPE_BITMAP:
-      return true;
-    case ResourceProvider::RESOURCE_TYPE_INVALID:
-      break;
-  }
-
-  LOG(FATAL) << "Invalid resource type.";
-  return false;
-}
-
-void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame,
-                                  const DrawQuad* quad,
-                                  const gfx::QuadF* draw_region) {
-  if (draw_region) {
-    current_canvas_->save();
-  }
-
-  TRACE_EVENT0("cc", "SoftwareRenderer::DoDrawQuad");
-  gfx::Transform quad_rect_matrix;
-  QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect);
-  gfx::Transform contents_device_transform =
-      frame->window_matrix * frame->projection_matrix * quad_rect_matrix;
-  contents_device_transform.FlattenTo2d();
-  SkMatrix sk_device_matrix;
-  gfx::TransformToFlattenedSkMatrix(contents_device_transform,
-                                    &sk_device_matrix);
-  current_canvas_->setMatrix(sk_device_matrix);
-
-  current_paint_.reset();
-  if (settings_->force_antialiasing ||
-      !IsScaleAndIntegerTranslate(sk_device_matrix)) {
-    // TODO(danakj): Until we can enable AA only on exterior edges of the
-    // layer, disable AA if any interior edges are present. crbug.com/248175
-    bool all_four_edges_are_exterior = quad->IsTopEdge() &&
-                                       quad->IsLeftEdge() &&
-                                       quad->IsBottomEdge() &&
-                                       quad->IsRightEdge();
-    if (settings_->allow_antialiasing &&
-        (settings_->force_antialiasing || all_four_edges_are_exterior))
-      current_paint_.setAntiAlias(true);
-    current_paint_.setFilterQuality(kLow_SkFilterQuality);
-  }
-
-  if (quad->ShouldDrawWithBlending() ||
-      quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) {
-    current_paint_.setAlpha(quad->opacity() * 255);
-    current_paint_.setXfermodeMode(quad->shared_quad_state->blend_mode);
-  } else {
-    current_paint_.setXfermodeMode(SkXfermode::kSrc_Mode);
-  }
-
-  if (draw_region) {
-    gfx::QuadF local_draw_region(*draw_region);
-    SkPath draw_region_clip_path;
-    local_draw_region -=
-        gfx::Vector2dF(quad->visible_rect.x(), quad->visible_rect.y());
-    local_draw_region.Scale(1.0f / quad->visible_rect.width(),
-                            1.0f / quad->visible_rect.height());
-    local_draw_region -= gfx::Vector2dF(0.5f, 0.5f);
-
-    SkPoint clip_points[4];
-    QuadFToSkPoints(local_draw_region, clip_points);
-    draw_region_clip_path.addPoly(clip_points, 4, true);
-
-    current_canvas_->clipPath(draw_region_clip_path, SkRegion::kIntersect_Op,
-                              false);
-  }
-
-  switch (quad->material) {
-    case DrawQuad::CHECKERBOARD:
-      // TODO(enne) For now since checkerboards shouldn't be part of a 3D
-      // context, clipping regions aren't supported so we skip drawing them
-      // if this becomes the case.
-      if (!draw_region) {
-        DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad));
-      }
-      break;
-    case DrawQuad::DEBUG_BORDER:
-      DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::RENDER_PASS:
-      DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::SOLID_COLOR:
-      DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::TEXTURE_CONTENT:
-      DrawTextureQuad(frame, TextureDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::TILED_CONTENT:
-      DrawTileQuad(frame, TileDrawQuad::MaterialCast(quad));
-      break;
-    case DrawQuad::SURFACE_CONTENT:
-      // Surface content should be fully resolved to other quad types before
-      // reaching a direct renderer.
-      NOTREACHED();
-      break;
-    case DrawQuad::INVALID:
-    case DrawQuad::IO_SURFACE_CONTENT:
-    case DrawQuad::YUV_VIDEO_CONTENT:
-    case DrawQuad::STREAM_VIDEO_CONTENT:
-    case DrawQuad::UNUSED_SPACE_FOR_PICTURE_CONTENT:
-      DrawUnsupportedQuad(frame, quad);
-      NOTREACHED();
-      break;
-  }
-
-  current_canvas_->resetMatrix();
-  if (draw_region) {
-    current_canvas_->restore();
-  }
-}
-
-void SoftwareRenderer::DrawCheckerboardQuad(const DrawingFrame* frame,
-                                            const CheckerboardDrawQuad* quad) {
-  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
-      QuadVertexRect(), quad->rect, quad->visible_rect);
-  current_paint_.setColor(quad->color);
-  current_paint_.setAlpha(quad->opacity());
-  current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
-                            current_paint_);
-}
-
-void SoftwareRenderer::DrawDebugBorderQuad(const DrawingFrame* frame,
-                                           const DebugBorderDrawQuad* quad) {
-  // We need to apply the matrix manually to have pixel-sized stroke width.
-  SkPoint vertices[4];
-  gfx::RectFToSkRect(QuadVertexRect()).toQuad(vertices);
-  SkPoint transformed_vertices[4];
-  current_canvas_->getTotalMatrix().mapPoints(transformed_vertices,
-                                              vertices,
-                                              4);
-  current_canvas_->resetMatrix();
-
-  current_paint_.setColor(quad->color);
-  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
-  current_paint_.setStyle(SkPaint::kStroke_Style);
-  current_paint_.setStrokeWidth(quad->width);
-  current_canvas_->drawPoints(SkCanvas::kPolygon_PointMode,
-                              4, transformed_vertices, current_paint_);
-}
-
-void SoftwareRenderer::DrawSolidColorQuad(const DrawingFrame* frame,
-                                          const SolidColorDrawQuad* quad) {
-  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
-      QuadVertexRect(), quad->rect, quad->visible_rect);
-  current_paint_.setColor(quad->color);
-  current_paint_.setAlpha(quad->opacity() * SkColorGetA(quad->color));
-  current_canvas_->drawRect(gfx::RectFToSkRect(visible_quad_vertex_rect),
-                            current_paint_);
-}
-
-void SoftwareRenderer::DrawTextureQuad(const DrawingFrame* frame,
-                                       const TextureDrawQuad* quad) {
-  if (!IsSoftwareResource(quad->resource_id)) {
-    DrawUnsupportedQuad(frame, quad);
-    return;
-  }
-
-  // TODO(skaslev): Add support for non-premultiplied alpha.
-  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
-                                                quad->resource_id);
-  if (!lock.valid())
-    return;
-  const SkBitmap* bitmap = lock.sk_bitmap();
-  gfx::RectF uv_rect = gfx::ScaleRect(gfx::BoundingRect(quad->uv_top_left,
-                                                        quad->uv_bottom_right),
-                                      bitmap->width(),
-                                      bitmap->height());
-  gfx::RectF visible_uv_rect =
-      MathUtil::ScaleRectProportional(uv_rect, quad->rect, quad->visible_rect);
-  SkRect sk_uv_rect = gfx::RectFToSkRect(visible_uv_rect);
-  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
-      QuadVertexRect(), quad->rect, quad->visible_rect);
-  SkRect quad_rect = gfx::RectFToSkRect(visible_quad_vertex_rect);
-
-  if (quad->flipped)
-    current_canvas_->scale(1, -1);
-
-  bool blend_background = quad->background_color != SK_ColorTRANSPARENT &&
-                          !bitmap->isOpaque();
-  bool needs_layer = blend_background && (current_paint_.getAlpha() != 0xFF);
-  if (needs_layer) {
-    current_canvas_->saveLayerAlpha(&quad_rect, current_paint_.getAlpha());
-    current_paint_.setAlpha(0xFF);
-  }
-  if (blend_background) {
-    SkPaint background_paint;
-    background_paint.setColor(quad->background_color);
-    current_canvas_->drawRect(quad_rect, background_paint);
-  }
-  SkShader::TileMode tile_mode = WrapModeToTileMode(lock.wrap_mode());
-  if (tile_mode != SkShader::kClamp_TileMode) {
-    SkMatrix matrix;
-    matrix.setRectToRect(sk_uv_rect, quad_rect, SkMatrix::kFill_ScaleToFit);
-    skia::RefPtr<SkShader> shader = skia::AdoptRef(
-        SkShader::CreateBitmapShader(*bitmap, tile_mode, tile_mode, &matrix));
-    SkPaint paint;
-    paint.setStyle(SkPaint::kFill_Style);
-    paint.setShader(shader.get());
-    current_canvas_->drawRect(quad_rect, paint);
-  } else {
-    current_canvas_->drawBitmapRect(*bitmap, sk_uv_rect, quad_rect,
-                                    &current_paint_);
-  }
-
-  if (needs_layer)
-    current_canvas_->restore();
-}
-
-void SoftwareRenderer::DrawTileQuad(const DrawingFrame* frame,
-                                    const TileDrawQuad* quad) {
-  // |resource_provider_| can be NULL in resourceless software draws, which
-  // should never produce tile quads in the first place.
-  DCHECK(resource_provider_);
-  DCHECK(IsSoftwareResource(quad->resource_id));
-
-  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
-                                                quad->resource_id);
-  if (!lock.valid())
-    return;
-  DCHECK_EQ(GL_CLAMP_TO_EDGE, lock.wrap_mode());
-
-  gfx::RectF visible_tex_coord_rect = MathUtil::ScaleRectProportional(
-      quad->tex_coord_rect, quad->rect, quad->visible_rect);
-  gfx::RectF visible_quad_vertex_rect = MathUtil::ScaleRectProportional(
-      QuadVertexRect(), quad->rect, quad->visible_rect);
-
-  SkRect uv_rect = gfx::RectFToSkRect(visible_tex_coord_rect);
-  current_paint_.setFilterQuality(
-      quad->nearest_neighbor ? kNone_SkFilterQuality : kLow_SkFilterQuality);
-  current_canvas_->drawBitmapRect(*lock.sk_bitmap(), uv_rect,
-                                  gfx::RectFToSkRect(visible_quad_vertex_rect),
-                                  &current_paint_);
-}
-
-void SoftwareRenderer::DrawRenderPassQuad(const DrawingFrame* frame,
-                                          const RenderPassDrawQuad* quad) {
-  ScopedResource* content_texture =
-      render_pass_textures_.get(quad->render_pass_id);
-  if (!content_texture || !content_texture->id())
-    return;
-
-  DCHECK(IsSoftwareResource(content_texture->id()));
-  ResourceProvider::ScopedReadLockSoftware lock(resource_provider_,
-                                                content_texture->id());
-  if (!lock.valid())
-    return;
-  SkShader::TileMode content_tile_mode = WrapModeToTileMode(lock.wrap_mode());
-
-  SkRect dest_rect = gfx::RectFToSkRect(QuadVertexRect());
-  SkRect dest_visible_rect = gfx::RectFToSkRect(MathUtil::ScaleRectProportional(
-      QuadVertexRect(), quad->rect, quad->visible_rect));
-  SkRect content_rect = SkRect::MakeWH(quad->rect.width(), quad->rect.height());
-
-  SkMatrix content_mat;
-  content_mat.setRectToRect(content_rect, dest_rect,
-                            SkMatrix::kFill_ScaleToFit);
-
-  const SkBitmap* content = lock.sk_bitmap();
-
-  SkBitmap filter_bitmap;
-  if (!quad->filters.IsEmpty()) {
-    skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
-        quad->filters, content_texture->size());
-    // TODO(ajuma): Apply the filter in the same pass as the content where
-    // possible (e.g. when there's no origin offset). See crbug.com/308201.
-    if (filter) {
-      SkImageInfo info = SkImageInfo::MakeN32Premul(
-          content_texture->size().width(), content_texture->size().height());
-      if (filter_bitmap.tryAllocPixels(info)) {
-        SkCanvas canvas(filter_bitmap);
-        SkPaint paint;
-        paint.setImageFilter(filter.get());
-        canvas.clear(SK_ColorTRANSPARENT);
-        canvas.translate(SkIntToScalar(-quad->rect.origin().x()),
-                         SkIntToScalar(-quad->rect.origin().y()));
-        canvas.scale(quad->filters_scale.x(), quad->filters_scale.y());
-        canvas.drawSprite(*content, 0, 0, &paint);
-      }
-    }
-  }
-
-  skia::RefPtr<SkShader> shader;
-  if (filter_bitmap.isNull()) {
-    shader = skia::AdoptRef(SkShader::CreateBitmapShader(
-        *content, content_tile_mode, content_tile_mode, &content_mat));
-  } else {
-    shader = skia::AdoptRef(SkShader::CreateBitmapShader(
-        filter_bitmap, content_tile_mode, content_tile_mode, &content_mat));
-  }
-  current_paint_.setShader(shader.get());
-
-  if (quad->mask_resource_id) {
-    ResourceProvider::ScopedReadLockSoftware mask_lock(resource_provider_,
-                                                       quad->mask_resource_id);
-    if (!lock.valid())
-      return;
-    SkShader::TileMode mask_tile_mode = WrapModeToTileMode(
-        mask_lock.wrap_mode());
-
-    const SkBitmap* mask = mask_lock.sk_bitmap();
-
-    // Scale normalized uv rect into absolute texel coordinates.
-    SkRect mask_rect =
-        gfx::RectFToSkRect(gfx::ScaleRect(quad->MaskUVRect(),
-                                          quad->mask_texture_size.width(),
-                                          quad->mask_texture_size.height()));
-
-    SkMatrix mask_mat;
-    mask_mat.setRectToRect(mask_rect, dest_rect, SkMatrix::kFill_ScaleToFit);
-
-    skia::RefPtr<SkShader> mask_shader =
-        skia::AdoptRef(SkShader::CreateBitmapShader(
-            *mask, mask_tile_mode, mask_tile_mode, &mask_mat));
-
-    SkPaint mask_paint;
-    mask_paint.setShader(mask_shader.get());
-
-    SkLayerRasterizer::Builder builder;
-    builder.addLayer(mask_paint);
-
-    skia::RefPtr<SkLayerRasterizer> mask_rasterizer =
-        skia::AdoptRef(builder.detachRasterizer());
-
-    current_paint_.setRasterizer(mask_rasterizer.get());
-    current_canvas_->drawRect(dest_visible_rect, current_paint_);
-  } else {
-    // TODO(skaslev): Apply background filters
-    current_canvas_->drawRect(dest_visible_rect, current_paint_);
-  }
-}
-
-void SoftwareRenderer::DrawUnsupportedQuad(const DrawingFrame* frame,
-                                           const DrawQuad* quad) {
-#ifdef NDEBUG
-  current_paint_.setColor(SK_ColorWHITE);
-#else
-  current_paint_.setColor(SK_ColorMAGENTA);
-#endif
-  current_paint_.setAlpha(quad->opacity() * 255);
-  current_canvas_->drawRect(gfx::RectFToSkRect(QuadVertexRect()),
-                            current_paint_);
-}
-
-void SoftwareRenderer::CopyCurrentRenderPassToBitmap(
-    DrawingFrame* frame,
-    scoped_ptr<CopyOutputRequest> request) {
-  gfx::Rect copy_rect = frame->current_render_pass->output_rect;
-  if (request->has_area())
-    copy_rect.Intersect(request->area());
-  gfx::Rect window_copy_rect = MoveFromDrawToWindowSpace(frame, copy_rect);
-
-  scoped_ptr<SkBitmap> bitmap(new SkBitmap);
-  bitmap->setInfo(SkImageInfo::MakeN32Premul(window_copy_rect.width(),
-                                             window_copy_rect.height()));
-  current_canvas_->readPixels(
-      bitmap.get(), window_copy_rect.x(), window_copy_rect.y());
-
-  request->SendBitmapResult(bitmap.Pass());
-}
-
-void SoftwareRenderer::DiscardBackbuffer() {
-  if (is_backbuffer_discarded_)
-    return;
-
-  output_surface_->DiscardBackbuffer();
-
-  is_backbuffer_discarded_ = true;
-
-  // Damage tracker needs a full reset every time framebuffer is discarded.
-  client_->SetFullRootLayerDamage();
-}
-
-void SoftwareRenderer::EnsureBackbuffer() {
-  if (!is_backbuffer_discarded_)
-    return;
-
-  output_surface_->EnsureBackbuffer();
-  is_backbuffer_discarded_ = false;
-}
-
-void SoftwareRenderer::DidChangeVisibility() {
-  if (visible())
-    EnsureBackbuffer();
-  else
-    DiscardBackbuffer();
-}
-
-}  // namespace cc
diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h
deleted file mode 100644
index d172ac5..0000000
--- a/cc/output/software_renderer.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_OUTPUT_SOFTWARE_RENDERER_H_
-#define CC_OUTPUT_SOFTWARE_RENDERER_H_
-
-#include "base/basictypes.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/direct_renderer.h"
-
-namespace cc {
-
-class OutputSurface;
-class RendererClient;
-class ResourceProvider;
-class SoftwareOutputDevice;
-
-class CheckerboardDrawQuad;
-class DebugBorderDrawQuad;
-class PictureDrawQuad;
-class RenderPassDrawQuad;
-class SolidColorDrawQuad;
-class TextureDrawQuad;
-class TileDrawQuad;
-
-class SoftwareRenderer : public DirectRenderer {
- public:
-  static scoped_ptr<SoftwareRenderer> Create(
-      RendererClient* client,
-      const RendererSettings* settings,
-      OutputSurface* output_surface,
-      ResourceProvider* resource_provider);
-
-  ~SoftwareRenderer() override;
-  const RendererCapabilitiesImpl& Capabilities() const override;
-  void Finish() override;
-  void SwapBuffers(const CompositorFrameMetadata& metadata) override;
-  void ReceiveSwapBuffersAck(const CompositorFrameAck& ack) override;
-  void DiscardBackbuffer() override;
-  void EnsureBackbuffer() override;
-
- protected:
-  void BindFramebufferToOutputSurface(DrawingFrame* frame) override;
-  bool BindFramebufferToTexture(DrawingFrame* frame,
-                                const ScopedResource* texture,
-                                const gfx::Rect& target_rect) override;
-  void SetDrawViewport(const gfx::Rect& window_space_viewport) override;
-  void SetScissorTestRect(const gfx::Rect& scissor_rect) override;
-  void PrepareSurfaceForPass(DrawingFrame* frame,
-                             SurfaceInitializationMode initialization_mode,
-                             const gfx::Rect& render_pass_scissor) override;
-
-  void DoDrawQuad(DrawingFrame* frame,
-                  const DrawQuad* quad,
-                  const gfx::QuadF* draw_region) override;
-  void BeginDrawingFrame(DrawingFrame* frame) override;
-  void FinishDrawingFrame(DrawingFrame* frame) override;
-  bool FlippedFramebuffer(const DrawingFrame* frame) const override;
-  void EnsureScissorTestEnabled() override;
-  void EnsureScissorTestDisabled() override;
-  void CopyCurrentRenderPassToBitmap(
-      DrawingFrame* frame,
-      scoped_ptr<CopyOutputRequest> request) override;
-
-  SoftwareRenderer(RendererClient* client,
-                   const RendererSettings* settings,
-                   OutputSurface* output_surface,
-                   ResourceProvider* resource_provider);
-
-  void DidChangeVisibility() override;
-
- private:
-  void ClearCanvas(SkColor color);
-  void ClearFramebuffer(DrawingFrame* frame);
-  void SetClipRect(const gfx::Rect& rect);
-  bool IsSoftwareResource(ResourceProvider::ResourceId resource_id) const;
-
-  void DrawCheckerboardQuad(const DrawingFrame* frame,
-                            const CheckerboardDrawQuad* quad);
-  void DrawDebugBorderQuad(const DrawingFrame* frame,
-                           const DebugBorderDrawQuad* quad);
-  void DrawPictureQuad(const DrawingFrame* frame,
-                       const PictureDrawQuad* quad);
-  void DrawRenderPassQuad(const DrawingFrame* frame,
-                          const RenderPassDrawQuad* quad);
-  void DrawSolidColorQuad(const DrawingFrame* frame,
-                          const SolidColorDrawQuad* quad);
-  void DrawTextureQuad(const DrawingFrame* frame,
-                       const TextureDrawQuad* quad);
-  void DrawTileQuad(const DrawingFrame* frame,
-                    const TileDrawQuad* quad);
-  void DrawUnsupportedQuad(const DrawingFrame* frame,
-                           const DrawQuad* quad);
-
-  RendererCapabilitiesImpl capabilities_;
-  bool is_scissor_enabled_;
-  bool is_backbuffer_discarded_;
-  gfx::Rect scissor_rect_;
-
-  SoftwareOutputDevice* output_device_;
-  SkCanvas* root_canvas_;
-  SkCanvas* current_canvas_;
-  SkPaint current_paint_;
-  scoped_ptr<ResourceProvider::ScopedWriteLockSoftware>
-      current_framebuffer_lock_;
-  skia::RefPtr<SkCanvas> current_framebuffer_canvas_;
-  scoped_ptr<SoftwareFrameData> current_frame_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(SoftwareRenderer);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_SOFTWARE_RENDERER_H_
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc
deleted file mode 100644
index 3b2c4bc..0000000
--- a/cc/output/software_renderer_unittest.cc
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/output/software_renderer.h"
-
-#include "base/run_loop.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/output/software_output_device.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/test/animation_test_common.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/render_pass_test_common.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-
-namespace cc {
-namespace {
-
-class SoftwareRendererTest : public testing::Test, public RendererClient {
- public:
-  void InitializeRenderer(
-      scoped_ptr<SoftwareOutputDevice> software_output_device) {
-    output_surface_ = FakeOutputSurface::CreateSoftware(
-        software_output_device.Pass());
-    CHECK(output_surface_->BindToClient(&output_surface_client_));
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1);
-    renderer_ = SoftwareRenderer::Create(
-        this, &settings_, output_surface_.get(), resource_provider());
-  }
-
-  ResourceProvider* resource_provider() const {
-    return resource_provider_.get();
-  }
-
-  SoftwareRenderer* renderer() const { return renderer_.get(); }
-
-  // RendererClient implementation.
-  void SetFullRootLayerDamage() override {}
-
-  scoped_ptr<SkBitmap> DrawAndCopyOutput(RenderPassList* list,
-                                         float device_scale_factor,
-                                         gfx::Rect device_viewport_rect) {
-    scoped_ptr<SkBitmap> bitmap_result;
-    base::RunLoop loop;
-
-    list->back()->copy_requests.push_back(
-        CopyOutputRequest::CreateBitmapRequest(
-            base::Bind(&SoftwareRendererTest::SaveBitmapResult,
-                       base::Unretained(&bitmap_result),
-                       loop.QuitClosure())));
-
-    renderer()->DrawFrame(list,
-                          device_scale_factor,
-                          device_viewport_rect,
-                          device_viewport_rect,
-                          false);
-    loop.Run();
-    return bitmap_result.Pass();
-  }
-
-  static void SaveBitmapResult(scoped_ptr<SkBitmap>* bitmap_result,
-                               const base::Closure& quit_closure,
-                               scoped_ptr<CopyOutputResult> result) {
-    DCHECK(result->HasBitmap());
-    *bitmap_result = result->TakeBitmap();
-    quit_closure.Run();
-  }
-
- protected:
-  RendererSettings settings_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_ptr<FakeOutputSurface> output_surface_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<SoftwareRenderer> renderer_;
-};
-
-TEST_F(SoftwareRendererTest, SolidColorQuad) {
-  gfx::Size outer_size(100, 100);
-  gfx::Size inner_size(98, 98);
-  gfx::Rect outer_rect(outer_size);
-  gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
-  gfx::Rect visible_rect(gfx::Point(1, 2), gfx::Size(98, 97));
-
-  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
-
-  RenderPassId root_render_pass_id = RenderPassId(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, outer_rect, outer_rect, gfx::Transform());
-  SharedQuadState* shared_quad_state =
-      root_render_pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->SetAll(gfx::Transform(),
-                            outer_size,
-                            outer_rect,
-                            outer_rect,
-                            false,
-                            1.0,
-                            SkXfermode::kSrcOver_Mode,
-                            0);
-  SolidColorDrawQuad* inner_quad =
-      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  inner_quad->SetNew(
-      shared_quad_state, inner_rect, inner_rect, SK_ColorCYAN, false);
-  inner_quad->visible_rect = visible_rect;
-  SolidColorDrawQuad* outer_quad =
-      root_render_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  outer_quad->SetNew(
-      shared_quad_state, outer_rect, outer_rect, SK_ColorYELLOW, false);
-
-  RenderPassList list;
-  list.push_back(root_render_pass.Pass());
-
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect(outer_size);
-  scoped_ptr<SkBitmap> output =
-      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(outer_rect.width(), output->info().fWidth);
-  EXPECT_EQ(outer_rect.height(), output->info().fHeight);
-
-  EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
-  EXPECT_EQ(SK_ColorYELLOW,
-            output->getColor(outer_size.width() - 1, outer_size.height() - 1));
-  EXPECT_EQ(SK_ColorYELLOW, output->getColor(1, 1));
-  EXPECT_EQ(SK_ColorCYAN, output->getColor(1, 2));
-  EXPECT_EQ(SK_ColorCYAN,
-            output->getColor(inner_size.width() - 1, inner_size.height() - 1));
-}
-
-TEST_F(SoftwareRendererTest, TileQuad) {
-  gfx::Size outer_size(100, 100);
-  gfx::Size inner_size(98, 98);
-  gfx::Rect outer_rect(outer_size);
-  gfx::Rect inner_rect(gfx::Point(1, 1), inner_size);
-  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
-
-  ResourceProvider::ResourceId resource_yellow =
-      resource_provider()->CreateResource(
-          outer_size, GL_CLAMP_TO_EDGE,
-          ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-  ResourceProvider::ResourceId resource_cyan =
-      resource_provider()->CreateResource(
-          inner_size, GL_CLAMP_TO_EDGE,
-          ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-
-  SkBitmap yellow_tile;
-  yellow_tile.allocN32Pixels(outer_size.width(), outer_size.height());
-  yellow_tile.eraseColor(SK_ColorYELLOW);
-
-  SkBitmap cyan_tile;
-  cyan_tile.allocN32Pixels(inner_size.width(), inner_size.height());
-  cyan_tile.eraseColor(SK_ColorCYAN);
-
-  resource_provider()->CopyToResource(
-      resource_yellow, static_cast<uint8_t*>(yellow_tile.getPixels()),
-      outer_size);
-  resource_provider()->CopyToResource(
-      resource_cyan, static_cast<uint8_t*>(cyan_tile.getPixels()), inner_size);
-
-  gfx::Rect root_rect = outer_rect;
-
-  RenderPassId root_render_pass_id = RenderPassId(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, root_rect, root_rect, gfx::Transform());
-  SharedQuadState* shared_quad_state =
-      root_render_pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->SetAll(gfx::Transform(),
-                            outer_size,
-                            outer_rect,
-                            outer_rect,
-                            false,
-                            1.0,
-                            SkXfermode::kSrcOver_Mode,
-                            0);
-  TileDrawQuad* inner_quad =
-      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  inner_quad->SetNew(shared_quad_state,
-                     inner_rect,
-                     inner_rect,
-                     inner_rect,
-                     resource_cyan,
-                     gfx::RectF(inner_size),
-                     inner_size,
-                     false,
-                     false);
-  TileDrawQuad* outer_quad =
-      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  outer_quad->SetNew(shared_quad_state,
-                     outer_rect,
-                     outer_rect,
-                     outer_rect,
-                     resource_yellow,
-                     gfx::RectF(outer_size),
-                     outer_size,
-                     false,
-                     false);
-
-  RenderPassList list;
-  list.push_back(root_render_pass.Pass());
-
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect(outer_size);
-  scoped_ptr<SkBitmap> output =
-      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(outer_rect.width(), output->info().fWidth);
-  EXPECT_EQ(outer_rect.height(), output->info().fHeight);
-
-  EXPECT_EQ(SK_ColorYELLOW, output->getColor(0, 0));
-  EXPECT_EQ(SK_ColorYELLOW,
-            output->getColor(outer_size.width() - 1, outer_size.height() - 1));
-  EXPECT_EQ(SK_ColorCYAN, output->getColor(1, 1));
-  EXPECT_EQ(SK_ColorCYAN,
-            output->getColor(inner_size.width() - 1, inner_size.height() - 1));
-}
-
-TEST_F(SoftwareRendererTest, TileQuadVisibleRect) {
-  gfx::Size tile_size(100, 100);
-  gfx::Rect tile_rect(tile_size);
-  gfx::Rect visible_rect = tile_rect;
-  visible_rect.Inset(1, 2, 3, 4);
-  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
-
-  ResourceProvider::ResourceId resource_cyan =
-      resource_provider()->CreateResource(
-          tile_size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-          RGBA_8888);
-
-  SkBitmap cyan_tile;  // The lowest five rows are yellow.
-  cyan_tile.allocN32Pixels(tile_size.width(), tile_size.height());
-  cyan_tile.eraseColor(SK_ColorCYAN);
-  cyan_tile.eraseArea(
-      SkIRect::MakeLTRB(
-          0, visible_rect.bottom() - 1, tile_rect.width(), tile_rect.bottom()),
-      SK_ColorYELLOW);
-
-  resource_provider()->CopyToResource(
-      resource_cyan, static_cast<uint8_t*>(cyan_tile.getPixels()), tile_size);
-
-  gfx::Rect root_rect(tile_size);
-
-  RenderPassId root_render_pass_id = RenderPassId(1, 1);
-  scoped_ptr<TestRenderPass> root_render_pass = TestRenderPass::Create();
-  root_render_pass->SetNew(
-      root_render_pass_id, root_rect, root_rect, gfx::Transform());
-  SharedQuadState* shared_quad_state =
-      root_render_pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->SetAll(gfx::Transform(),
-                            tile_size,
-                            tile_rect,
-                            tile_rect,
-                            false,
-                            1.0,
-                            SkXfermode::kSrcOver_Mode,
-                            0);
-  TileDrawQuad* quad =
-      root_render_pass->CreateAndAppendDrawQuad<TileDrawQuad>();
-  quad->SetNew(shared_quad_state,
-               tile_rect,
-               tile_rect,
-               tile_rect,
-               resource_cyan,
-               gfx::RectF(tile_size),
-               tile_size,
-               false,
-               false);
-  quad->visible_rect = visible_rect;
-
-  RenderPassList list;
-  list.push_back(root_render_pass.Pass());
-
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect(tile_size);
-  scoped_ptr<SkBitmap> output =
-      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(tile_rect.width(), output->info().fWidth);
-  EXPECT_EQ(tile_rect.height(), output->info().fHeight);
-
-  // Check portion of tile not in visible rect isn't drawn.
-  const unsigned int kTransparent = SK_ColorTRANSPARENT;
-  EXPECT_EQ(kTransparent, output->getColor(0, 0));
-  EXPECT_EQ(kTransparent,
-            output->getColor(tile_rect.width() - 1, tile_rect.height() - 1));
-  EXPECT_EQ(kTransparent,
-            output->getColor(visible_rect.x() - 1, visible_rect.y() - 1));
-  EXPECT_EQ(kTransparent,
-            output->getColor(visible_rect.right(), visible_rect.bottom()));
-  // Ensure visible part is drawn correctly.
-  EXPECT_EQ(SK_ColorCYAN, output->getColor(visible_rect.x(), visible_rect.y()));
-  EXPECT_EQ(
-      SK_ColorCYAN,
-      output->getColor(visible_rect.right() - 2, visible_rect.bottom() - 2));
-  // Ensure last visible line is correct.
-  EXPECT_EQ(
-      SK_ColorYELLOW,
-      output->getColor(visible_rect.right() - 1, visible_rect.bottom() - 1));
-}
-
-TEST_F(SoftwareRendererTest, ShouldClearRootRenderPass) {
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect(0, 0, 100, 100);
-
-  settings_.should_clear_root_render_pass = false;
-  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
-
-  RenderPassList list;
-
-  // Draw a fullscreen green quad in a first frame.
-  RenderPassId root_clear_pass_id(1, 0);
-  TestRenderPass* root_clear_pass = AddRenderPass(
-      &list, root_clear_pass_id, device_viewport_rect, gfx::Transform());
-  AddQuad(root_clear_pass, device_viewport_rect, SK_ColorGREEN);
-
-  renderer()->DecideRenderPassAllocationsForFrame(list);
-
-  scoped_ptr<SkBitmap> output =
-      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
-  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
-
-  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
-  EXPECT_EQ(SK_ColorGREEN,
-            output->getColor(device_viewport_rect.width() - 1,
-                             device_viewport_rect.height() - 1));
-
-  list.clear();
-
-  // Draw a smaller magenta rect without filling the viewport in a separate
-  // frame.
-  gfx::Rect smaller_rect(20, 20, 60, 60);
-
-  RenderPassId root_smaller_pass_id(2, 0);
-  TestRenderPass* root_smaller_pass = AddRenderPass(
-      &list, root_smaller_pass_id, device_viewport_rect, gfx::Transform());
-  AddQuad(root_smaller_pass, smaller_rect, SK_ColorMAGENTA);
-
-  renderer()->DecideRenderPassAllocationsForFrame(list);
-
-  output = DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
-  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
-
-  // If we didn't clear, the borders should still be green.
-  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
-  EXPECT_EQ(SK_ColorGREEN,
-            output->getColor(device_viewport_rect.width() - 1,
-                             device_viewport_rect.height() - 1));
-
-  EXPECT_EQ(SK_ColorMAGENTA,
-            output->getColor(smaller_rect.x(), smaller_rect.y()));
-  EXPECT_EQ(
-      SK_ColorMAGENTA,
-      output->getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
-}
-
-TEST_F(SoftwareRendererTest, RenderPassVisibleRect) {
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect(0, 0, 100, 100);
-  InitializeRenderer(make_scoped_ptr(new SoftwareOutputDevice));
-
-  RenderPassList list;
-
-  // Pass drawn as inner quad is magenta.
-  gfx::Rect smaller_rect(20, 20, 60, 60);
-  RenderPassId smaller_pass_id(2, 1);
-  TestRenderPass* smaller_pass =
-      AddRenderPass(&list, smaller_pass_id, smaller_rect, gfx::Transform());
-  AddQuad(smaller_pass, smaller_rect, SK_ColorMAGENTA);
-
-  // Root pass is green.
-  RenderPassId root_clear_pass_id(1, 0);
-  TestRenderPass* root_clear_pass = AddRenderPass(
-      &list, root_clear_pass_id, device_viewport_rect, gfx::Transform());
-  AddRenderPassQuad(root_clear_pass, smaller_pass);
-  AddQuad(root_clear_pass, device_viewport_rect, SK_ColorGREEN);
-
-  // Interior pass quad has smaller visible rect.
-  gfx::Rect interior_visible_rect(30, 30, 40, 40);
-  root_clear_pass->quad_list.front()->visible_rect = interior_visible_rect;
-
-  renderer()->DecideRenderPassAllocationsForFrame(list);
-
-  scoped_ptr<SkBitmap> output =
-      DrawAndCopyOutput(&list, device_scale_factor, device_viewport_rect);
-  EXPECT_EQ(device_viewport_rect.width(), output->info().fWidth);
-  EXPECT_EQ(device_viewport_rect.height(), output->info().fHeight);
-
-  EXPECT_EQ(SK_ColorGREEN, output->getColor(0, 0));
-  EXPECT_EQ(SK_ColorGREEN,
-            output->getColor(device_viewport_rect.width() - 1,
-                             device_viewport_rect.height() - 1));
-
-  // Part outside visible rect should remain green.
-  EXPECT_EQ(SK_ColorGREEN,
-            output->getColor(smaller_rect.x(), smaller_rect.y()));
-  EXPECT_EQ(
-      SK_ColorGREEN,
-      output->getColor(smaller_rect.right() - 1, smaller_rect.bottom() - 1));
-
-  EXPECT_EQ(
-      SK_ColorMAGENTA,
-      output->getColor(interior_visible_rect.x(), interior_visible_rect.y()));
-  EXPECT_EQ(SK_ColorMAGENTA,
-            output->getColor(interior_visible_rect.right() - 1,
-                             interior_visible_rect.bottom() - 1));
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/output/static_geometry_binding.cc b/cc/output/static_geometry_binding.cc
deleted file mode 100644
index 683db2d..0000000
--- a/cc/output/static_geometry_binding.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-// 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.
-
-#include "cc/output/static_geometry_binding.h"
-
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace cc {
-
-StaticGeometryBinding::StaticGeometryBinding(gpu::gles2::GLES2Interface* gl,
-                                             const gfx::RectF& quad_vertex_rect)
-    : gl_(gl), quad_vertices_vbo_(0), quad_elements_vbo_(0) {
-  GeometryBindingQuad quads[8];
-  GeometryBindingQuadIndex quad_indices[8];
-
-  static_assert(sizeof(GeometryBindingQuad) == 24 * sizeof(float),
-                "struct Quad should be densely packed");
-  static_assert(sizeof(GeometryBindingQuadIndex) == 6 * sizeof(uint16_t),
-                "struct QuadIndex should be densely packed");
-
-  for (size_t i = 0; i < 8; i++) {
-    GeometryBindingVertex v0 = {
-        {quad_vertex_rect.x(), quad_vertex_rect.bottom(), 0.0f},
-        {0.0f, 1.0f},
-        i * 4.0f + 0.0f};
-    GeometryBindingVertex v1 = {
-        {quad_vertex_rect.x(), quad_vertex_rect.y(), 0.0f},
-        {0.0f, 0.0f},
-        i * 4.0f + 1.0f};
-    GeometryBindingVertex v2 = {
-        {quad_vertex_rect.right(), quad_vertex_rect.y(), 0.0f},
-        {1.0f, 0.0f},
-        i * 4.0f + 2.0f};
-    GeometryBindingVertex v3 = {
-        {quad_vertex_rect.right(), quad_vertex_rect.bottom(), 0.0f},
-        {1.0f, 1.0f},
-        i * 4.0f + 3.0f};
-    GeometryBindingQuad x(v0, v1, v2, v3);
-    quads[i] = x;
-    GeometryBindingQuadIndex y(
-        static_cast<uint16>(0 + 4 * i), static_cast<uint16>(1 + 4 * i),
-        static_cast<uint16>(2 + 4 * i), static_cast<uint16>(3 + 4 * i),
-        static_cast<uint16>(0 + 4 * i), static_cast<uint16>(2 + 4 * i));
-    quad_indices[i] = y;
-  }
-
-  GLC(gl_, gl_->GenBuffers(1, &quad_vertices_vbo_));
-  GLC(gl_, gl_->GenBuffers(1, &quad_elements_vbo_));
-
-  GLC(gl_, gl_->BindBuffer(GL_ARRAY_BUFFER, quad_vertices_vbo_));
-  GLC(gl_, gl_->BufferData(GL_ARRAY_BUFFER, sizeof(GeometryBindingQuad) * 8,
-                           quads, GL_STATIC_DRAW));
-
-  GLC(gl_, gl_->BindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad_elements_vbo_));
-  GLC(gl_, gl_->BufferData(GL_ELEMENT_ARRAY_BUFFER,
-                           sizeof(GeometryBindingQuadIndex) * 8, &quad_indices,
-                           GL_STATIC_DRAW));
-}
-
-StaticGeometryBinding::~StaticGeometryBinding() {
-  gl_->DeleteBuffers(1, &quad_vertices_vbo_);
-  gl_->DeleteBuffers(1, &quad_elements_vbo_);
-}
-
-void StaticGeometryBinding::PrepareForDraw() {
-  SetupGLContext(gl_, quad_elements_vbo_, quad_vertices_vbo_);
-}
-
-}  // namespace cc
diff --git a/cc/output/static_geometry_binding.h b/cc/output/static_geometry_binding.h
deleted file mode 100644
index bd6bfcc..0000000
--- a/cc/output/static_geometry_binding.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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.
-
-#ifndef CC_OUTPUT_STATIC_GEOMETRY_BINDING_H_
-#define CC_OUTPUT_STATIC_GEOMETRY_BINDING_H_
-
-#include "cc/output/geometry_binding.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-class StaticGeometryBinding {
- public:
-  StaticGeometryBinding(gpu::gles2::GLES2Interface* gl,
-                        const gfx::RectF& quad_vertex_rect);
-  ~StaticGeometryBinding();
-
-  void PrepareForDraw();
-
- private:
-  gpu::gles2::GLES2Interface* gl_;
-
-  GLuint quad_vertices_vbo_;
-  GLuint quad_elements_vbo_;
-
-  DISALLOW_COPY_AND_ASSIGN(StaticGeometryBinding);
-};
-
-}  // namespace cc
-
-#endif  // CC_OUTPUT_STATIC_GEOMETRY_BINDING_H_
diff --git a/cc/output/vsync_parameter_observer.h b/cc/output/vsync_parameter_observer.h
deleted file mode 100644
index e586925..0000000
--- a/cc/output/vsync_parameter_observer.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
-#define CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
-
-#include "base/time/time.h"
-
-// Interface for a class which observes the parameters regarding vsync
-// information.
-class VSyncParameterObserver {
- public:
-  virtual void OnUpdateVSyncParameters(base::TimeTicks timebase,
-                                       base::TimeDelta interval) = 0;
-};
-
-#endif  // CC_OUTPUT_VSYNC_PARAMETER_OBSERVER_H_
diff --git a/cc/quads/checkerboard_draw_quad.cc b/cc/quads/checkerboard_draw_quad.cc
deleted file mode 100644
index db6ad1e..0000000
--- a/cc/quads/checkerboard_draw_quad.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/checkerboard_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace cc {
-
-CheckerboardDrawQuad::CheckerboardDrawQuad() : color(0), scale(0.f) {
-}
-
-void CheckerboardDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                                  const gfx::Rect& rect,
-                                  const gfx::Rect& visible_rect,
-                                  SkColor color,
-                                  float scale) {
-  gfx::Rect opaque_rect = SkColorGetA(color) == 255 ? rect : gfx::Rect();
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::CHECKERBOARD, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->scale = scale;
-}
-
-void CheckerboardDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                                  const gfx::Rect& rect,
-                                  const gfx::Rect& opaque_rect,
-                                  const gfx::Rect& visible_rect,
-                                  bool needs_blending,
-                                  SkColor color,
-                                  float scale) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::CHECKERBOARD, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->scale = scale;
-}
-
-void CheckerboardDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {}
-
-const CheckerboardDrawQuad* CheckerboardDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::CHECKERBOARD);
-  return static_cast<const CheckerboardDrawQuad*>(quad);
-}
-
-void CheckerboardDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  value->SetInteger("color", color);
-  value->SetDouble("scale", scale);
-}
-
-}  // namespace cc
diff --git a/cc/quads/checkerboard_draw_quad.h b/cc/quads/checkerboard_draw_quad.h
deleted file mode 100644
index 3e560f2..0000000
--- a/cc/quads/checkerboard_draw_quad.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_CHECKERBOARD_DRAW_QUAD_H_
-#define CC_QUADS_CHECKERBOARD_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-
-class CheckerboardDrawQuad : public DrawQuad {
- public:
-  CheckerboardDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& visible_rect,
-              SkColor color,
-              float scale);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              SkColor color,
-              float scale);
-
-  SkColor color;
-  float scale;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const CheckerboardDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_CHECKERBOARD_DRAW_QUAD_H_
diff --git a/cc/quads/content_draw_quad_base.cc b/cc/quads/content_draw_quad_base.cc
deleted file mode 100644
index 66fa147..0000000
--- a/cc/quads/content_draw_quad_base.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/quads/content_draw_quad_base.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-
-namespace cc {
-
-ContentDrawQuadBase::ContentDrawQuadBase()
-    : swizzle_contents(false) {
-}
-
-ContentDrawQuadBase::~ContentDrawQuadBase() {
-}
-
-void ContentDrawQuadBase::SetNew(const SharedQuadState* shared_quad_state,
-                                 DrawQuad::Material material,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& opaque_rect,
-                                 const gfx::Rect& visible_rect,
-                                 const gfx::RectF& tex_coord_rect,
-                                 const gfx::Size& texture_size,
-                                 bool swizzle_contents,
-                                 bool nearest_neighbor) {
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, material, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->tex_coord_rect = tex_coord_rect;
-  this->texture_size = texture_size;
-  this->swizzle_contents = swizzle_contents;
-  this->nearest_neighbor = nearest_neighbor;
-}
-
-void ContentDrawQuadBase::SetAll(const SharedQuadState* shared_quad_state,
-                                 DrawQuad::Material material,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& opaque_rect,
-                                 const gfx::Rect& visible_rect,
-                                 bool needs_blending,
-                                 const gfx::RectF& tex_coord_rect,
-                                 const gfx::Size& texture_size,
-                                 bool swizzle_contents,
-                                 bool nearest_neighbor) {
-  DrawQuad::SetAll(shared_quad_state, material, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->tex_coord_rect = tex_coord_rect;
-  this->texture_size = texture_size;
-  this->swizzle_contents = swizzle_contents;
-  this->nearest_neighbor = nearest_neighbor;
-}
-
-void ContentDrawQuadBase::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  MathUtil::AddToTracedValue("tex_coord_rect", tex_coord_rect, value);
-  MathUtil::AddToTracedValue("texture_size", texture_size, value);
-
-  value->SetBoolean("swizzle_contents", swizzle_contents);
-  value->SetBoolean("nearest_neighbor", nearest_neighbor);
-}
-
-}  // namespace cc
diff --git a/cc/quads/content_draw_quad_base.h b/cc/quads/content_draw_quad_base.h
deleted file mode 100644
index 0421a1e..0000000
--- a/cc/quads/content_draw_quad_base.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_QUADS_CONTENT_DRAW_QUAD_BASE_H_
-#define CC_QUADS_CONTENT_DRAW_QUAD_BASE_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class ContentDrawQuadBase : public DrawQuad {
- public:
-  void SetNew(const SharedQuadState* shared_quad_state,
-              DrawQuad::Material material,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& texture_size,
-              bool swizzle_contents,
-              bool nearest_neighbor);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              DrawQuad::Material material,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& texture_size,
-              bool swizzle_contents,
-              bool nearest_neighbor);
-
-  gfx::RectF tex_coord_rect;
-  gfx::Size texture_size;
-  bool swizzle_contents;
-  bool nearest_neighbor;
-
- protected:
-  ContentDrawQuadBase();
-  ~ContentDrawQuadBase() override;
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_CONTENT_DRAW_QUAD_BASE_H_
diff --git a/cc/quads/debug_border_draw_quad.cc b/cc/quads/debug_border_draw_quad.cc
deleted file mode 100644
index f91bf3b..0000000
--- a/cc/quads/debug_border_draw_quad.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/debug_border_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace cc {
-
-DebugBorderDrawQuad::DebugBorderDrawQuad()
-    : color(0),
-      width(0) {
-}
-
-void DebugBorderDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& visible_rect,
-                                 SkColor color,
-                                 int width) {
-  gfx::Rect opaque_rect;
-  bool needs_blending = SkColorGetA(color) < 255;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::DEBUG_BORDER, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->width = width;
-}
-
-void DebugBorderDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& opaque_rect,
-                                 const gfx::Rect& visible_rect,
-                                 bool needs_blending,
-                                 SkColor color,
-                                 int width) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::DEBUG_BORDER, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->width = width;
-}
-
-void DebugBorderDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {}
-
-const DebugBorderDrawQuad* DebugBorderDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::DEBUG_BORDER);
-  return static_cast<const DebugBorderDrawQuad*>(quad);
-}
-
-void DebugBorderDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  value->SetInteger("color", color);
-  value->SetInteger("width", width);
-}
-
-}  // namespace cc
diff --git a/cc/quads/debug_border_draw_quad.h b/cc/quads/debug_border_draw_quad.h
deleted file mode 100644
index 07c94bf..0000000
--- a/cc/quads/debug_border_draw_quad.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_DEBUG_BORDER_DRAW_QUAD_H_
-#define CC_QUADS_DEBUG_BORDER_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-
-class DebugBorderDrawQuad : public DrawQuad {
- public:
-  DebugBorderDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& visible_rect,
-              SkColor color,
-              int width);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              SkColor color,
-              int width);
-
-  SkColor color;
-  int width;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const DebugBorderDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_DEBUG_BORDER_DRAW_QUAD_H_
diff --git a/cc/quads/draw_polygon.cc b/cc/quads/draw_polygon.cc
deleted file mode 100644
index 6544b64..0000000
--- a/cc/quads/draw_polygon.cc
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/draw_polygon.h"
-
-#include <vector>
-
-#include "cc/output/bsp_compare_result.h"
-#include "cc/quads/draw_quad.h"
-
-namespace {
-// This allows for some imperfection in the normal comparison when checking if
-// two pieces of geometry are coplanar.
-static const float coplanar_dot_epsilon = 0.001f;
-// This threshold controls how "thick" a plane is. If a point's distance is
-// <= |compare_threshold|, then it is considered on the plane. Only when this
-// boundary is crossed do we consider doing splitting.
-static const float compare_threshold = 1.0f;
-// |split_threshold| is lower in this case because we want the points created
-// during splitting to be well within the range of |compare_threshold| for
-// comparison purposes. The splitting operation will produce intersection points
-// that fit within a tighter distance to the splitting plane as a result of this
-// value. By using a value >= |compare_threshold| we run the risk of creating
-// points that SHOULD be intersecting the "thick plane", but actually fail to
-// test positively for it because |split_threshold| allowed them to be outside
-// this range.
-// This is really supposd to be compare_threshold / 2.0f, but that would
-// create another static initializer.
-static const float split_threshold = 0.5f;
-
-static const float normalized_threshold = 0.001f;
-}  // namespace
-
-namespace cc {
-
-DrawPolygon::DrawPolygon() {
-}
-
-DrawPolygon::DrawPolygon(const DrawQuad* original,
-                         const std::vector<gfx::Point3F>& in_points,
-                         const gfx::Vector3dF& normal,
-                         int draw_order_index)
-    : order_index_(draw_order_index), original_ref_(original), is_split_(true) {
-  for (size_t i = 0; i < in_points.size(); i++) {
-    points_.push_back(in_points[i]);
-  }
-  normal_ = normal;
-}
-
-// This takes the original DrawQuad that this polygon should be based on,
-// a visible content rect to make the 4 corner points from, and a transformation
-// to move it and its normal into screen space.
-DrawPolygon::DrawPolygon(const DrawQuad* original_ref,
-                         const gfx::RectF& visible_content_rect,
-                         const gfx::Transform& transform,
-                         int draw_order_index)
-    : normal_(0.0f, 0.0f, 1.0f),
-      order_index_(draw_order_index),
-      original_ref_(original_ref),
-      is_split_(false) {
-  gfx::Point3F points[8];
-  int num_vertices_in_clipped_quad;
-  gfx::QuadF send_quad(visible_content_rect);
-
-  // Doing this mapping here is very important, since we can't just transform
-  // the points without clipping and not run into strange geometry issues when
-  // crossing w = 0. At this point, in the constructor, we know that we're
-  // working with a quad, so we can reuse the MathUtil::MapClippedQuad3d
-  // function instead of writing a generic polygon version of it.
-  MathUtil::MapClippedQuad3d(
-      transform, send_quad, points, &num_vertices_in_clipped_quad);
-  for (int i = 0; i < num_vertices_in_clipped_quad; i++) {
-    points_.push_back(points[i]);
-  }
-  ApplyTransformToNormal(transform);
-}
-
-DrawPolygon::~DrawPolygon() {
-}
-
-scoped_ptr<DrawPolygon> DrawPolygon::CreateCopy() {
-  scoped_ptr<DrawPolygon> new_polygon(new DrawPolygon());
-  new_polygon->order_index_ = order_index_;
-  new_polygon->original_ref_ = original_ref_;
-  new_polygon->points_.reserve(points_.size());
-  new_polygon->points_ = points_;
-  new_polygon->normal_.set_x(normal_.x());
-  new_polygon->normal_.set_y(normal_.y());
-  new_polygon->normal_.set_z(normal_.z());
-  return new_polygon.Pass();
-}
-
-float DrawPolygon::SignedPointDistance(const gfx::Point3F& point) const {
-  return gfx::DotProduct(point - points_[0], normal_);
-}
-
-// Checks whether or not shape a lies on the front or back side of b, or
-// whether they should be considered coplanar. If on the back side, we
-// say A_BEFORE_B because it should be drawn in that order.
-// Assumes that layers are split and there are no intersecting planes.
-BspCompareResult DrawPolygon::SideCompare(const DrawPolygon& a,
-                                          const DrawPolygon& b) {
-  // Let's make sure that both of these are normalized.
-  DCHECK_GE(normalized_threshold, std::abs(a.normal_.LengthSquared() - 1.0f));
-  DCHECK_GE(normalized_threshold, std::abs(b.normal_.LengthSquared() - 1.0f));
-  // Right away let's check if they're coplanar
-  double dot = gfx::DotProduct(a.normal_, b.normal_);
-  float sign = 0.0f;
-  bool normal_match = false;
-  // This check assumes that the normals are normalized.
-  if (std::abs(dot) >= 1.0f - coplanar_dot_epsilon) {
-    normal_match = true;
-    // The normals are matching enough that we only have to test one point.
-    sign = b.SignedPointDistance(a.points_[0]);
-    // Is it on either side of the splitter?
-    if (sign < -compare_threshold) {
-      return BSP_BACK;
-    }
-
-    if (sign > compare_threshold) {
-      return BSP_FRONT;
-    }
-
-    // No it wasn't, so the sign of the dot product of the normals
-    // along with document order determines which side it goes on.
-    if (dot >= 0.0f) {
-      if (a.order_index_ < b.order_index_) {
-        return BSP_COPLANAR_FRONT;
-      }
-      return BSP_COPLANAR_BACK;
-    }
-
-    if (a.order_index_ < b.order_index_) {
-      return BSP_COPLANAR_BACK;
-    }
-    return BSP_COPLANAR_FRONT;
-  }
-
-  int pos_count = 0;
-  int neg_count = 0;
-  for (size_t i = 0; i < a.points_.size(); i++) {
-    if (!normal_match || (normal_match && i > 0)) {
-      sign = gfx::DotProduct(a.points_[i] - b.points_[0], b.normal_);
-    }
-
-    if (sign < -compare_threshold) {
-      ++neg_count;
-    } else if (sign > compare_threshold) {
-      ++pos_count;
-    }
-
-    if (pos_count && neg_count) {
-      return BSP_SPLIT;
-    }
-  }
-
-  if (pos_count) {
-    return BSP_FRONT;
-  }
-  return BSP_BACK;
-}
-
-static bool LineIntersectPlane(const gfx::Point3F& line_start,
-                               const gfx::Point3F& line_end,
-                               const gfx::Point3F& plane_origin,
-                               const gfx::Vector3dF& plane_normal,
-                               gfx::Point3F* intersection,
-                               float distance_threshold) {
-  gfx::Vector3dF start_to_origin_vector = plane_origin - line_start;
-  gfx::Vector3dF end_to_origin_vector = plane_origin - line_end;
-
-  double start_distance = gfx::DotProduct(start_to_origin_vector, plane_normal);
-  double end_distance = gfx::DotProduct(end_to_origin_vector, plane_normal);
-
-  // The case where one vertex lies on the thick-plane and the other
-  // is outside of it.
-  if (std::abs(start_distance) <= distance_threshold &&
-      std::abs(end_distance) > distance_threshold) {
-    intersection->SetPoint(line_start.x(), line_start.y(), line_start.z());
-    return true;
-  }
-
-  // This is the case where we clearly cross the thick-plane.
-  if ((start_distance > distance_threshold &&
-       end_distance < -distance_threshold) ||
-      (start_distance < -distance_threshold &&
-       end_distance > distance_threshold)) {
-    gfx::Vector3dF v = line_end - line_start;
-    float total_distance = std::abs(start_distance) + std::abs(end_distance);
-    float lerp_factor = std::abs(start_distance) / total_distance;
-
-    intersection->SetPoint(line_start.x() + (v.x() * lerp_factor),
-                           line_start.y() + (v.y() * lerp_factor),
-                           line_start.z() + (v.z() * lerp_factor));
-
-    return true;
-  }
-  return false;
-}
-
-// This function is separate from ApplyTransform because it is often unnecessary
-// to transform the normal with the rest of the polygon.
-// When drawing these polygons, it is necessary to move them back into layer
-// space before sending them to OpenGL, which requires using ApplyTransform,
-// but normal information is no longer needed after sorting.
-void DrawPolygon::ApplyTransformToNormal(const gfx::Transform& transform) {
-  // Now we use the inverse transpose of |transform| to transform the normal.
-  gfx::Transform inverse_transform;
-  bool inverted = transform.GetInverse(&inverse_transform);
-  DCHECK(inverted);
-  if (!inverted)
-    return;
-  inverse_transform.Transpose();
-
-  gfx::Point3F new_normal(normal_.x(), normal_.y(), normal_.z());
-  inverse_transform.TransformPoint(&new_normal);
-  // Make sure our normal is still normalized.
-  normal_ = gfx::Vector3dF(new_normal.x(), new_normal.y(), new_normal.z());
-  float normal_magnitude = normal_.Length();
-  if (normal_magnitude != 0 && normal_magnitude != 1) {
-    normal_.Scale(1.0f / normal_magnitude);
-  }
-}
-
-void DrawPolygon::ApplyTransform(const gfx::Transform& transform) {
-  for (size_t i = 0; i < points_.size(); i++) {
-    transform.TransformPoint(&points_[i]);
-  }
-}
-
-// TransformToScreenSpace assumes we're moving a layer from its layer space
-// into 3D screen space, which for sorting purposes requires the normal to
-// be transformed along with the vertices.
-void DrawPolygon::TransformToScreenSpace(const gfx::Transform& transform) {
-  ApplyTransform(transform);
-  ApplyTransformToNormal(transform);
-}
-
-// In the case of TransformToLayerSpace, we assume that we are giving the
-// inverse transformation back to the polygon to move it back into layer space
-// but we can ignore the costly process of applying the inverse to the normal
-// since we know the normal will just reset to its original state.
-void DrawPolygon::TransformToLayerSpace(
-    const gfx::Transform& inverse_transform) {
-  ApplyTransform(inverse_transform);
-  normal_ = gfx::Vector3dF(0.0f, 0.0f, -1.0f);
-}
-
-bool DrawPolygon::Split(const DrawPolygon& splitter,
-                        scoped_ptr<DrawPolygon>* front,
-                        scoped_ptr<DrawPolygon>* back) {
-  gfx::Point3F intersections[2];
-  std::vector<gfx::Point3F> out_points[2];
-  // vertex_before stores the index of the vertex before its matching
-  // intersection.
-  // i.e. vertex_before[0] stores the vertex we saw before we crossed the plane
-  // which resulted in the line/plane intersection giving us intersections[0].
-  size_t vertex_before[2];
-  size_t points_size = points_.size();
-  size_t current_intersection = 0;
-
-  size_t current_vertex = 0;
-  // We will only have two intersection points because we assume all polygons
-  // are convex.
-  while (current_intersection < 2) {
-    if (LineIntersectPlane(points_[(current_vertex % points_size)],
-                           points_[(current_vertex + 1) % points_size],
-                           splitter.points_[0],
-                           splitter.normal_,
-                           &intersections[current_intersection],
-                           split_threshold)) {
-      vertex_before[current_intersection] = current_vertex % points_size;
-      current_intersection++;
-      // We found both intersection points so we're done already.
-      if (current_intersection == 2) {
-        break;
-      }
-    }
-    if (current_vertex++ > (points_size)) {
-      break;
-    }
-  }
-  DCHECK_EQ(current_intersection, static_cast<size_t>(2));
-
-  // Since we found both the intersection points, we can begin building the
-  // vertex set for both our new polygons.
-  size_t start1 = (vertex_before[0] + 1) % points_size;
-  size_t start2 = (vertex_before[1] + 1) % points_size;
-  size_t points_remaining = points_size;
-
-  // First polygon.
-  out_points[0].push_back(intersections[0]);
-  DCHECK_GE(vertex_before[1], start1);
-  for (size_t i = start1; i <= vertex_before[1]; i++) {
-    out_points[0].push_back(points_[i]);
-    --points_remaining;
-  }
-  out_points[0].push_back(intersections[1]);
-
-  // Second polygon.
-  out_points[1].push_back(intersections[1]);
-  size_t index = start2;
-  for (size_t i = 0; i < points_remaining; i++) {
-    out_points[1].push_back(points_[index % points_size]);
-    ++index;
-  }
-  out_points[1].push_back(intersections[0]);
-
-  // Give both polygons the original splitting polygon's ID, so that they'll
-  // still be sorted properly in co-planar instances.
-  scoped_ptr<DrawPolygon> poly1(
-      new DrawPolygon(original_ref_, out_points[0], normal_, order_index_));
-  scoped_ptr<DrawPolygon> poly2(
-      new DrawPolygon(original_ref_, out_points[1], normal_, order_index_));
-
-  DCHECK_GE(poly1->points().size(), 3u);
-  DCHECK_GE(poly2->points().size(), 3u);
-
-  if (SideCompare(*poly1, splitter) == BSP_FRONT) {
-    *front = poly1.Pass();
-    *back = poly2.Pass();
-  } else {
-    *front = poly2.Pass();
-    *back = poly1.Pass();
-  }
-  return true;
-}
-
-// This algorithm takes the first vertex in the polygon and uses that as a
-// pivot point to fan out and create quads from the rest of the vertices.
-// |offset| starts off as the second vertex, and then |op1| and |op2| indicate
-// offset+1 and offset+2 respectively.
-// After the first quad is created, the first vertex in the next quad is the
-// same as all the rest, the pivot point. The second vertex in the next quad is
-// the old |op2|, the last vertex added to the previous quad. This continues
-// until all points are exhausted.
-// The special case here is where there are only 3 points remaining, in which
-// case we use the same values for vertex 3 and 4 to make a degenerate quad
-// that represents a triangle.
-void DrawPolygon::ToQuads2D(std::vector<gfx::QuadF>* quads) const {
-  if (points_.size() <= 2)
-    return;
-
-  gfx::PointF first(points_[0].x(), points_[0].y());
-  size_t offset = 1;
-  while (offset < points_.size() - 1) {
-    size_t op1 = offset + 1;
-    size_t op2 = offset + 2;
-    if (op2 >= points_.size()) {
-      // It's going to be a degenerate triangle.
-      op2 = op1;
-    }
-    quads->push_back(
-        gfx::QuadF(first,
-                   gfx::PointF(points_[offset].x(), points_[offset].y()),
-                   gfx::PointF(points_[op1].x(), points_[op1].y()),
-                   gfx::PointF(points_[op2].x(), points_[op2].y())));
-    offset = op2;
-  }
-}
-
-}  // namespace cc
diff --git a/cc/quads/draw_polygon.h b/cc/quads/draw_polygon.h
deleted file mode 100644
index e1df8f1..0000000
--- a/cc/quads/draw_polygon.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_QUADS_DRAW_POLYGON_H_
-#define CC_QUADS_DRAW_POLYGON_H_
-
-#include <vector>
-
-#include "cc/base/math_util.h"
-#include "cc/output/bsp_compare_result.h"
-#include "ui/gfx/geometry/point3_f.h"
-#include "ui/gfx/geometry/quad_f.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/geometry/vector3d_f.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-class DrawQuad;
-
-class DrawPolygon {
- public:
-  DrawPolygon();
-  ~DrawPolygon();
-
-  DrawPolygon(const DrawQuad* original_ref,
-              const std::vector<gfx::Point3F>& in_points,
-              const gfx::Vector3dF& normal,
-              int draw_order_index = 0);
-  DrawPolygon(const DrawQuad* original_ref,
-              const gfx::RectF& visible_content_rect,
-              const gfx::Transform& transform,
-              int draw_order_index = 0);
-
-  // Split takes this DrawPolygon and splits it into two pieces that are on
-  // either side of |splitter|. Any edges of this polygon that cross the plane
-  // of |splitter| will have an intersection point that is shared by both
-  // polygons on either side.
-  // Split will only return true if it determines that we got back 2
-  // intersection points. Only when it returns true will front and back both be
-  // valid new polygons that are on opposite sides of the splitting plane.
-  bool Split(const DrawPolygon& splitter,
-             scoped_ptr<DrawPolygon>* front,
-             scoped_ptr<DrawPolygon>* back);
-  float SignedPointDistance(const gfx::Point3F& point) const;
-  // Checks polygon a against polygon b and returns which side it lies on, or
-  // whether it crosses (necessitating a split in the BSP tree).
-  static BspCompareResult SideCompare(const DrawPolygon& a,
-                                      const DrawPolygon& b);
-  void ToQuads2D(std::vector<gfx::QuadF>* quads) const;
-  void TransformToScreenSpace(const gfx::Transform& transform);
-  void TransformToLayerSpace(const gfx::Transform& inverse_transform);
-
-  const std::vector<gfx::Point3F>& points() const { return points_; }
-  const gfx::Vector3dF& normal() const { return normal_; }
-  const DrawQuad* original_ref() const { return original_ref_; }
-  int order_index() const { return order_index_; }
-  bool is_split() const { return is_split_; }
-  scoped_ptr<DrawPolygon> CreateCopy();
-
- private:
-  void ApplyTransform(const gfx::Transform& transform);
-  void ApplyTransformToNormal(const gfx::Transform& transform);
-
-  std::vector<gfx::Point3F> points_;
-  // Normalized, necessitated by distance calculations and tests of coplanarity.
-  gfx::Vector3dF normal_;
-  // This is an index that can be used to test whether a quad comes before or
-  // after another in document order, useful for tie-breaking when it comes
-  // to coplanar surfaces.
-  int order_index_;
-  // The pointer to the original quad, which gives us all the drawing info
-  // we need.
-  // This DrawQuad is owned by the caller and its lifetime must be preserved
-  // as long as this DrawPolygon is alive.
-  const DrawQuad* original_ref_;
-  bool is_split_;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_DRAW_POLYGON_H_
diff --git a/cc/quads/draw_polygon_unittest.cc b/cc/quads/draw_polygon_unittest.cc
deleted file mode 100644
index 27cfed4..0000000
--- a/cc/quads/draw_polygon_unittest.cc
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2014 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.
-
-#include <limits>
-#include <vector>
-
-#include "cc/output/bsp_compare_result.h"
-#include "cc/quads/draw_polygon.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-#define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \
-  DrawPolygon name(NULL, points_vector, normal, polygon_id)
-
-#define EXPECT_FLOAT_WITHIN_EPSILON_OF(a, b) \
-  EXPECT_TRUE(std::abs(a - b) < std::numeric_limits<float>::epsilon());
-
-#define EXPECT_POINT_EQ(point_a, point_b)    \
-  EXPECT_FLOAT_EQ(point_a.x(), point_b.x()); \
-  EXPECT_FLOAT_EQ(point_a.y(), point_b.y()); \
-  EXPECT_FLOAT_EQ(point_a.z(), point_b.z());
-
-static void ValidatePoints(const DrawPolygon& polygon,
-                           const std::vector<gfx::Point3F>& points) {
-  EXPECT_EQ(polygon.points().size(), points.size());
-  for (size_t i = 0; i < points.size(); i++) {
-    EXPECT_POINT_EQ(polygon.points()[i], points[i]);
-  }
-}
-
-// Two quads are definitely not touching and so no split should occur.
-TEST(DrawPolygonSplitTest, NotTouchingNoSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 15.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
-
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
-
-  EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_FRONT);
-}
-
-// One quad is resting against another, but doesn't cross its plane so no split
-// should occur.
-TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -10.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
-
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
-
-  EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_BACK);
-}
-
-// One quad intersects another and becomes two pieces.
-TEST(DrawPolygonSplitTest, BasicSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f));
-  vertices_b.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
-
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_a, vertices_a, gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0);
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_b, vertices_b, gfx::Vector3dF(-1.0f, 0.0f, 0.0f), 1);
-
-  EXPECT_EQ(DrawPolygon::SideCompare(polygon_b, polygon_a), BSP_SPLIT);
-
-  scoped_ptr<DrawPolygon> front_polygon;
-  scoped_ptr<DrawPolygon> back_polygon;
-  polygon_b.Split(polygon_a, &front_polygon, &back_polygon);
-  EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_a), BSP_FRONT);
-  EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_a), BSP_BACK);
-
-  std::vector<gfx::Point3F> test_points_a;
-  test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
-  test_points_a.push_back(gfx::Point3F(5.0f, 0.0f, 5.0f));
-  test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 5.0f));
-  test_points_a.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
-  std::vector<gfx::Point3F> test_points_b;
-  test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, 0.0f));
-  test_points_b.push_back(gfx::Point3F(5.0f, 10.0f, -5.0f));
-  test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, -5.0f));
-  test_points_b.push_back(gfx::Point3F(5.0f, 0.0f, 0.0f));
-  ValidatePoints(*(front_polygon.get()), test_points_a);
-  ValidatePoints(*(back_polygon.get()), test_points_b);
-
-  EXPECT_EQ(front_polygon->points().size(), 4u);
-  EXPECT_EQ(back_polygon->points().size(), 4u);
-}
-
-// In this test we cut the corner of a quad so that it creates a triangle and
-// a pentagon as a result.
-TEST(DrawPolygonSplitTest, AngledSplit) {
-  std::vector<gfx::Point3F> vertices_a;
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
-  vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  std::vector<gfx::Point3F> vertices_b;
-  vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f));
-  vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f));
-  vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f));
-  vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f));
-
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_a, vertices_a, gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0);
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_b, vertices_b, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 1);
-
-  EXPECT_EQ(DrawPolygon::SideCompare(polygon_a, polygon_b), BSP_SPLIT);
-
-  scoped_ptr<DrawPolygon> front_polygon;
-  scoped_ptr<DrawPolygon> back_polygon;
-  polygon_a.Split(polygon_b, &front_polygon, &back_polygon);
-  EXPECT_EQ(DrawPolygon::SideCompare(*front_polygon, polygon_b), BSP_FRONT);
-  EXPECT_EQ(DrawPolygon::SideCompare(*back_polygon, polygon_b), BSP_BACK);
-
-  EXPECT_EQ(front_polygon->points().size(), 3u);
-  EXPECT_EQ(back_polygon->points().size(), 5u);
-
-  std::vector<gfx::Point3F> test_points_a;
-  test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
-  test_points_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f));
-  test_points_a.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
-  std::vector<gfx::Point3F> test_points_b;
-  test_points_b.push_back(gfx::Point3F(1.0f, 0.0f, 0.0f));
-  test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f));
-  test_points_b.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f));
-  test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f));
-  test_points_b.push_back(gfx::Point3F(10.0f, 0.0f, 9.0f));
-
-  ValidatePoints(*(front_polygon.get()), test_points_a);
-  ValidatePoints(*(back_polygon.get()), test_points_b);
-}
-
-TEST(DrawPolygonTransformTest, TransformNormal) {
-  // We give this polygon no actual vertices because we're not interested
-  // in actually transforming any points, just the normal.
-  std::vector<gfx::Point3F> vertices_a;
-  CREATE_NEW_DRAW_POLYGON(
-      polygon_a, vertices_a, gfx::Vector3dF(0.707107f, 0.0f, -0.707107f), 0);
-
-  gfx::Transform transform;
-  transform.RotateAboutYAxis(45.0);
-  // This would transform the vertices as well, but we are transforming a
-  // DrawPolygon with 0 vertices just to make sure our normal transformation
-  // using the inverse tranpose matrix gives us the right result.
-  polygon_a.TransformToScreenSpace(transform);
-
-  // Note: We use EXPECT_FLOAT_WITHIN_EPSILON instead of EXPECT_FLOAT_EQUAL here
-  // because some architectures (e.g., Arm64) employ a fused multiply-add
-  // instruction which causes rounding asymmetry and reduces precision.
-  // http://crbug.com/401117.
-  EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().x(), 0);
-  EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().y(), 0);
-  EXPECT_FLOAT_WITHIN_EPSILON_OF(polygon_a.normal().z(), -1);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/quads/draw_quad.cc b/cc/quads/draw_quad.cc
deleted file mode 100644
index 4282f01..0000000
--- a/cc/quads/draw_quad.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "cc/debug/traced_value.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-namespace cc {
-
-DrawQuad::DrawQuad()
-    : material(INVALID), needs_blending(false), shared_quad_state(0) {
-}
-
-void DrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                      Material material,
-                      const gfx::Rect& rect,
-                      const gfx::Rect& opaque_rect,
-                      const gfx::Rect& visible_rect,
-                      bool needs_blending) {
-  DCHECK(rect.Contains(visible_rect)) << "rect: " << rect.ToString()
-                                      << " visible_rect: "
-                                      << visible_rect.ToString();
-  DCHECK(opaque_rect.IsEmpty() || rect.Contains(opaque_rect))
-      << "rect: " << rect.ToString() << "opaque_rect "
-      << opaque_rect.ToString();
-
-  this->material = material;
-  this->rect = rect;
-  this->opaque_rect = opaque_rect;
-  this->visible_rect = visible_rect;
-  this->needs_blending = needs_blending;
-  this->shared_quad_state = shared_quad_state;
-
-  DCHECK(shared_quad_state);
-  DCHECK(material != INVALID);
-}
-
-DrawQuad::~DrawQuad() {
-}
-
-void DrawQuad::AsValueInto(base::trace_event::TracedValue* value) const {
-  value->SetInteger("material", material);
-  TracedValue::SetIDRef(shared_quad_state, value, "shared_state");
-
-  MathUtil::AddToTracedValue("content_space_rect", rect, value);
-
-  bool rect_is_clipped;
-  gfx::QuadF rect_as_target_space_quad = MathUtil::MapQuad(
-      shared_quad_state->content_to_target_transform,
-      gfx::QuadF(rect),
-      &rect_is_clipped);
-  MathUtil::AddToTracedValue("rect_as_target_space_quad",
-                             rect_as_target_space_quad, value);
-
-  value->SetBoolean("rect_is_clipped", rect_is_clipped);
-
-  MathUtil::AddToTracedValue("content_space_opaque_rect", opaque_rect, value);
-
-  bool opaque_rect_is_clipped;
-  gfx::QuadF opaque_rect_as_target_space_quad = MathUtil::MapQuad(
-      shared_quad_state->content_to_target_transform,
-      gfx::QuadF(opaque_rect),
-      &opaque_rect_is_clipped);
-  MathUtil::AddToTracedValue("opaque_rect_as_target_space_quad",
-                             opaque_rect_as_target_space_quad, value);
-
-  value->SetBoolean("opaque_rect_is_clipped", opaque_rect_is_clipped);
-
-  MathUtil::AddToTracedValue("content_space_visible_rect", visible_rect, value);
-
-  bool visible_rect_is_clipped;
-  gfx::QuadF visible_rect_as_target_space_quad = MathUtil::MapQuad(
-      shared_quad_state->content_to_target_transform,
-      gfx::QuadF(visible_rect),
-      &visible_rect_is_clipped);
-
-  MathUtil::AddToTracedValue("visible_rect_as_target_space_quad",
-                             visible_rect_as_target_space_quad, value);
-
-  value->SetBoolean("visible_rect_is_clipped", visible_rect_is_clipped);
-
-  value->SetBoolean("needs_blending", needs_blending);
-  value->SetBoolean("should_draw_with_blending", ShouldDrawWithBlending());
-  ExtendValue(value);
-}
-
-}  // namespace cc
diff --git a/cc/quads/draw_quad.h b/cc/quads/draw_quad.h
deleted file mode 100644
index 6e6b028..0000000
--- a/cc/quads/draw_quad.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_DRAW_QUAD_H_
-#define CC_QUADS_DRAW_QUAD_H_
-
-#include "base/callback.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/resources/resource_provider.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class Value;
-class DictionaryValue;
-}
-
-namespace cc {
-
-// DrawQuad is a bag of data used for drawing a quad. Because different
-// materials need different bits of per-quad data to render, classes that derive
-// from DrawQuad store additional data in their derived instance. The Material
-// enum is used to "safely" downcast to the derived class.
-// Note: quads contain rects and sizes, which live in different spaces. There is
-// the "content space", which is the arbitrary space in which the quad's
-// geometry is defined (generally related to the layer that produced the quad,
-// e.g. the content space for TiledLayerImpls, or the geometry space for
-// PictureLayerImpls). There is also the "target space", which is the space, in
-// "physical" pixels, of the render target where the quads is drawn. The quad's
-// transform maps the content space to the target space.
-class DrawQuad {
- public:
-  enum Material {
-    INVALID,
-    CHECKERBOARD,
-    DEBUG_BORDER,
-    IO_SURFACE_CONTENT,
-    UNUSED_SPACE_FOR_PICTURE_CONTENT,
-    RENDER_PASS,
-    SOLID_COLOR,
-    STREAM_VIDEO_CONTENT,
-    SURFACE_CONTENT,
-    TEXTURE_CONTENT,
-    TILED_CONTENT,
-    YUV_VIDEO_CONTENT,
-    MATERIAL_LAST = YUV_VIDEO_CONTENT
-  };
-
-  virtual ~DrawQuad();
-
-  // TODO(danakj): Chromify or remove these SharedQuadState helpers.
-  const gfx::Transform& quadTransform() const {
-    return shared_quad_state->content_to_target_transform;
-  }
-  gfx::Rect visibleContentRect() const {
-    return shared_quad_state->visible_content_rect;
-  }
-  gfx::Rect clipRect() const { return shared_quad_state->clip_rect; }
-  bool isClipped() const { return shared_quad_state->is_clipped; }
-  float opacity() const { return shared_quad_state->opacity; }
-
-  Material material;
-
-  // This rect, after applying the quad_transform(), gives the geometry that
-  // this quad should draw to. This rect lives in content space.
-  gfx::Rect rect;
-
-  // This specifies the region of the quad that is opaque. This rect lives in
-  // content space.
-  gfx::Rect opaque_rect;
-
-  // Allows changing the rect that gets drawn to make it smaller. This value
-  // should be clipped to |rect|. This rect lives in content space.
-  gfx::Rect visible_rect;
-
-  // By default blending is used when some part of the quad is not opaque.
-  // With this setting, it is possible to force blending on regardless of the
-  // opaque area.
-  bool needs_blending;
-
-  // Stores state common to a large bundle of quads; kept separate for memory
-  // efficiency. There is special treatment to reconstruct these pointers
-  // during serialization.
-  const SharedQuadState* shared_quad_state;
-
-  bool IsDebugQuad() const { return material == DEBUG_BORDER; }
-
-  bool ShouldDrawWithBlending() const {
-    if (needs_blending || shared_quad_state->opacity < 1.0f)
-      return true;
-    if (visible_rect.IsEmpty())
-      return false;
-    return !opaque_rect.Contains(visible_rect);
-  }
-
-  typedef ResourceProvider::ResourceId ResourceId;
-  typedef base::Callback<ResourceId(ResourceId)> ResourceIteratorCallback;
-  virtual void IterateResources(const ResourceIteratorCallback& callback) = 0;
-
-  // Is the left edge of this tile aligned with the originating layer's
-  // left edge?
-  bool IsLeftEdge() const { return !rect.x(); }
-
-  // Is the top edge of this tile aligned with the originating layer's
-  // top edge?
-  bool IsTopEdge() const { return !rect.y(); }
-
-  // Is the right edge of this tile aligned with the originating layer's
-  // right edge?
-  bool IsRightEdge() const {
-    return rect.right() == shared_quad_state->content_bounds.width();
-  }
-
-  // Is the bottom edge of this tile aligned with the originating layer's
-  // bottom edge?
-  bool IsBottomEdge() const {
-    return rect.bottom() == shared_quad_state->content_bounds.height();
-  }
-
-  // Is any edge of this tile aligned with the originating layer's
-  // corresponding edge?
-  bool IsEdge() const {
-    return IsLeftEdge() || IsTopEdge() || IsRightEdge() || IsBottomEdge();
-  }
-
-  void AsValueInto(base::trace_event::TracedValue* value) const;
-
- protected:
-  DrawQuad();
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              Material material,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending);
-  virtual void ExtendValue(base::trace_event::TracedValue* value) const = 0;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_DRAW_QUAD_H_
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc
deleted file mode 100644
index 5b5f0b9..0000000
--- a/cc/quads/draw_quad_unittest.cc
+++ /dev/null
@@ -1,1038 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/draw_quad.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/compiler_specific.h"
-#include "cc/base/math_util.h"
-#include "cc/output/filter_operations.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/largest_draw_quad.h"
-#include "cc/quads/picture_draw_quad.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-#include "cc/test/fake_picture_pile_impl.h"
-#include "cc/test/geometry_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/effects/SkBlurImageFilter.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-namespace {
-
-TEST(DrawQuadTest, CopySharedQuadState) {
-  gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
-  gfx::Size content_bounds(26, 28);
-  gfx::Rect visible_content_rect(10, 12, 14, 16);
-  gfx::Rect clip_rect(19, 21, 23, 25);
-  bool is_clipped = true;
-  float opacity = 0.25f;
-  SkXfermode::Mode blend_mode = SkXfermode::kMultiply_Mode;
-  int sorting_context_id = 65536;
-
-  scoped_ptr<SharedQuadState> state(new SharedQuadState);
-  state->SetAll(quad_transform,
-                content_bounds,
-                visible_content_rect,
-                clip_rect,
-                is_clipped,
-                opacity,
-                blend_mode,
-                sorting_context_id);
-
-  scoped_ptr<SharedQuadState> copy(new SharedQuadState);
-  copy->CopyFrom(state.get());
-  EXPECT_EQ(quad_transform, copy->content_to_target_transform);
-  EXPECT_EQ(visible_content_rect, copy->visible_content_rect);
-  EXPECT_EQ(opacity, copy->opacity);
-  EXPECT_EQ(clip_rect, copy->clip_rect);
-  EXPECT_EQ(is_clipped, copy->is_clipped);
-  EXPECT_EQ(blend_mode, copy->blend_mode);
-}
-
-SharedQuadState* CreateSharedQuadState(RenderPass* render_pass) {
-  gfx::Transform quad_transform = gfx::Transform(1.0, 0.0, 0.5, 1.0, 0.5, 0.0);
-  gfx::Size content_bounds(26, 28);
-  gfx::Rect visible_content_rect(10, 12, 14, 16);
-  gfx::Rect clip_rect(19, 21, 23, 25);
-  bool is_clipped = false;
-  float opacity = 1.f;
-  int sorting_context_id = 65536;
-  SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-
-  SharedQuadState* state = render_pass->CreateAndAppendSharedQuadState();
-  state->SetAll(quad_transform,
-                content_bounds,
-                visible_content_rect,
-                clip_rect,
-                is_clipped,
-                opacity,
-                blend_mode,
-                sorting_context_id);
-  return state;
-}
-
-void CompareDrawQuad(DrawQuad* quad,
-                     DrawQuad* copy,
-                     SharedQuadState* copy_shared_state) {
-  EXPECT_EQ(quad->material, copy->material);
-  EXPECT_EQ(quad->rect, copy->rect);
-  EXPECT_EQ(quad->visible_rect, copy->visible_rect);
-  EXPECT_EQ(quad->opaque_rect, copy->opaque_rect);
-  EXPECT_EQ(quad->needs_blending, copy->needs_blending);
-  EXPECT_EQ(copy_shared_state, copy->shared_quad_state);
-}
-
-#define CREATE_SHARED_STATE()                                              \
-  scoped_ptr<RenderPass> render_pass = RenderPass::Create();               \
-  SharedQuadState* shared_state(CreateSharedQuadState(render_pass.get())); \
-  SharedQuadState* copy_shared_state =                                     \
-      render_pass->CreateAndAppendSharedQuadState();                       \
-  copy_shared_state->CopyFrom(shared_state);
-
-#define QUAD_DATA                              \
-  gfx::Rect quad_rect(30, 40, 50, 60);         \
-  gfx::Rect quad_visible_rect(40, 50, 30, 20); \
-  gfx::Rect quad_opaque_rect(60, 55, 10, 10);  \
-  ALLOW_UNUSED_LOCAL(quad_opaque_rect);        \
-  bool needs_blending = true;                  \
-  ALLOW_UNUSED_LOCAL(needs_blending);
-
-#define SETUP_AND_COPY_QUAD_NEW(Type, quad)                                \
-  DrawQuad* copy_new =                                                     \
-      render_pass->CopyFromAndAppendDrawQuad(quad_new, copy_shared_state); \
-  CompareDrawQuad(quad_new, copy_new, copy_shared_state);                  \
-  const Type* copy_quad = Type::MaterialCast(copy_new);                    \
-  ALLOW_UNUSED_LOCAL(copy_quad);
-
-#define SETUP_AND_COPY_QUAD_ALL(Type, quad)                                \
-  DrawQuad* copy_all =                                                     \
-      render_pass->CopyFromAndAppendDrawQuad(quad_all, copy_shared_state); \
-  CompareDrawQuad(quad_all, copy_all, copy_shared_state);                  \
-  copy_quad = Type::MaterialCast(copy_all);
-
-#define SETUP_AND_COPY_QUAD_NEW_RP(Type, quad, a)                        \
-  DrawQuad* copy_new = render_pass->CopyFromAndAppendRenderPassDrawQuad( \
-      quad_new, copy_shared_state, a);                                   \
-  CompareDrawQuad(quad_new, copy_new, copy_shared_state);                \
-  const Type* copy_quad = Type::MaterialCast(copy_new);                  \
-  ALLOW_UNUSED_LOCAL(copy_quad);
-
-#define SETUP_AND_COPY_QUAD_ALL_RP(Type, quad, a)                        \
-  DrawQuad* copy_all = render_pass->CopyFromAndAppendRenderPassDrawQuad( \
-      quad_all, copy_shared_state, a);                                   \
-  CompareDrawQuad(quad_all, copy_all, copy_shared_state);                \
-  copy_quad = Type::MaterialCast(copy_all);
-
-#define CREATE_QUAD_1_NEW(Type, a)                               \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a); }    \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_1_ALL(Type, a)                               \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_2_NEW(Type, a, b)                            \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b); } \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_2_ALL(Type, a, b)                            \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_3_NEW(Type, a, b, c)                            \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>();    \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c); } \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_3_ALL(Type, a, b, c)                         \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_4_NEW(Type, a, b, c, d)                            \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>();       \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d); } \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_4_ALL(Type, a, b, c, d)                      \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_5_NEW(Type, a, b, c, d, e)                            \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>();          \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e); } \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_5_ALL(Type, a, b, c, d, e)                   \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d,                                \
-                               e);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_6_NEW(Type, a, b, c, d, e, f)                            \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>();             \
-  { QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e, f); } \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_6_ALL(Type, a, b, c, d, e, f)                \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d,                                \
-                               e,                                \
-                               f);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_7_NEW(Type, a, b, c, d, e, f, g)                          \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>();              \
-  {                                                                           \
-    QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e, f, g); \
-  }                                                                           \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_7_ALL(Type, a, b, c, d, e, f, g)             \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d,                                \
-                               e,                                \
-                               f,                                \
-                               g);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_8_NEW(Type, a, b, c, d, e, f, g, h)          \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_new->SetNew(                                  \
-        shared_state, quad_rect, a, b, c, d, e, f, g, h);        \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_8_ALL(Type, a, b, c, d, e, f, g, h)          \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d,                                \
-                               e,                                \
-                               f,                                \
-                               g,                                \
-                               h);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_9_NEW(Type, a, b, c, d, e, f, g, h, i)       \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_new->SetNew(                                  \
-        shared_state, quad_rect, a, b, c, d, e, f, g, h, i);     \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_9_ALL(Type, a, b, c, d, e, f, g, h, i) \
-  {                                                        \
-    QUAD_DATA quad_all->SetAll(shared_state,               \
-                               quad_rect,                  \
-                               quad_opaque_rect,           \
-                               quad_visible_rect,          \
-                               needs_blending,             \
-                               a,                          \
-                               b,                          \
-                               c,                          \
-                               d,                          \
-                               e,                          \
-                               f,                          \
-                               g,                          \
-                               h,                          \
-                               i);                         \
-  }                                                        \
-  SETUP_AND_COPY_QUAD_ALL(Type, quad_all);
-
-#define CREATE_QUAD_10_NEW(Type, a, b, c, d, e, f, g, h, i, j)   \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_new->SetNew(                                  \
-        shared_state, quad_rect, a, b, c, d, e, f, g, h, i, j);  \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_NEW(Type, quad_new);
-
-#define CREATE_QUAD_ALL_RP(Type, a, b, c, d, e, f, g, copy_a)    \
-  Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_all->SetAll(shared_state,                     \
-                               quad_rect,                        \
-                               quad_opaque_rect,                 \
-                               quad_visible_rect,                \
-                               needs_blending,                   \
-                               a,                                \
-                               b,                                \
-                               c,                                \
-                               d,                                \
-                               e,                                \
-                               f,                                \
-                               g);                               \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_ALL_RP(Type, quad_all, copy_a);
-
-#define CREATE_QUAD_NEW_RP(Type, a, b, c, d, e, f, g, h, copy_a) \
-  Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \
-  {                                                              \
-    QUAD_DATA quad_new->SetNew(                                  \
-        shared_state, quad_rect, a, b, c, d, e, f, g, h);        \
-  }                                                              \
-  SETUP_AND_COPY_QUAD_NEW_RP(Type, quad_new, copy_a);
-
-TEST(DrawQuadTest, CopyCheckerboardDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0xfabb0011;
-  float scale = 2.3f;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_3_NEW(CheckerboardDrawQuad, visible_rect, color, scale);
-  EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(scale, copy_quad->scale);
-
-  CREATE_QUAD_2_ALL(CheckerboardDrawQuad, color, scale);
-  EXPECT_EQ(DrawQuad::CHECKERBOARD, copy_quad->material);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(scale, copy_quad->scale);
-}
-
-TEST(DrawQuadTest, CopyDebugBorderDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0xfabb0011;
-  int width = 99;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_3_NEW(DebugBorderDrawQuad, visible_rect, color, width);
-  EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(width, copy_quad->width);
-
-  CREATE_QUAD_2_ALL(DebugBorderDrawQuad, color, width);
-  EXPECT_EQ(DrawQuad::DEBUG_BORDER, copy_quad->material);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(width, copy_quad->width);
-}
-
-TEST(DrawQuadTest, CopyIOSurfaceDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::Size size(58, 95);
-  ResourceProvider::ResourceId resource_id = 72;
-  IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_5_NEW(IOSurfaceDrawQuad,
-                    opaque_rect,
-                    visible_rect,
-                    size,
-                    resource_id,
-                    orientation);
-  EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(size, copy_quad->io_surface_size);
-  EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
-  EXPECT_EQ(orientation, copy_quad->orientation);
-
-  CREATE_QUAD_3_ALL(IOSurfaceDrawQuad, size, resource_id, orientation);
-  EXPECT_EQ(DrawQuad::IO_SURFACE_CONTENT, copy_quad->material);
-  EXPECT_EQ(size, copy_quad->io_surface_size);
-  EXPECT_EQ(resource_id, copy_quad->io_surface_resource_id);
-  EXPECT_EQ(orientation, copy_quad->orientation);
-}
-
-TEST(DrawQuadTest, CopyRenderPassDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  RenderPassId render_pass_id(22, 64);
-  ResourceProvider::ResourceId mask_resource_id = 78;
-  gfx::Vector2dF mask_uv_scale(33.f, 19.f);
-  gfx::Size mask_texture_size(128, 134);
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateBlurFilter(1.f));
-  gfx::Vector2dF filters_scale;
-  FilterOperations background_filters;
-  background_filters.Append(
-      FilterOperation::CreateGrayscaleFilter(1.f));
-
-  RenderPassId copied_render_pass_id(235, 11);
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_NEW_RP(RenderPassDrawQuad,
-                     visible_rect,
-                     render_pass_id,
-                     mask_resource_id,
-                     mask_uv_scale,
-                     mask_texture_size,
-                     filters,
-                     filters_scale,
-                     background_filters,
-                     copied_render_pass_id);
-  EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
-  EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
-  EXPECT_EQ(mask_uv_scale.ToString(), copy_quad->mask_uv_scale.ToString());
-  EXPECT_EQ(mask_texture_size.ToString(),
-            copy_quad->mask_texture_size.ToString());
-  EXPECT_EQ(filters, copy_quad->filters);
-  EXPECT_EQ(filters_scale, copy_quad->filters_scale);
-  EXPECT_EQ(background_filters, copy_quad->background_filters);
-
-  CREATE_QUAD_ALL_RP(RenderPassDrawQuad,
-                     render_pass_id,
-                     mask_resource_id,
-                     mask_uv_scale,
-                     mask_texture_size,
-                     filters,
-                     filters_scale,
-                     background_filters,
-                     copied_render_pass_id);
-  EXPECT_EQ(DrawQuad::RENDER_PASS, copy_quad->material);
-  EXPECT_EQ(copied_render_pass_id, copy_quad->render_pass_id);
-  EXPECT_EQ(mask_resource_id, copy_quad->mask_resource_id);
-  EXPECT_EQ(mask_uv_scale.ToString(), copy_quad->mask_uv_scale.ToString());
-  EXPECT_EQ(mask_texture_size.ToString(),
-            copy_quad->mask_texture_size.ToString());
-  EXPECT_EQ(filters, copy_quad->filters);
-  EXPECT_EQ(filters_scale, copy_quad->filters_scale);
-  EXPECT_EQ(background_filters, copy_quad->background_filters);
-}
-
-TEST(DrawQuadTest, CopySolidColorDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0x49494949;
-  bool force_anti_aliasing_off = false;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_3_NEW(
-      SolidColorDrawQuad, visible_rect, color, force_anti_aliasing_off);
-  EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off);
-
-  CREATE_QUAD_2_ALL(SolidColorDrawQuad, color, force_anti_aliasing_off);
-  EXPECT_EQ(DrawQuad::SOLID_COLOR, copy_quad->material);
-  EXPECT_EQ(color, copy_quad->color);
-  EXPECT_EQ(force_anti_aliasing_off, copy_quad->force_anti_aliasing_off);
-}
-
-TEST(DrawQuadTest, CopyStreamVideoDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  ResourceProvider::ResourceId resource_id = 64;
-  gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_4_NEW(
-      StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id, matrix);
-  EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(matrix, copy_quad->matrix);
-
-  CREATE_QUAD_2_ALL(StreamVideoDrawQuad, resource_id, matrix);
-  EXPECT_EQ(DrawQuad::STREAM_VIDEO_CONTENT, copy_quad->material);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(matrix, copy_quad->matrix);
-}
-
-TEST(DrawQuadTest, CopySurfaceDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SurfaceId surface_id(1234);
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_2_NEW(SurfaceDrawQuad, visible_rect, surface_id);
-  EXPECT_EQ(DrawQuad::SURFACE_CONTENT, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(surface_id, copy_quad->surface_id);
-
-  CREATE_QUAD_1_ALL(SurfaceDrawQuad, surface_id);
-  EXPECT_EQ(DrawQuad::SURFACE_CONTENT, copy_quad->material);
-  EXPECT_EQ(surface_id, copy_quad->surface_id);
-}
-
-
-TEST(DrawQuadTest, CopyTextureDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  unsigned resource_id = 82;
-  bool premultiplied_alpha = true;
-  gfx::PointF uv_top_left(0.5f, 224.f);
-  gfx::PointF uv_bottom_right(51.5f, 260.f);
-  const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f };
-  bool flipped = true;
-  bool nearest_neighbor = true;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_10_NEW(TextureDrawQuad,
-                     opaque_rect,
-                     visible_rect,
-                     resource_id,
-                     premultiplied_alpha,
-                     uv_top_left,
-                     uv_bottom_right,
-                     SK_ColorTRANSPARENT,
-                     vertex_opacity,
-                     flipped,
-                     nearest_neighbor);
-  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
-  EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
-  EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
-  EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
-  EXPECT_EQ(flipped, copy_quad->flipped);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-
-  CREATE_QUAD_8_ALL(TextureDrawQuad,
-                    resource_id,
-                    premultiplied_alpha,
-                    uv_top_left,
-                    uv_bottom_right,
-                    SK_ColorTRANSPARENT,
-                    vertex_opacity,
-                    flipped,
-                    nearest_neighbor);
-  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, copy_quad->material);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(premultiplied_alpha, copy_quad->premultiplied_alpha);
-  EXPECT_EQ(uv_top_left, copy_quad->uv_top_left);
-  EXPECT_EQ(uv_bottom_right, copy_quad->uv_bottom_right);
-  EXPECT_FLOAT_ARRAY_EQ(vertex_opacity, copy_quad->vertex_opacity, 4);
-  EXPECT_EQ(flipped, copy_quad->flipped);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-}
-
-TEST(DrawQuadTest, CopyTileDrawQuad) {
-  gfx::Rect opaque_rect(33, 44, 22, 33);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  unsigned resource_id = 104;
-  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
-  gfx::Size texture_size(85, 32);
-  bool swizzle_contents = true;
-  bool nearest_neighbor = true;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_7_NEW(TileDrawQuad,
-                    opaque_rect,
-                    visible_rect,
-                    resource_id,
-                    tex_coord_rect,
-                    texture_size,
-                    swizzle_contents,
-                    nearest_neighbor);
-  EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(texture_size, copy_quad->texture_size);
-  EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-
-  CREATE_QUAD_5_ALL(TileDrawQuad,
-                    resource_id,
-                    tex_coord_rect,
-                    texture_size,
-                    swizzle_contents,
-                    nearest_neighbor);
-  EXPECT_EQ(DrawQuad::TILED_CONTENT, copy_quad->material);
-  EXPECT_EQ(resource_id, copy_quad->resource_id);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(texture_size, copy_quad->texture_size);
-  EXPECT_EQ(swizzle_contents, copy_quad->swizzle_contents);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-}
-
-TEST(DrawQuadTest, CopyYUVVideoDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::RectF tex_coord_rect(0.0f, 0.0f, 0.75f, 0.5f);
-  gfx::Size tex_size(32, 68);
-  ResourceProvider::ResourceId y_plane_resource_id = 45;
-  ResourceProvider::ResourceId u_plane_resource_id = 532;
-  ResourceProvider::ResourceId v_plane_resource_id = 4;
-  ResourceProvider::ResourceId a_plane_resource_id = 63;
-  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG;
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_9_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
-                    tex_size, y_plane_resource_id, u_plane_resource_id,
-                    v_plane_resource_id, a_plane_resource_id, color_space);
-  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(tex_size, copy_quad->tex_size);
-  EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
-  EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
-  EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
-  EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
-  EXPECT_EQ(color_space, copy_quad->color_space);
-
-  CREATE_QUAD_7_ALL(YUVVideoDrawQuad, tex_coord_rect, tex_size,
-                    y_plane_resource_id, u_plane_resource_id,
-                    v_plane_resource_id, a_plane_resource_id, color_space);
-  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(tex_size, copy_quad->tex_size);
-  EXPECT_EQ(y_plane_resource_id, copy_quad->y_plane_resource_id);
-  EXPECT_EQ(u_plane_resource_id, copy_quad->u_plane_resource_id);
-  EXPECT_EQ(v_plane_resource_id, copy_quad->v_plane_resource_id);
-  EXPECT_EQ(a_plane_resource_id, copy_quad->a_plane_resource_id);
-  EXPECT_EQ(color_space, copy_quad->color_space);
-}
-
-TEST(DrawQuadTest, CopyPictureDrawQuad) {
-  gfx::Rect opaque_rect(33, 44, 22, 33);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
-  gfx::Size texture_size(85, 32);
-  bool nearest_neighbor = true;
-  ResourceFormat texture_format = RGBA_8888;
-  gfx::Rect content_rect(30, 40, 20, 30);
-  float contents_scale = 3.141592f;
-  scoped_refptr<RasterSource> raster_source =
-      FakePicturePileImpl::CreateEmptyPile(gfx::Size(100, 100),
-                                           gfx::Size(100, 100));
-  CREATE_SHARED_STATE();
-
-  CREATE_QUAD_9_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
-                    texture_size, nearest_neighbor, texture_format,
-                    content_rect, contents_scale, raster_source);
-  EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material);
-  EXPECT_EQ(opaque_rect, copy_quad->opaque_rect);
-  EXPECT_EQ(visible_rect, copy_quad->visible_rect);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(texture_size, copy_quad->texture_size);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-  EXPECT_EQ(texture_format, copy_quad->texture_format);
-  EXPECT_EQ(content_rect, copy_quad->content_rect);
-  EXPECT_EQ(contents_scale, copy_quad->contents_scale);
-  EXPECT_EQ(raster_source, copy_quad->raster_source);
-
-  CREATE_QUAD_7_ALL(PictureDrawQuad, tex_coord_rect, texture_size,
-                    nearest_neighbor, texture_format, content_rect,
-                    contents_scale, raster_source);
-  EXPECT_EQ(DrawQuad::PICTURE_CONTENT, copy_quad->material);
-  EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
-  EXPECT_EQ(texture_size, copy_quad->texture_size);
-  EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-  EXPECT_EQ(texture_format, copy_quad->texture_format);
-  EXPECT_EQ(content_rect, copy_quad->content_rect);
-  EXPECT_EQ(contents_scale, copy_quad->contents_scale);
-  EXPECT_EQ(raster_source, copy_quad->raster_source);
-}
-
-class DrawQuadIteratorTest : public testing::Test {
- protected:
-  ResourceProvider::ResourceId IncrementResourceId(
-      ResourceProvider::ResourceId id) {
-    ++num_resources_;
-    return id + 1;
-  }
-
-  int IterateAndCount(DrawQuad* quad) {
-    num_resources_ = 0;
-    quad->IterateResources(base::Bind(
-        &DrawQuadIteratorTest::IncrementResourceId, base::Unretained(this)));
-    return num_resources_;
-  }
-
- private:
-  int num_resources_;
-};
-
-TEST_F(DrawQuadIteratorTest, CheckerboardDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0xfabb0011;
-  float scale = 3.2f;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_3_NEW(CheckerboardDrawQuad, visible_rect, color, scale);
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-}
-
-TEST_F(DrawQuadIteratorTest, DebugBorderDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0xfabb0011;
-  int width = 99;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_3_NEW(DebugBorderDrawQuad, visible_rect, color, width);
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-}
-
-TEST_F(DrawQuadIteratorTest, IOSurfaceDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::Size size(58, 95);
-  ResourceProvider::ResourceId resource_id = 72;
-  IOSurfaceDrawQuad::Orientation orientation = IOSurfaceDrawQuad::UNFLIPPED;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_5_NEW(IOSurfaceDrawQuad,
-                    opaque_rect,
-                    visible_rect,
-                    size,
-                    resource_id,
-                    orientation);
-  EXPECT_EQ(resource_id, quad_new->io_surface_resource_id);
-  EXPECT_EQ(1, IterateAndCount(quad_new));
-  EXPECT_EQ(resource_id + 1, quad_new->io_surface_resource_id);
-}
-
-TEST_F(DrawQuadIteratorTest, RenderPassDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  RenderPassId render_pass_id(22, 64);
-  ResourceProvider::ResourceId mask_resource_id = 78;
-  gfx::Vector2dF mask_uv_scale(33.f, 19.f);
-  gfx::Size mask_texture_size(128, 134);
-  FilterOperations filters;
-  filters.Append(FilterOperation::CreateBlurFilter(1.f));
-  gfx::Vector2dF filters_scale(2.f, 3.f);
-  FilterOperations background_filters;
-  background_filters.Append(
-      FilterOperation::CreateGrayscaleFilter(1.f));
-
-  RenderPassId copied_render_pass_id(235, 11);
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_NEW_RP(RenderPassDrawQuad,
-                     visible_rect,
-                     render_pass_id,
-                     mask_resource_id,
-                     mask_uv_scale,
-                     mask_texture_size,
-                     filters,
-                     filters_scale,
-                     background_filters,
-                     copied_render_pass_id);
-  EXPECT_EQ(mask_resource_id, quad_new->mask_resource_id);
-  EXPECT_EQ(1, IterateAndCount(quad_new));
-  EXPECT_EQ(mask_resource_id + 1, quad_new->mask_resource_id);
-  quad_new->mask_resource_id = 0;
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-  EXPECT_EQ(0u, quad_new->mask_resource_id);
-}
-
-TEST_F(DrawQuadIteratorTest, SolidColorDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SkColor color = 0x49494949;
-  bool force_anti_aliasing_off = false;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_3_NEW(
-      SolidColorDrawQuad, visible_rect, color, force_anti_aliasing_off);
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-}
-
-TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  ResourceProvider::ResourceId resource_id = 64;
-  gfx::Transform matrix = gfx::Transform(0.5, 0.25, 1, 0.75, 0, 1);
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_4_NEW(
-      StreamVideoDrawQuad, opaque_rect, visible_rect, resource_id, matrix);
-  EXPECT_EQ(resource_id, quad_new->resource_id);
-  EXPECT_EQ(1, IterateAndCount(quad_new));
-  EXPECT_EQ(resource_id + 1, quad_new->resource_id);
-}
-
-TEST_F(DrawQuadIteratorTest, SurfaceDrawQuad) {
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  SurfaceId surface_id(4321);
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_2_NEW(SurfaceDrawQuad, visible_rect, surface_id);
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-}
-
-TEST_F(DrawQuadIteratorTest, TextureDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  unsigned resource_id = 82;
-  bool premultiplied_alpha = true;
-  gfx::PointF uv_top_left(0.5f, 224.f);
-  gfx::PointF uv_bottom_right(51.5f, 260.f);
-  const float vertex_opacity[] = { 1.0f, 1.0f, 1.0f, 1.0f };
-  bool flipped = true;
-  bool nearest_neighbor = true;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_10_NEW(TextureDrawQuad,
-                     opaque_rect,
-                     visible_rect,
-                     resource_id,
-                     premultiplied_alpha,
-                     uv_top_left,
-                     uv_bottom_right,
-                     SK_ColorTRANSPARENT,
-                     vertex_opacity,
-                     flipped,
-                     nearest_neighbor);
-  EXPECT_EQ(resource_id, quad_new->resource_id);
-  EXPECT_EQ(1, IterateAndCount(quad_new));
-  EXPECT_EQ(resource_id + 1, quad_new->resource_id);
-}
-
-TEST_F(DrawQuadIteratorTest, TileDrawQuad) {
-  gfx::Rect opaque_rect(33, 44, 22, 33);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  unsigned resource_id = 104;
-  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
-  gfx::Size texture_size(85, 32);
-  bool swizzle_contents = true;
-  bool nearest_neighbor = true;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_7_NEW(TileDrawQuad,
-                    opaque_rect,
-                    visible_rect,
-                    resource_id,
-                    tex_coord_rect,
-                    texture_size,
-                    swizzle_contents,
-                    nearest_neighbor);
-  EXPECT_EQ(resource_id, quad_new->resource_id);
-  EXPECT_EQ(1, IterateAndCount(quad_new));
-  EXPECT_EQ(resource_id + 1, quad_new->resource_id);
-}
-
-TEST_F(DrawQuadIteratorTest, YUVVideoDrawQuad) {
-  gfx::Rect opaque_rect(33, 47, 10, 12);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::RectF tex_coord_rect(0.0f, 0.0f, 0.75f, 0.5f);
-  gfx::Size tex_size(32, 68);
-  ResourceProvider::ResourceId y_plane_resource_id = 45;
-  ResourceProvider::ResourceId u_plane_resource_id = 532;
-  ResourceProvider::ResourceId v_plane_resource_id = 4;
-  ResourceProvider::ResourceId a_plane_resource_id = 63;
-  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG;
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_9_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
-                    tex_size, y_plane_resource_id, u_plane_resource_id,
-                    v_plane_resource_id, a_plane_resource_id, color_space);
-  EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material);
-  EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id);
-  EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id);
-  EXPECT_EQ(v_plane_resource_id, quad_new->v_plane_resource_id);
-  EXPECT_EQ(a_plane_resource_id, quad_new->a_plane_resource_id);
-  EXPECT_EQ(color_space, quad_new->color_space);
-  EXPECT_EQ(4, IterateAndCount(quad_new));
-  EXPECT_EQ(y_plane_resource_id + 1, quad_new->y_plane_resource_id);
-  EXPECT_EQ(u_plane_resource_id + 1, quad_new->u_plane_resource_id);
-  EXPECT_EQ(v_plane_resource_id + 1, quad_new->v_plane_resource_id);
-  EXPECT_EQ(a_plane_resource_id + 1, quad_new->a_plane_resource_id);
-}
-
-// Disabled until picture draw quad is supported for ubercomp: crbug.com/231715
-TEST_F(DrawQuadIteratorTest, DISABLED_PictureDrawQuad) {
-  gfx::Rect opaque_rect(33, 44, 22, 33);
-  gfx::Rect visible_rect(40, 50, 30, 20);
-  gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
-  gfx::Size texture_size(85, 32);
-  bool nearest_neighbor = true;
-  ResourceFormat texture_format = RGBA_8888;
-  gfx::Rect content_rect(30, 40, 20, 30);
-  float contents_scale = 3.141592f;
-  scoped_refptr<RasterSource> raster_source =
-      FakePicturePileImpl::CreateEmptyPile(gfx::Size(100, 100),
-                                           gfx::Size(100, 100));
-
-  CREATE_SHARED_STATE();
-  CREATE_QUAD_9_NEW(PictureDrawQuad, opaque_rect, visible_rect, tex_coord_rect,
-                    texture_size, nearest_neighbor, texture_format,
-                    content_rect, contents_scale, raster_source);
-  EXPECT_EQ(0, IterateAndCount(quad_new));
-}
-
-TEST(DrawQuadTest, LargestQuadType) {
-  size_t largest = 0;
-
-  for (int i = 0; i <= DrawQuad::MATERIAL_LAST; ++i) {
-    switch (static_cast<DrawQuad::Material>(i)) {
-      case DrawQuad::CHECKERBOARD:
-        largest = std::max(largest, sizeof(CheckerboardDrawQuad));
-        break;
-      case DrawQuad::DEBUG_BORDER:
-        largest = std::max(largest, sizeof(DebugBorderDrawQuad));
-        break;
-      case DrawQuad::IO_SURFACE_CONTENT:
-        largest = std::max(largest, sizeof(IOSurfaceDrawQuad));
-        break;
-      case DrawQuad::PICTURE_CONTENT:
-        largest = std::max(largest, sizeof(PictureDrawQuad));
-        break;
-      case DrawQuad::TEXTURE_CONTENT:
-        largest = std::max(largest, sizeof(TextureDrawQuad));
-        break;
-      case DrawQuad::RENDER_PASS:
-        largest = std::max(largest, sizeof(RenderPassDrawQuad));
-        break;
-      case DrawQuad::SOLID_COLOR:
-        largest = std::max(largest, sizeof(SolidColorDrawQuad));
-        break;
-      case DrawQuad::SURFACE_CONTENT:
-        largest = std::max(largest, sizeof(SurfaceDrawQuad));
-        break;
-      case DrawQuad::TILED_CONTENT:
-        largest = std::max(largest, sizeof(TileDrawQuad));
-        break;
-      case DrawQuad::STREAM_VIDEO_CONTENT:
-        largest = std::max(largest, sizeof(StreamVideoDrawQuad));
-        break;
-      case DrawQuad::YUV_VIDEO_CONTENT:
-        largest = std::max(largest, sizeof(YUVVideoDrawQuad));
-        break;
-      case DrawQuad::INVALID:
-        break;
-    }
-  }
-  EXPECT_EQ(LargestDrawQuadSize(), largest);
-
-  if (!HasFailure())
-    return;
-
-  // On failure, output the size of all quads for debugging.
-  LOG(ERROR) << "largest " << largest;
-  LOG(ERROR) << "kLargestDrawQuad " << LargestDrawQuadSize();
-  for (int i = 0; i <= DrawQuad::MATERIAL_LAST; ++i) {
-    switch (static_cast<DrawQuad::Material>(i)) {
-      case DrawQuad::CHECKERBOARD:
-        LOG(ERROR) << "CheckerboardDrawQuad " << sizeof(CheckerboardDrawQuad);
-        break;
-      case DrawQuad::DEBUG_BORDER:
-        LOG(ERROR) << "DebugBorderDrawQuad " << sizeof(DebugBorderDrawQuad);
-        break;
-      case DrawQuad::IO_SURFACE_CONTENT:
-        LOG(ERROR) << "IOSurfaceDrawQuad " << sizeof(IOSurfaceDrawQuad);
-        break;
-      case DrawQuad::PICTURE_CONTENT:
-        LOG(ERROR) << "PictureDrawQuad " << sizeof(PictureDrawQuad);
-        break;
-      case DrawQuad::TEXTURE_CONTENT:
-        LOG(ERROR) << "TextureDrawQuad " << sizeof(TextureDrawQuad);
-        break;
-      case DrawQuad::RENDER_PASS:
-        LOG(ERROR) << "RenderPassDrawQuad " << sizeof(RenderPassDrawQuad);
-        break;
-      case DrawQuad::SOLID_COLOR:
-        LOG(ERROR) << "SolidColorDrawQuad " << sizeof(SolidColorDrawQuad);
-        break;
-      case DrawQuad::SURFACE_CONTENT:
-        LOG(ERROR) << "SurfaceDrawQuad " << sizeof(SurfaceDrawQuad);
-        break;
-      case DrawQuad::TILED_CONTENT:
-        LOG(ERROR) << "TileDrawQuad " << sizeof(TileDrawQuad);
-        break;
-      case DrawQuad::STREAM_VIDEO_CONTENT:
-        LOG(ERROR) << "StreamVideoDrawQuad " << sizeof(StreamVideoDrawQuad);
-        break;
-      case DrawQuad::YUV_VIDEO_CONTENT:
-        LOG(ERROR) << "YUVVideoDrawQuad " << sizeof(YUVVideoDrawQuad);
-        break;
-      case DrawQuad::INVALID:
-        break;
-    }
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/quads/io_surface_draw_quad.cc b/cc/quads/io_surface_draw_quad.cc
deleted file mode 100644
index 8a37b0a..0000000
--- a/cc/quads/io_surface_draw_quad.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/io_surface_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-
-namespace cc {
-
-IOSurfaceDrawQuad::IOSurfaceDrawQuad()
-    : io_surface_resource_id(0),
-      orientation(FLIPPED) {
-}
-
-void IOSurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                               const gfx::Rect& rect,
-                               const gfx::Rect& opaque_rect,
-                               const gfx::Rect& visible_rect,
-                               const gfx::Size& io_surface_size,
-                               unsigned io_surface_resource_id,
-                               Orientation orientation) {
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->io_surface_size = io_surface_size;
-  this->io_surface_resource_id = io_surface_resource_id;
-  this->orientation = orientation;
-}
-
-void IOSurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                               const gfx::Rect& rect,
-                               const gfx::Rect& opaque_rect,
-                               const gfx::Rect& visible_rect,
-                               bool needs_blending,
-                               const gfx::Size& io_surface_size,
-                               unsigned io_surface_resource_id,
-                               Orientation orientation) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::IO_SURFACE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->io_surface_size = io_surface_size;
-  this->io_surface_resource_id = io_surface_resource_id;
-  this->orientation = orientation;
-}
-
-void IOSurfaceDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  io_surface_resource_id = callback.Run(io_surface_resource_id);
-}
-
-const IOSurfaceDrawQuad* IOSurfaceDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::IO_SURFACE_CONTENT);
-  return static_cast<const IOSurfaceDrawQuad*>(quad);
-}
-
-void IOSurfaceDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  MathUtil::AddToTracedValue("io_surface_size", io_surface_size, value);
-
-  value->SetInteger("io_surface_resource_id", io_surface_resource_id);
-  const char* orientation_string = NULL;
-  switch (orientation) {
-    case FLIPPED:
-      orientation_string = "flipped";
-      break;
-    case UNFLIPPED:
-      orientation_string = "unflipped";
-      break;
-  }
-
-  value->SetString("orientation", orientation_string);
-}
-
-}  // namespace cc
diff --git a/cc/quads/io_surface_draw_quad.h b/cc/quads/io_surface_draw_quad.h
deleted file mode 100644
index 61cde82..0000000
--- a/cc/quads/io_surface_draw_quad.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_IO_SURFACE_DRAW_QUAD_H_
-#define CC_QUADS_IO_SURFACE_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class IOSurfaceDrawQuad : public DrawQuad {
- public:
-  enum Orientation {
-    FLIPPED,
-    UNFLIPPED,
-    ORIENTATION_LAST = UNFLIPPED
-  };
-
-  IOSurfaceDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              const gfx::Size& io_surface_size,
-              unsigned io_surface_resource_id,
-              Orientation orientation);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              const gfx::Size& io_surface_size,
-              unsigned io_surface_resource_id,
-              Orientation orientation);
-
-  gfx::Size io_surface_size;
-  unsigned io_surface_resource_id;
-  Orientation orientation;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const IOSurfaceDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_IO_SURFACE_DRAW_QUAD_H_
diff --git a/cc/quads/largest_draw_quad.cc b/cc/quads/largest_draw_quad.cc
deleted file mode 100644
index fd7fdb3..0000000
--- a/cc/quads/largest_draw_quad.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/largest_draw_quad.h"
-
-#include <algorithm>
-
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-
-namespace {
-const size_t kLargestDrawQuadSize =
-    sizeof(cc::RenderPassDrawQuad) > sizeof(cc::StreamVideoDrawQuad)
-        ? sizeof(cc::RenderPassDrawQuad)
-        : sizeof(cc::StreamVideoDrawQuad);
-}  // namespace
-
-namespace cc {
-
-size_t LargestDrawQuadSize() {
-  // Currently the largest quad is either a RenderPassDrawQuad or a
-  // StreamVideoDrawQuad depends on hardware structure.
-
-  // Use compile assert to make sure largest is actually larger than all other
-  // type of draw quads.
-  static_assert(sizeof(CheckerboardDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. CheckerboardDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(DebugBorderDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. DebugBorderDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(IOSurfaceDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. IOSurfaceDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(TextureDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. TextureDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(SolidColorDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. SolidColorDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(SurfaceDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. SurfaceDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(TileDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. TileDrawQuad is "
-                "currently largest.");
-  static_assert(sizeof(YUVVideoDrawQuad) <= kLargestDrawQuadSize,
-                "Largest Draw Quad size needs update. YUVVideoDrawQuad is "
-                "currently largest.");
-
-  return kLargestDrawQuadSize;
-}
-
-}  // namespace cc
diff --git a/cc/quads/largest_draw_quad.h b/cc/quads/largest_draw_quad.h
deleted file mode 100644
index 0cddb39..0000000
--- a/cc/quads/largest_draw_quad.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_QUADS_LARGEST_DRAW_QUAD_H_
-#define CC_QUADS_LARGEST_DRAW_QUAD_H_
-
-#include "base/basictypes.h"
-
-namespace cc {
-
-size_t LargestDrawQuadSize();
-
-}  // namespace cc
-
-#endif  // CC_QUADS_LARGEST_DRAW_QUAD_H_
diff --git a/cc/quads/list_container.cc b/cc/quads/list_container.cc
deleted file mode 100644
index 04e1c97..0000000
--- a/cc/quads/list_container.cc
+++ /dev/null
@@ -1,684 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/list_container.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-
-namespace {
-const size_t kDefaultNumElementTypesToReserve = 32;
-}  // namespace
-
-namespace cc {
-
-// ListContainerCharAllocator
-////////////////////////////////////////////////////
-// This class deals only with char* and void*. It does allocation and passing
-// out raw pointers, as well as memory deallocation when being destroyed.
-template <typename BaseElementType>
-class ListContainer<BaseElementType>::ListContainerCharAllocator {
- public:
-  // ListContainerCharAllocator::InnerList
-  /////////////////////////////////////////////
-  // This class holds the raw memory chunk, as well as information about its
-  // size and availability.
-  struct InnerList {
-    scoped_ptr<char[]> data;
-    // The number of elements in total the memory can hold. The difference
-    // between capacity and size is the how many more elements this list can
-    // hold.
-    size_t capacity;
-    // The number of elements have been put into this list.
-    size_t size;
-    // The size of each element is in bytes. This is used to move from between
-    // elements' memory locations.
-    size_t step;
-
-    InnerList() : capacity(0), size(0), step(0) {}
-
-    void Erase(char* position) {
-      // Confident that destructor is called by caller of this function. Since
-      // ListContainerCharAllocator does not handle construction after
-      // allocation, it doesn't handle desctrution before deallocation.
-      DCHECK_LE(position, LastElement());
-      DCHECK_GE(position, Begin());
-      char* start = position + step;
-      std::copy(start, End(), position);
-
-      --size;
-      // Decrease capacity to avoid creating not full not last InnerList.
-      --capacity;
-    }
-
-    bool IsFull() { return capacity == size; }
-    size_t NumElementsAvailable() const { return capacity - size; }
-
-    void* AddElement() {
-      DCHECK_LT(size, capacity);
-      ++size;
-      return LastElement();
-    }
-
-    char* Begin() const { return data.get(); }
-    char* End() const { return data.get() + size * step; }
-    char* LastElement() const { return data.get() + (size - 1) * step; }
-    char* ElementAt(size_t index) const { return data.get() + index * step; }
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(InnerList);
-  };
-
-  explicit ListContainerCharAllocator(size_t element_size)
-      : element_size_(element_size),
-        size_(0),
-        list_count_(0),
-        last_list_(NULL) {
-    AllocateNewList(kDefaultNumElementTypesToReserve);
-  }
-
-  ListContainerCharAllocator(size_t element_size, size_t element_count)
-      : element_size_(element_size),
-        size_(0),
-        list_count_(0),
-        last_list_(NULL) {
-    AllocateNewList(element_count > 0 ? element_count
-                                      : kDefaultNumElementTypesToReserve);
-  }
-
-  ~ListContainerCharAllocator() {}
-
-  void* Allocate() {
-    if (last_list_->IsFull())
-      AllocateNewList(last_list_->capacity * 2);
-
-    ++size_;
-    return last_list_->AddElement();
-  }
-
-  size_t element_size() const { return element_size_; }
-  size_t list_count() const { return list_count_; }
-  size_t size() const { return size_; }
-  bool IsEmpty() const { return size() == 0; }
-
-  size_t Capacity() const {
-    size_t capacity_sum = 0;
-    for (typename ScopedPtrVector<InnerList>::const_iterator iter =
-             storage_.begin();
-         iter != storage_.end();
-         ++iter) {
-      capacity_sum += (*iter)->capacity;
-    }
-    return capacity_sum;
-  }
-
-  void Clear() {
-    size_t initial_allocation_size = storage_.front()->capacity;
-    storage_.clear();
-    list_count_ = 0;
-    last_list_ = NULL;
-    size_ = 0;
-    AllocateNewList(initial_allocation_size);
-  }
-
-  void Erase(PositionInListContainerCharAllocator position) {
-    DCHECK_EQ(this, position.ptr_to_container);
-    storage_[position.vector_index]->Erase(position.item_iterator);
-    // TODO(weiliangc): Free the InnerList if it is empty.
-    --size_;
-  }
-
-  InnerList* InnerListById(size_t id) const {
-    DCHECK_LT(id, list_count_);
-    return storage_[id];
-  }
-
-  void AllocateNewList(size_t list_size) {
-    ++list_count_;
-    scoped_ptr<InnerList> new_list(new InnerList);
-    storage_.push_back(new_list.Pass());
-    last_list_ = storage_.back();
-    InnerList* list = last_list_;
-    list->capacity = list_size;
-    list->size = 0;
-    list->step = element_size_;
-    list->data.reset(new char[list->capacity * list->step]);
-  }
-
-  size_t NumAvailableElementsInLastList() const {
-    return last_list_->NumElementsAvailable();
-  }
-
- private:
-  ScopedPtrVector<InnerList> storage_;
-  const size_t element_size_;
-  size_t size_;
-  size_t list_count_;
-  InnerList* last_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(ListContainerCharAllocator);
-};
-
-// PositionInListContainerCharAllocator
-//////////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-    PositionInListContainerCharAllocator(const typename ListContainer<
-        BaseElementType>::PositionInListContainerCharAllocator& other)
-    : ptr_to_container(other.ptr_to_container),
-      vector_index(other.vector_index),
-      item_iterator(other.item_iterator) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-    PositionInListContainerCharAllocator(
-        typename ListContainer<BaseElementType>::ListContainerCharAllocator*
-            container,
-        size_t vector_ind,
-        char* item_iter)
-    : ptr_to_container(container),
-      vector_index(vector_ind),
-      item_iterator(item_iter) {
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-operator==(const typename ListContainer<
-    BaseElementType>::PositionInListContainerCharAllocator& other) const {
-  DCHECK_EQ(ptr_to_container, other.ptr_to_container);
-  return vector_index == other.vector_index &&
-         item_iterator == other.item_iterator;
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::PositionInListContainerCharAllocator::
-operator!=(const typename ListContainer<
-    BaseElementType>::PositionInListContainerCharAllocator& other) const {
-  return !(*this == other);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
-ListContainer<
-    BaseElementType>::PositionInListContainerCharAllocator::Increment() {
-  typename ListContainerCharAllocator::InnerList* list =
-      ptr_to_container->InnerListById(vector_index);
-  if (item_iterator == list->LastElement()) {
-    if (vector_index < ptr_to_container->list_count() - 1) {
-      ++vector_index;
-      item_iterator = ptr_to_container->InnerListById(vector_index)->Begin();
-    } else {
-      item_iterator = NULL;
-    }
-  } else {
-    item_iterator += list->step;
-  }
-  return *this;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::PositionInListContainerCharAllocator
-ListContainer<
-    BaseElementType>::PositionInListContainerCharAllocator::ReverseIncrement() {
-  typename ListContainerCharAllocator::InnerList* list =
-      ptr_to_container->InnerListById(vector_index);
-  if (item_iterator == list->Begin()) {
-    if (vector_index > 0) {
-      --vector_index;
-      item_iterator =
-          ptr_to_container->InnerListById(vector_index)->LastElement();
-    } else {
-      item_iterator = NULL;
-    }
-  } else {
-    item_iterator -= list->step;
-  }
-  return *this;
-}
-
-// ListContainer
-////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer(size_t max_size_for_derived_class)
-    : data_(new ListContainerCharAllocator(max_size_for_derived_class)) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer(
-    size_t max_size_for_derived_class,
-    size_t num_of_elements_to_reserve_for)
-    : data_(new ListContainerCharAllocator(max_size_for_derived_class,
-                                           num_of_elements_to_reserve_for)) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ListContainer()
-    : data_(new ListContainerCharAllocator(sizeof(BaseElementType))) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::~ListContainer() {
-  for (Iterator i = begin(); i != end(); ++i) {
-    i->~BaseElementType();
-  }
-}
-
-template <typename BaseElementType>
-void ListContainer<BaseElementType>::EraseAndInvalidateAllPointers(
-    typename ListContainer<BaseElementType>::Iterator position) {
-  BaseElementType* item = *position;
-  item->~BaseElementType();
-  data_->Erase(position);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::crbegin() const {
-  if (data_->IsEmpty())
-    return ConstReverseIterator(data_.get(), 0, NULL, 0);
-
-  size_t last_id = data_->list_count() - 1;
-  return ConstReverseIterator(
-      data_.get(), last_id, data_->InnerListById(last_id)->LastElement(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::crend() const {
-  return ConstReverseIterator(data_.get(), 0, NULL, size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::rbegin() const {
-  return crbegin();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::rend() const {
-  return crend();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::rbegin() {
-  if (data_->IsEmpty())
-    return ReverseIterator(data_.get(), 0, NULL, 0);
-
-  size_t last_id = data_->list_count() - 1;
-  return ReverseIterator(
-      data_.get(), last_id, data_->InnerListById(last_id)->LastElement(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::rend() {
-  return ReverseIterator(data_.get(), 0, NULL, size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::cbegin() const {
-  if (data_->IsEmpty())
-    return ConstIterator(data_.get(), 0, NULL, 0);
-
-  return ConstIterator(data_.get(), 0, data_->InnerListById(0)->Begin(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::cend() const {
-  if (data_->IsEmpty())
-    return ConstIterator(data_.get(), 0, NULL, size());
-
-  size_t last_id = data_->list_count() - 1;
-  return ConstIterator(data_.get(), last_id, NULL, size());
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::begin() const {
-  return cbegin();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::end() const {
-  return cend();
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::begin() {
-  if (data_->IsEmpty())
-    return Iterator(data_.get(), 0, NULL, 0);
-
-  return Iterator(data_.get(), 0, data_->InnerListById(0)->Begin(), 0);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::end() {
-  if (data_->IsEmpty())
-    return Iterator(data_.get(), 0, NULL, size());
-
-  size_t last_id = data_->list_count() - 1;
-  return Iterator(data_.get(), last_id, NULL, size());
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::front() {
-  Iterator iter = begin();
-  return *iter;
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::back() {
-  ReverseIterator iter = rbegin();
-  return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::front() const {
-  ConstIterator iter = begin();
-  return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::back() const {
-  ConstReverseIterator iter = rbegin();
-  return *iter;
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ElementAt(
-    size_t index) const {
-  DCHECK_LT(index, size());
-  size_t original_index = index;
-  size_t list_index;
-  for (list_index = 0; list_index < data_->list_count(); ++list_index) {
-    size_t current_size = data_->InnerListById(list_index)->size;
-    if (index < current_size)
-      break;
-    index -= current_size;
-  }
-  return *ConstIterator(data_.get(),
-                        list_index,
-                        data_->InnerListById(list_index)->ElementAt(index),
-                        original_index);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ElementAt(size_t index) {
-  DCHECK_LT(index, size());
-  size_t original_index = index;
-  size_t list_index;
-  for (list_index = 0; list_index < data_->list_count(); ++list_index) {
-    size_t current_size = data_->InnerListById(list_index)->size;
-    if (index < current_size)
-      break;
-    index -= current_size;
-  }
-  return *Iterator(data_.get(),
-                   list_index,
-                   data_->InnerListById(list_index)->ElementAt(index),
-                   original_index);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::Allocate(
-    size_t size_of_actual_element_in_bytes) {
-  DCHECK_LE(size_of_actual_element_in_bytes, data_->element_size());
-  void* result = data_->Allocate();
-  return static_cast<BaseElementType*>(result);
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::size() const {
-  return data_->size();
-}
-
-template <typename BaseElementType>
-bool ListContainer<BaseElementType>::empty() const {
-  return data_->IsEmpty();
-}
-
-template <typename BaseElementType>
-void ListContainer<BaseElementType>::clear() {
-  for (Iterator i = begin(); i != end(); ++i) {
-    i->~BaseElementType();
-  }
-  data_->Clear();
-}
-
-template <typename BaseElementType>
-size_t ListContainer<
-    BaseElementType>::AvailableSizeWithoutAnotherAllocationForTesting() const {
-  return data_->NumAvailableElementsInLastList();
-}
-
-// ListContainer::Iterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::Iterator::Iterator(
-    ListContainerCharAllocator* container,
-    size_t vector_ind,
-    char* item_iter,
-    size_t index)
-    : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
-      index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::Iterator::~Iterator() {
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::Iterator::operator->() const {
-  return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::Iterator::operator*() const {
-  return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator
-ListContainer<BaseElementType>::Iterator::
-operator++(int unused_post_increment) {
-  Iterator tmp = *this;
-  operator++();
-  return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::Iterator&
-    ListContainer<BaseElementType>::Iterator::
-    operator++() {
-  this->Increment();
-  ++index_;
-  return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::Iterator::index() const {
-  return index_;
-}
-
-// ListContainer::ConstIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::ConstIterator(
-    const typename ListContainer<BaseElementType>::Iterator& other)
-    : PositionInListContainerCharAllocator(other), index_(other.index()) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::ConstIterator(
-    ListContainerCharAllocator* container,
-    size_t vector_ind,
-    char* item_iter,
-    size_t index)
-    : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
-      index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstIterator::~ConstIterator() {
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstIterator::
-operator->() const {
-  return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstIterator::
-operator*() const {
-  return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator
-ListContainer<BaseElementType>::ConstIterator::
-operator++(int unused_post_increment) {
-  ConstIterator tmp = *this;
-  operator++();
-  return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstIterator&
-    ListContainer<BaseElementType>::ConstIterator::
-    operator++() {
-  this->Increment();
-  ++index_;
-  return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ConstIterator::index() const {
-  return index_;
-}
-
-// ListContainer::ReverseIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ReverseIterator::ReverseIterator(
-    ListContainerCharAllocator* container,
-    size_t vector_ind,
-    char* item_iter,
-    size_t index)
-    : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
-      index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ReverseIterator::~ReverseIterator() {
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ReverseIterator::operator->()
-    const {
-  return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-BaseElementType* ListContainer<BaseElementType>::ReverseIterator::operator*()
-    const {
-  return reinterpret_cast<BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator
-ListContainer<BaseElementType>::ReverseIterator::
-operator++(int unused_post_increment) {
-  ReverseIterator tmp = *this;
-  operator++();
-  return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ReverseIterator&
-    ListContainer<BaseElementType>::ReverseIterator::
-    operator++() {
-  this->ReverseIncrement();
-  ++index_;
-  return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ReverseIterator::index() const {
-  return index_;
-}
-
-// ListContainer::ConstReverseIterator
-/////////////////////////////////////////////////
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
-    const typename ListContainer<BaseElementType>::ReverseIterator& other)
-    : PositionInListContainerCharAllocator(other), index_(other.index()) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::ConstReverseIterator(
-    ListContainerCharAllocator* container,
-    size_t vector_ind,
-    char* item_iter,
-    size_t index)
-    : PositionInListContainerCharAllocator(container, vector_ind, item_iter),
-      index_(index) {
-}
-
-template <typename BaseElementType>
-ListContainer<BaseElementType>::ConstReverseIterator::~ConstReverseIterator() {
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstReverseIterator::
-operator->() const {
-  return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-const BaseElementType* ListContainer<BaseElementType>::ConstReverseIterator::
-operator*() const {
-  return reinterpret_cast<const BaseElementType*>(this->item_iterator);
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator
-ListContainer<BaseElementType>::ConstReverseIterator::
-operator++(int unused_post_increment) {
-  ConstReverseIterator tmp = *this;
-  operator++();
-  return tmp;
-}
-
-template <typename BaseElementType>
-typename ListContainer<BaseElementType>::ConstReverseIterator&
-    ListContainer<BaseElementType>::ConstReverseIterator::
-    operator++() {
-  this->ReverseIncrement();
-  ++index_;
-  return *this;
-}
-
-template <typename BaseElementType>
-size_t ListContainer<BaseElementType>::ConstReverseIterator::index() const {
-  return index_;
-}
-
-template class ListContainer<SharedQuadState>;
-template class ListContainer<DrawQuad>;
-
-}  // namespace cc
diff --git a/cc/quads/list_container.h b/cc/quads/list_container.h
deleted file mode 100644
index dfa3612..0000000
--- a/cc/quads/list_container.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_QUADS_LIST_CONTAINER_H_
-#define CC_QUADS_LIST_CONTAINER_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace cc {
-class SharedQuadState;
-class DrawQuad;
-
-// This class is a container type that handles allocating contiguous memory for
-// new elements and traversing through elements with either iterator or reverse
-// iterator. Since this container hands out raw pointers of its elements, it is
-// very important that this container never reallocate its memory so those raw
-// pointer will continue to be valid.  This class is used to contain
-// SharedQuadState or DrawQuad. Since the size of each DrawQuad varies, to hold
-// DrawQuads, the allocations size of each element in this class is
-// LargestDrawQuadSize while BaseElementType is DrawQuad.
-template <class BaseElementType>
-class ListContainer {
- public:
-  // BaseElementType is the type of raw pointers this class hands out; however,
-  // its derived classes might require different memory sizes.
-  // max_size_for_derived_class the largest memory size required for all the
-  // derived classes to use for allocation.
-  explicit ListContainer(size_t max_size_for_derived_class);
-  // This constructor omits input variable for max_size_for_derived_class. This
-  // is used when there is no derived classes from BaseElementType we need to
-  // worry about, and allocation size is just sizeof(BaseElementType).
-  ListContainer();
-  // This constructor reserves the requested memory up front so only single
-  // allocation is needed. When num_of_elements_to_reserve_for is zero, use the
-  // default size.
-  ListContainer(size_t max_size_for_derived_class,
-                size_t num_of_elements_to_reserve_for);
-
-  ~ListContainer();
-
-  // This class deals only with char* and void*. It does allocation and passing
-  // out raw pointers, as well as memory deallocation when being destroyed.
-  class ListContainerCharAllocator;
-
-  // This class points to a certain position inside memory of
-  // ListContainerCharAllocator. It is a base class for ListContainer iterators.
-  struct PositionInListContainerCharAllocator {
-    ListContainerCharAllocator* ptr_to_container;
-    size_t vector_index;
-    char* item_iterator;
-
-    PositionInListContainerCharAllocator(
-        const PositionInListContainerCharAllocator& other);
-
-    PositionInListContainerCharAllocator(ListContainerCharAllocator* container,
-                                         size_t vector_ind,
-                                         char* item_iter);
-
-    bool operator==(const PositionInListContainerCharAllocator& other) const;
-    bool operator!=(const PositionInListContainerCharAllocator& other) const;
-
-    PositionInListContainerCharAllocator Increment();
-    PositionInListContainerCharAllocator ReverseIncrement();
-  };
-
-  // Iterator classes that can be used to access data.
-  /////////////////////////////////////////////////////////////////
-  class Iterator : public PositionInListContainerCharAllocator {
-    // This class is only defined to forward iterate through
-    // ListContainerCharAllocator.
-   public:
-    Iterator(ListContainerCharAllocator* container,
-             size_t vector_ind,
-             char* item_iter,
-             size_t index);
-    ~Iterator();
-    BaseElementType* operator->() const;
-    BaseElementType* operator*() const;
-    Iterator operator++(int unused_post_increment);
-    Iterator& operator++();
-
-    size_t index() const;
-
-   private:
-    // This is used to track how many increment has happened since begin(). It
-    // is used to avoid double increment at places an index reference is
-    // needed. For iterator this means begin() corresponds to index 0 and end()
-    // corresponds to index |size|.
-    size_t index_;
-  };
-
-  class ConstIterator : public PositionInListContainerCharAllocator {
-    // This class is only defined to forward iterate through
-    // ListContainerCharAllocator.
-   public:
-    ConstIterator(ListContainerCharAllocator* container,
-                  size_t vector_ind,
-                  char* item_iter,
-                  size_t index);
-    ConstIterator(const Iterator& other);  // NOLINT
-    ~ConstIterator();
-    const BaseElementType* operator->() const;
-    const BaseElementType* operator*() const;
-    ConstIterator operator++(int unused_post_increment);
-    ConstIterator& operator++();
-
-    size_t index() const;
-
-   private:
-    // This is used to track how many increment has happened since begin(). It
-    // is used to avoid double increment at places an index reference is
-    // needed. For iterator this means begin() corresponds to index 0 and end()
-    // corresponds to index |size|.
-    size_t index_;
-  };
-
-  class ReverseIterator : public PositionInListContainerCharAllocator {
-    // This class is only defined to reverse iterate through
-    // ListContainerCharAllocator.
-   public:
-    ReverseIterator(ListContainerCharAllocator* container,
-                    size_t vector_ind,
-                    char* item_iter,
-                    size_t index);
-    ~ReverseIterator();
-    BaseElementType* operator->() const;
-    BaseElementType* operator*() const;
-    ReverseIterator operator++(int unused_post_increment);
-    ReverseIterator& operator++();
-
-    size_t index() const;
-
-   private:
-    // This is used to track how many increment has happened since rbegin(). It
-    // is used to avoid double increment at places an index reference is
-    // needed. For reverse iterator this means rbegin() corresponds to index 0
-    // and rend() corresponds to index |size|.
-    size_t index_;
-  };
-
-  class ConstReverseIterator : public PositionInListContainerCharAllocator {
-    // This class is only defined to reverse iterate through
-    // ListContainerCharAllocator.
-   public:
-    ConstReverseIterator(ListContainerCharAllocator* container,
-                         size_t vector_ind,
-                         char* item_iter,
-                         size_t index);
-    ConstReverseIterator(const ReverseIterator& other);  // NOLINT
-    ~ConstReverseIterator();
-    const BaseElementType* operator->() const;
-    const BaseElementType* operator*() const;
-    ConstReverseIterator operator++(int unused_post_increment);
-    ConstReverseIterator& operator++();
-
-    size_t index() const;
-
-   private:
-    // This is used to track how many increment has happened since rbegin(). It
-    // is used to avoid double increment at places an index reference is
-    // needed. For reverse iterator this means rbegin() corresponds to index 0
-    // and rend() corresponds to index |size|.
-    size_t index_;
-  };
-
-  // When called, all raw pointers that have been handed out are no longer
-  // valid. Use with caution.
-  // This function does not deallocate memory.
-  void EraseAndInvalidateAllPointers(Iterator position);
-
-  ConstReverseIterator crbegin() const;
-  ConstReverseIterator crend() const;
-  ConstReverseIterator rbegin() const;
-  ConstReverseIterator rend() const;
-  ReverseIterator rbegin();
-  ReverseIterator rend();
-  ConstIterator cbegin() const;
-  ConstIterator cend() const;
-  ConstIterator begin() const;
-  ConstIterator end() const;
-  Iterator begin();
-  Iterator end();
-
-  // TODO(weiliangc): front(), back() and ElementAt() function should return
-  // reference, consistent with container-of-object.
-  BaseElementType* front();
-  BaseElementType* back();
-  const BaseElementType* front() const;
-  const BaseElementType* back() const;
-
-  BaseElementType* ElementAt(size_t index);
-  const BaseElementType* ElementAt(size_t index) const;
-
-  // Take in derived element type and construct it at location generated by
-  // Allocate().
-  template <typename DerivedElementType>
-  DerivedElementType* AllocateAndConstruct() {
-    return new (Allocate(sizeof(DerivedElementType))) DerivedElementType;
-  }
-  // Take in derived element type and copy construct it at location generated by
-  // Allocate().
-  template <typename DerivedElementType>
-  DerivedElementType* AllocateAndCopyFrom(const DerivedElementType* source) {
-    return new (Allocate(sizeof(DerivedElementType)))
-        DerivedElementType(*source);
-  }
-
-  size_t size() const;
-  bool empty() const;
-  void clear();
-
-  size_t AvailableSizeWithoutAnotherAllocationForTesting() const;
-
- private:
-  // Hands out memory location for an element at the end of data structure.
-  BaseElementType* Allocate(size_t size_of_actual_element_in_bytes);
-
-  scoped_ptr<ListContainerCharAllocator> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(ListContainer);
-};
-
-#if !defined(COMPILER_MSVC)
-extern template class ListContainer<SharedQuadState>;
-extern template class ListContainer<DrawQuad>;
-#endif
-}  // namespace cc
-
-#endif  // CC_QUADS_LIST_CONTAINER_H_
diff --git a/cc/quads/list_container_unittest.cc b/cc/quads/list_container_unittest.cc
deleted file mode 100644
index de88750..0000000
--- a/cc/quads/list_container_unittest.cc
+++ /dev/null
@@ -1,554 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/list_container.h"
-
-#include <vector>
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/largest_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-int kMagicNumberToUseForDrawQuadOne = 42;
-int kMagicNumberToUseForDrawQuadTwo = 314;
-
-bool isConstSharedQuadStatePointer(const SharedQuadState* ptr) {
-  return true;
-}
-
-bool isConstSharedQuadStatePointer(SharedQuadState* ptr) {
-  return false;
-}
-
-class SimpleDrawQuad : public DrawQuad {
- public:
-  ~SimpleDrawQuad() override {}
-  void IterateResources(const ResourceIteratorCallback& callback) override {}
-
-  void set_value(int val) { value = val; }
-  int get_value() { return value; }
-  void ExtendValue(base::trace_event::TracedValue* value) const override {}
-
- private:
-  int value;
-};
-
-class SimpleDrawQuadConstructMagicNumberOne : public SimpleDrawQuad {
- public:
-  SimpleDrawQuadConstructMagicNumberOne() : SimpleDrawQuad() {
-    set_value(kMagicNumberToUseForDrawQuadOne);
-  }
-};
-
-class SimpleDrawQuadConstructMagicNumberTwo : public SimpleDrawQuad {
- public:
-  SimpleDrawQuadConstructMagicNumberTwo() : SimpleDrawQuad() {
-    set_value(kMagicNumberToUseForDrawQuadTwo);
-  }
-};
-
-class MockDrawQuad : public DrawQuad {
- public:
-  ~MockDrawQuad() override { Destruct(); }
-  void IterateResources(const ResourceIteratorCallback& callback) override {}
-  void ExtendValue(base::trace_event::TracedValue* value) const override {}
-  MOCK_METHOD0(Destruct, void());
-};
-
-TEST(ListContainerTest, ConstructorCalledInAllocateAndConstruct) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-
-  size_t size = 2;
-  SimpleDrawQuadConstructMagicNumberOne* dq_1 =
-      list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberOne>();
-  SimpleDrawQuadConstructMagicNumberTwo* dq_2 =
-      list.AllocateAndConstruct<SimpleDrawQuadConstructMagicNumberTwo>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(dq_1, list.front());
-  EXPECT_EQ(dq_2, list.back());
-
-  EXPECT_EQ(kMagicNumberToUseForDrawQuadOne, dq_1->get_value());
-  EXPECT_EQ(kMagicNumberToUseForDrawQuadTwo, dq_2->get_value());
-}
-
-TEST(ListContainerTest, DestructorCalled) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-
-  size_t size = 1;
-  MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
-  EXPECT_CALL(*dq_1, Destruct());
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(dq_1, list.front());
-}
-
-TEST(ListContainerTest, DestructorCalledOnceWhenClear) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-  size_t size = 1;
-  MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(dq_1, list.front());
-
-  // Make sure destructor is called once during clear, and won't be called
-  // again.
-  testing::MockFunction<void()> separator;
-  {
-    testing::InSequence s;
-    EXPECT_CALL(*dq_1, Destruct());
-    EXPECT_CALL(separator, Call());
-    EXPECT_CALL(*dq_1, Destruct()).Times(0);
-  }
-
-  list.clear();
-  separator.Call();
-}
-
-TEST(ListContainerTest, DestructorCalledOnceWhenErase) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-  size_t size = 1;
-  MockDrawQuad* dq_1 = list.AllocateAndConstruct<MockDrawQuad>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(dq_1, list.front());
-
-  // Make sure destructor is called once during clear, and won't be called
-  // again.
-  testing::MockFunction<void()> separator;
-  {
-    testing::InSequence s;
-    EXPECT_CALL(*dq_1, Destruct());
-    EXPECT_CALL(separator, Call());
-    EXPECT_CALL(*dq_1, Destruct()).Times(0);
-  }
-
-  list.EraseAndInvalidateAllPointers(list.begin());
-  separator.Call();
-}
-
-TEST(ListContainerTest, SimpleIndexAccessSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-
-  size_t size = 3;
-  SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
-  SharedQuadState* sqs_2 = list.AllocateAndConstruct<SharedQuadState>();
-  SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(sqs_1, list.front());
-  EXPECT_EQ(sqs_3, list.back());
-  EXPECT_EQ(list.front(), list.ElementAt(0));
-  EXPECT_EQ(sqs_2, list.ElementAt(1));
-  EXPECT_EQ(list.back(), list.ElementAt(2));
-}
-
-TEST(ListContainerTest, SimpleInsertionSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-
-  size_t size = 3;
-  SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
-  list.AllocateAndConstruct<SharedQuadState>();
-  SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(sqs_1, list.front());
-  EXPECT_EQ(sqs_3, list.back());
-}
-
-TEST(ListContainerTest, SimpleInsertionAndClearSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  EXPECT_TRUE(list.empty());
-  EXPECT_EQ(0u, list.size());
-
-  size_t size = 3;
-  SharedQuadState* sqs_1 = list.AllocateAndConstruct<SharedQuadState>();
-  list.AllocateAndConstruct<SharedQuadState>();
-  SharedQuadState* sqs_3 = list.AllocateAndConstruct<SharedQuadState>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(sqs_1, list.front());
-  EXPECT_EQ(sqs_3, list.back());
-  EXPECT_FALSE(list.empty());
-
-  list.clear();
-  EXPECT_TRUE(list.empty());
-  EXPECT_EQ(0u, list.size());
-}
-
-TEST(ListContainerTest, SimpleInsertionClearAndInsertAgainSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  EXPECT_TRUE(list.empty());
-  EXPECT_EQ(0u, list.size());
-
-  size_t size = 2;
-  SharedQuadState* sqs_front = list.AllocateAndConstruct<SharedQuadState>();
-  SharedQuadState* sqs_back = list.AllocateAndConstruct<SharedQuadState>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(sqs_front, list.front());
-  EXPECT_EQ(sqs_back, list.back());
-  EXPECT_FALSE(list.empty());
-
-  list.clear();
-  EXPECT_TRUE(list.empty());
-  EXPECT_EQ(0u, list.size());
-
-  size = 3;
-  sqs_front = list.AllocateAndConstruct<SharedQuadState>();
-  list.AllocateAndConstruct<SharedQuadState>();
-  sqs_back = list.AllocateAndConstruct<SharedQuadState>();
-
-  EXPECT_EQ(size, list.size());
-  EXPECT_EQ(sqs_front, list.front());
-  EXPECT_EQ(sqs_back, list.back());
-  EXPECT_FALSE(list.empty());
-}
-
-// This test is used to test when there is more than one allocation needed
-// for, ListContainer can still perform like normal vector.
-TEST(ListContainerTest,
-     SimpleInsertionTriggerMoreThanOneAllocationSharedQuadState) {
-  ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
-  std::vector<SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  ListContainer<SharedQuadState>::Iterator iter = list.begin();
-  for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
-           sqs_list.begin();
-       sqs_iter != sqs_list.end();
-       ++sqs_iter) {
-    EXPECT_EQ(*sqs_iter, *iter);
-    ++iter;
-  }
-}
-
-TEST(ListContainerTest,
-     CorrectAllocationSizeForMoreThanOneAllocationSharedQuadState) {
-  // Constructor sets the allocation size to 2. Every time ListContainer needs
-  // to allocate again, it doubles allocation size. In this test, 10 elements is
-  // needed, thus ListContainerShould allocate spaces 2, 4 and 8 elements.
-  ListContainer<SharedQuadState> list(sizeof(SharedQuadState), 2);
-  std::vector<SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    // Before asking for a new element, space available without another
-    // allocation follows.
-    switch (i) {
-      case 2:
-      case 6:
-        EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 1:
-      case 5:
-        EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 0:
-      case 4:
-        EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 3:
-        EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 9:
-        EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 8:
-        EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 7:
-        EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      default:
-        break;
-    }
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-    // After asking for a new element, space available without another
-    // allocation follows.
-    switch (i) {
-      case 1:
-      case 5:
-        EXPECT_EQ(0u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 0:
-      case 4:
-        EXPECT_EQ(1u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 3:
-        EXPECT_EQ(2u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 2:
-        EXPECT_EQ(3u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 9:
-        EXPECT_EQ(4u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 8:
-        EXPECT_EQ(5u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 7:
-        EXPECT_EQ(6u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      case 6:
-        EXPECT_EQ(7u, list.AvailableSizeWithoutAnotherAllocationForTesting());
-        break;
-      default:
-        break;
-    }
-  }
-  EXPECT_EQ(size, list.size());
-
-  ListContainer<SharedQuadState>::Iterator iter = list.begin();
-  for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
-           sqs_list.begin();
-       sqs_iter != sqs_list.end();
-       ++sqs_iter) {
-    EXPECT_EQ(*sqs_iter, *iter);
-    ++iter;
-  }
-}
-
-TEST(ListContainerTest, SimpleIterationSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  std::vector<SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  size_t num_iters_in_list = 0;
-  {
-    std::vector<SharedQuadState*>::const_iterator sqs_iter = sqs_list.begin();
-    for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
-         iter != list.end();
-         ++iter) {
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++num_iters_in_list;
-      ++sqs_iter;
-    }
-  }
-
-  size_t num_iters_in_vector = 0;
-  {
-    ListContainer<SharedQuadState>::Iterator iter = list.begin();
-    for (std::vector<SharedQuadState*>::const_iterator sqs_iter =
-             sqs_list.begin();
-         sqs_iter != sqs_list.end();
-         ++sqs_iter) {
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++num_iters_in_vector;
-      ++iter;
-    }
-  }
-
-  EXPECT_EQ(num_iters_in_vector, num_iters_in_list);
-}
-
-TEST(ListContainerTest, SimpleConstIteratorIterationSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  std::vector<const SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  {
-    std::vector<const SharedQuadState*>::const_iterator sqs_iter =
-        sqs_list.begin();
-    for (ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
-         iter != list.end();
-         ++iter) {
-      EXPECT_TRUE(isConstSharedQuadStatePointer(*iter));
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++sqs_iter;
-    }
-  }
-
-  {
-    std::vector<const SharedQuadState*>::const_iterator sqs_iter =
-        sqs_list.begin();
-    for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
-         iter != list.end();
-         ++iter) {
-      EXPECT_FALSE(isConstSharedQuadStatePointer(*iter));
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++sqs_iter;
-    }
-  }
-
-  {
-    ListContainer<SharedQuadState>::ConstIterator iter = list.begin();
-    for (std::vector<const SharedQuadState*>::const_iterator sqs_iter =
-             sqs_list.begin();
-         sqs_iter != sqs_list.end();
-         ++sqs_iter) {
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++iter;
-    }
-  }
-}
-
-TEST(ListContainerTest, SimpleReverseInsertionSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  std::vector<SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  {
-    std::vector<SharedQuadState*>::const_reverse_iterator sqs_iter =
-        sqs_list.rbegin();
-    for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
-         iter != list.rend();
-         ++iter) {
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++sqs_iter;
-    }
-  }
-
-  {
-    ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
-    for (std::vector<SharedQuadState*>::reverse_iterator sqs_iter =
-             sqs_list.rbegin();
-         sqs_iter != sqs_list.rend();
-         ++sqs_iter) {
-      EXPECT_EQ(*sqs_iter, *iter);
-      ++iter;
-    }
-  }
-}
-
-TEST(ListContainerTest, SimpleDeletion) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-  std::vector<SimpleDrawQuad*> sdq_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sdq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
-    sdq_list.back()->set_value(i);
-  }
-  EXPECT_EQ(size, list.size());
-
-  list.EraseAndInvalidateAllPointers(list.begin());
-  --size;
-  EXPECT_EQ(size, list.size());
-  int i = 1;
-  for (ListContainer<DrawQuad>::Iterator iter = list.begin();
-       iter != list.end();
-       ++iter) {
-    EXPECT_EQ(i, static_cast<SimpleDrawQuad*>(*iter)->get_value());
-    ++i;
-  }
-}
-
-TEST(ListContainerTest, SimpleIterationAndManipulation) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-  std::vector<SimpleDrawQuad*> sdq_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    SimpleDrawQuad* simple_dq = list.AllocateAndConstruct<SimpleDrawQuad>();
-    sdq_list.push_back(simple_dq);
-  }
-  EXPECT_EQ(size, list.size());
-
-  ListContainer<DrawQuad>::Iterator iter = list.begin();
-  for (int i = 0; i < 10; ++i) {
-    static_cast<SimpleDrawQuad*>(*iter)->set_value(i);
-    ++iter;
-  }
-
-  int i = 0;
-  for (std::vector<SimpleDrawQuad*>::const_iterator sdq_iter = sdq_list.begin();
-       sdq_iter < sdq_list.end();
-       ++sdq_iter) {
-    EXPECT_EQ(i, (*sdq_iter)->get_value());
-    ++i;
-  }
-}
-
-TEST(ListContainerTest, SimpleManipulationWithIndexSimpleDrawQuad) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize());
-  std::vector<SimpleDrawQuad*> dq_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  for (size_t i = 0; i < size; ++i) {
-    static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
-  }
-
-  int i = 0;
-  for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
-       dq_iter != dq_list.end();
-       ++dq_iter, ++i) {
-    EXPECT_EQ(i, (*dq_iter)->get_value());
-  }
-}
-
-TEST(ListContainerTest,
-     SimpleManipulationWithIndexMoreThanOneAllocationSimpleDrawQuad) {
-  ListContainer<DrawQuad> list(LargestDrawQuadSize(), 2);
-  std::vector<SimpleDrawQuad*> dq_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    dq_list.push_back(list.AllocateAndConstruct<SimpleDrawQuad>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  for (size_t i = 0; i < size; ++i) {
-    static_cast<SimpleDrawQuad*>(list.ElementAt(i))->set_value(i);
-  }
-
-  int i = 0;
-  for (std::vector<SimpleDrawQuad*>::const_iterator dq_iter = dq_list.begin();
-       dq_iter != dq_list.end();
-       ++dq_iter, ++i) {
-    EXPECT_EQ(i, (*dq_iter)->get_value());
-  }
-}
-
-TEST(ListContainerTest,
-     SimpleIterationAndReverseIterationWithIndexSharedQuadState) {
-  ListContainer<SharedQuadState> list;
-  std::vector<SharedQuadState*> sqs_list;
-  size_t size = 10;
-  for (size_t i = 0; i < size; ++i) {
-    sqs_list.push_back(list.AllocateAndConstruct<SharedQuadState>());
-  }
-  EXPECT_EQ(size, list.size());
-
-  size_t i = 0;
-  for (ListContainer<SharedQuadState>::Iterator iter = list.begin();
-       iter != list.end();
-       ++iter) {
-    EXPECT_EQ(i, iter.index());
-    ++i;
-  }
-
-  i = 0;
-  for (ListContainer<SharedQuadState>::ReverseIterator iter = list.rbegin();
-       iter != list.rend();
-       ++iter) {
-    EXPECT_EQ(i, iter.index());
-    ++i;
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/quads/render_pass.cc b/cc/quads/render_pass.cc
deleted file mode 100644
index 602b561..0000000
--- a/cc/quads/render_pass.cc
+++ /dev/null
@@ -1,269 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/quads/render_pass.h"
-
-#include <algorithm>
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "cc/debug/traced_value.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/largest_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-
-namespace {
-const size_t kDefaultNumSharedQuadStatesToReserve = 32;
-const size_t kDefaultNumQuadsToReserve = 128;
-}
-
-namespace cc {
-
-QuadList::QuadList(size_t default_size_to_reserve)
-    : ListContainer<DrawQuad>(LargestDrawQuadSize(), default_size_to_reserve) {
-}
-
-scoped_ptr<RenderPass> RenderPass::Create() {
-  return make_scoped_ptr(new RenderPass());
-}
-
-scoped_ptr<RenderPass> RenderPass::Create(size_t num_layers) {
-  return make_scoped_ptr(new RenderPass(num_layers));
-}
-
-scoped_ptr<RenderPass> RenderPass::Create(size_t shared_quad_state_list_size,
-                                          size_t quad_list_size) {
-  return make_scoped_ptr(
-      new RenderPass(shared_quad_state_list_size, quad_list_size));
-}
-
-RenderPass::RenderPass()
-    : id(RenderPassId(-1, -1)),
-      has_transparent_background(true),
-      quad_list(kDefaultNumQuadsToReserve),
-      shared_quad_state_list(sizeof(SharedQuadState),
-                             kDefaultNumSharedQuadStatesToReserve) {
-}
-
-// Each layer usually produces one shared quad state, so the number of layers
-// is a good hint for what to reserve here.
-RenderPass::RenderPass(size_t num_layers)
-    : id(RenderPassId(-1, -1)),
-      has_transparent_background(true),
-      quad_list(kDefaultNumQuadsToReserve),
-      shared_quad_state_list(sizeof(SharedQuadState), num_layers) {
-}
-
-RenderPass::RenderPass(size_t shared_quad_state_list_size,
-                       size_t quad_list_size)
-    : id(RenderPassId(-1, -1)),
-      has_transparent_background(true),
-      quad_list(quad_list_size),
-      shared_quad_state_list(sizeof(SharedQuadState),
-                             shared_quad_state_list_size) {
-}
-
-RenderPass::~RenderPass() {
-  TRACE_EVENT_OBJECT_DELETED_WITH_ID(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
-      "cc::RenderPass", id.AsTracingId());
-}
-
-scoped_ptr<RenderPass> RenderPass::Copy(RenderPassId new_id) const {
-  scoped_ptr<RenderPass> copy_pass(
-      Create(shared_quad_state_list.size(), quad_list.size()));
-  copy_pass->SetAll(new_id,
-                    output_rect,
-                    damage_rect,
-                    transform_to_root_target,
-                    has_transparent_background);
-  return copy_pass.Pass();
-}
-
-// static
-void RenderPass::CopyAll(const ScopedPtrVector<RenderPass>& in,
-                         ScopedPtrVector<RenderPass>* out) {
-  for (size_t i = 0; i < in.size(); ++i) {
-    RenderPass* source = in[i];
-
-    // Since we can't copy these, it's wrong to use CopyAll in a situation where
-    // you may have copy_requests present.
-    DCHECK_EQ(source->copy_requests.size(), 0u);
-
-    scoped_ptr<RenderPass> copy_pass(Create(
-        source->shared_quad_state_list.size(), source->quad_list.size()));
-    copy_pass->SetAll(source->id,
-                      source->output_rect,
-                      source->damage_rect,
-                      source->transform_to_root_target,
-                      source->has_transparent_background);
-    for (const auto& shared_quad_state : source->shared_quad_state_list) {
-      SharedQuadState* copy_shared_quad_state =
-          copy_pass->CreateAndAppendSharedQuadState();
-      copy_shared_quad_state->CopyFrom(shared_quad_state);
-    }
-    SharedQuadStateList::Iterator sqs_iter =
-        source->shared_quad_state_list.begin();
-    SharedQuadStateList::Iterator copy_sqs_iter =
-        copy_pass->shared_quad_state_list.begin();
-    for (const auto& quad : source->quad_list) {
-      while (quad->shared_quad_state != *sqs_iter) {
-        ++sqs_iter;
-        ++copy_sqs_iter;
-        DCHECK(sqs_iter != source->shared_quad_state_list.end());
-      }
-      DCHECK(quad->shared_quad_state == *sqs_iter);
-
-      SharedQuadState* copy_shared_quad_state = *copy_sqs_iter;
-
-      if (quad->material == DrawQuad::RENDER_PASS) {
-        const RenderPassDrawQuad* pass_quad =
-            RenderPassDrawQuad::MaterialCast(quad);
-        copy_pass->CopyFromAndAppendRenderPassDrawQuad(
-            pass_quad, copy_shared_quad_state, pass_quad->render_pass_id);
-      } else {
-        copy_pass->CopyFromAndAppendDrawQuad(quad, copy_shared_quad_state);
-      }
-    }
-    out->push_back(copy_pass.Pass());
-  }
-}
-
-void RenderPass::SetNew(RenderPassId id,
-                        const gfx::Rect& output_rect,
-                        const gfx::Rect& damage_rect,
-                        const gfx::Transform& transform_to_root_target) {
-  DCHECK_GT(id.layer_id, 0);
-  DCHECK_GE(id.index, 0);
-  DCHECK(damage_rect.IsEmpty() || output_rect.Contains(damage_rect))
-      << "damage_rect: " << damage_rect.ToString()
-      << " output_rect: " << output_rect.ToString();
-
-  this->id = id;
-  this->output_rect = output_rect;
-  this->damage_rect = damage_rect;
-  this->transform_to_root_target = transform_to_root_target;
-
-  DCHECK(quad_list.empty());
-  DCHECK(shared_quad_state_list.empty());
-}
-
-void RenderPass::SetAll(RenderPassId id,
-                        const gfx::Rect& output_rect,
-                        const gfx::Rect& damage_rect,
-                        const gfx::Transform& transform_to_root_target,
-                        bool has_transparent_background) {
-  DCHECK_GT(id.layer_id, 0);
-  DCHECK_GE(id.index, 0);
-
-  this->id = id;
-  this->output_rect = output_rect;
-  this->damage_rect = damage_rect;
-  this->transform_to_root_target = transform_to_root_target;
-  this->has_transparent_background = has_transparent_background;
-
-  DCHECK(quad_list.empty());
-  DCHECK(shared_quad_state_list.empty());
-}
-
-void RenderPass::AsValueInto(base::trace_event::TracedValue* value) const {
-  MathUtil::AddToTracedValue("output_rect", output_rect, value);
-  MathUtil::AddToTracedValue("damage_rect", damage_rect, value);
-
-  value->SetBoolean("has_transparent_background", has_transparent_background);
-  value->SetInteger("copy_requests", copy_requests.size());
-
-  value->BeginArray("shared_quad_state_list");
-  for (const auto& shared_quad_state : shared_quad_state_list) {
-    value->BeginDictionary();
-    shared_quad_state->AsValueInto(value);
-    value->EndDictionary();
-  }
-  value->EndArray();
-
-  value->BeginArray("quad_list");
-  for (const auto& quad : quad_list) {
-    value->BeginDictionary();
-    quad->AsValueInto(value);
-    value->EndDictionary();
-  }
-  value->EndArray();
-
-  TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
-      value,
-      "cc::RenderPass",
-      id.AsTracingId());
-}
-
-SharedQuadState* RenderPass::CreateAndAppendSharedQuadState() {
-  return shared_quad_state_list.AllocateAndConstruct<SharedQuadState>();
-}
-
-RenderPassDrawQuad* RenderPass::CopyFromAndAppendRenderPassDrawQuad(
-    const RenderPassDrawQuad* quad,
-    const SharedQuadState* shared_quad_state,
-    RenderPassId render_pass_id) {
-  RenderPassDrawQuad* copy_quad =
-      CopyFromAndAppendTypedDrawQuad<RenderPassDrawQuad>(quad);
-  copy_quad->shared_quad_state = shared_quad_state;
-  copy_quad->render_pass_id = render_pass_id;
-  return copy_quad;
-}
-
-DrawQuad* RenderPass::CopyFromAndAppendDrawQuad(
-    const DrawQuad* quad,
-    const SharedQuadState* shared_quad_state) {
-  switch (quad->material) {
-    case DrawQuad::CHECKERBOARD:
-      CopyFromAndAppendTypedDrawQuad<CheckerboardDrawQuad>(quad);
-      break;
-    case DrawQuad::DEBUG_BORDER:
-      CopyFromAndAppendTypedDrawQuad<DebugBorderDrawQuad>(quad);
-      break;
-    case DrawQuad::IO_SURFACE_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<IOSurfaceDrawQuad>(quad);
-      break;
-    case DrawQuad::TEXTURE_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<TextureDrawQuad>(quad);
-      break;
-    case DrawQuad::SOLID_COLOR:
-      CopyFromAndAppendTypedDrawQuad<SolidColorDrawQuad>(quad);
-      break;
-    case DrawQuad::TILED_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<TileDrawQuad>(quad);
-      break;
-    case DrawQuad::STREAM_VIDEO_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<StreamVideoDrawQuad>(quad);
-      break;
-    case DrawQuad::SURFACE_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<SurfaceDrawQuad>(quad);
-      break;
-    case DrawQuad::YUV_VIDEO_CONTENT:
-      CopyFromAndAppendTypedDrawQuad<YUVVideoDrawQuad>(quad);
-      break;
-    // RenderPass quads need to use specific CopyFrom function.
-    case DrawQuad::RENDER_PASS:
-    case DrawQuad::INVALID:
-    case DrawQuad::UNUSED_SPACE_FOR_PICTURE_CONTENT:
-      LOG(FATAL) << "Invalid DrawQuad material " << quad->material;
-      break;
-  }
-  quad_list.back()->shared_quad_state = shared_quad_state;
-  return quad_list.back();
-}
-
-}  // namespace cc
diff --git a/cc/quads/render_pass.h b/cc/quads/render_pass.h
deleted file mode 100644
index 94c0df4..0000000
--- a/cc/quads/render_pass.h
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_QUADS_RENDER_PASS_H_
-#define CC_QUADS_RENDER_PASS_H_
-
-#include <utility>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/containers/hash_tables.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/quads/list_container.h"
-#include "cc/quads/render_pass_id.h"
-#include "skia/ext/refptr.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/gfx/transform.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class Value;
-}
-
-namespace cc {
-
-class DrawQuad;
-class CopyOutputRequest;
-class RenderPassDrawQuad;
-class SharedQuadState;
-
-// A list of DrawQuad objects, sorted internally in front-to-back order.
-class QuadList : public ListContainer<DrawQuad> {
- public:
-  explicit QuadList(size_t default_size_to_reserve);
-
-  typedef QuadList::ReverseIterator BackToFrontIterator;
-  typedef QuadList::ConstReverseIterator ConstBackToFrontIterator;
-
-  inline BackToFrontIterator BackToFrontBegin() { return rbegin(); }
-  inline BackToFrontIterator BackToFrontEnd() { return rend(); }
-  inline ConstBackToFrontIterator BackToFrontBegin() const { return rbegin(); }
-  inline ConstBackToFrontIterator BackToFrontEnd() const { return rend(); }
-};
-
-typedef ListContainer<SharedQuadState> SharedQuadStateList;
-
-class RenderPass {
- public:
-  ~RenderPass();
-
-  static scoped_ptr<RenderPass> Create();
-  static scoped_ptr<RenderPass> Create(size_t num_layers);
-  static scoped_ptr<RenderPass> Create(size_t shared_quad_state_list_size,
-                                       size_t quad_list_size);
-
-  // A shallow copy of the render pass, which does not include its quads or copy
-  // requests.
-  scoped_ptr<RenderPass> Copy(RenderPassId new_id) const;
-
-  // A deep copy of the render passes in the list including the quads.
-  static void CopyAll(const ScopedPtrVector<RenderPass>& in,
-                      ScopedPtrVector<RenderPass>* out);
-
-  void SetNew(RenderPassId id,
-              const gfx::Rect& output_rect,
-              const gfx::Rect& damage_rect,
-              const gfx::Transform& transform_to_root_target);
-
-  void SetAll(RenderPassId id,
-              const gfx::Rect& output_rect,
-              const gfx::Rect& damage_rect,
-              const gfx::Transform& transform_to_root_target,
-              bool has_transparent_background);
-
-  void AsValueInto(base::trace_event::TracedValue* dict) const;
-
-  SharedQuadState* CreateAndAppendSharedQuadState();
-
-  template <typename DrawQuadType>
-  DrawQuadType* CreateAndAppendDrawQuad() {
-    return quad_list.AllocateAndConstruct<DrawQuadType>();
-  }
-
-  RenderPassDrawQuad* CopyFromAndAppendRenderPassDrawQuad(
-      const RenderPassDrawQuad* quad,
-      const SharedQuadState* shared_quad_state,
-      RenderPassId render_pass_id);
-  DrawQuad* CopyFromAndAppendDrawQuad(const DrawQuad* quad,
-                                      const SharedQuadState* shared_quad_state);
-
-  // Uniquely identifies the render pass in the compositor's current frame.
-  RenderPassId id;
-
-  // These are in the space of the render pass' physical pixels.
-  gfx::Rect output_rect;
-  gfx::Rect damage_rect;
-
-  // Transforms from the origin of the |output_rect| to the origin of the root
-  // render pass' |output_rect|.
-  gfx::Transform transform_to_root_target;
-
-  // If false, the pixels in the render pass' texture are all opaque.
-  bool has_transparent_background;
-
-  // If non-empty, the renderer should produce a copy of the render pass'
-  // contents as a bitmap, and give a copy of the bitmap to each callback in
-  // this list. This property should not be serialized between compositors, as
-  // it only makes sense in the root compositor.
-  ScopedPtrVector<CopyOutputRequest> copy_requests;
-
-  QuadList quad_list;
-  SharedQuadStateList shared_quad_state_list;
-
- protected:
-  explicit RenderPass(size_t num_layers);
-  RenderPass();
-  RenderPass(size_t shared_quad_state_list_size, size_t quad_list_size);
-
- private:
-  template <typename DrawQuadType>
-  DrawQuadType* CopyFromAndAppendTypedDrawQuad(const DrawQuad* quad) {
-    return quad_list.AllocateAndCopyFrom(DrawQuadType::MaterialCast(quad));
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(RenderPass);
-};
-
-}  // namespace cc
-
-namespace BASE_HASH_NAMESPACE {
-template <>
-struct hash<cc::RenderPassId> {
-  size_t operator()(cc::RenderPassId key) const {
-    return base::HashPair(key.layer_id, key.index);
-  }
-};
-}  // namespace BASE_HASH_NAMESPACE
-
-namespace cc {
-typedef ScopedPtrVector<RenderPass> RenderPassList;
-typedef base::hash_map<RenderPassId, RenderPass*> RenderPassIdHashMap;
-}  // namespace cc
-
-#endif  // CC_QUADS_RENDER_PASS_H_
diff --git a/cc/quads/render_pass_draw_quad.cc b/cc/quads/render_pass_draw_quad.cc
deleted file mode 100644
index 963a190..0000000
--- a/cc/quads/render_pass_draw_quad.cc
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/quads/render_pass_draw_quad.h"
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "cc/debug/traced_value.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-
-namespace cc {
-
-RenderPassDrawQuad::RenderPassDrawQuad()
-    : render_pass_id(RenderPassId(-1, -1)),
-      mask_resource_id(static_cast<ResourceProvider::ResourceId>(-1)) {
-}
-
-RenderPassDrawQuad::~RenderPassDrawQuad() {
-}
-
-void RenderPassDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                                const gfx::Rect& rect,
-                                const gfx::Rect& visible_rect,
-                                RenderPassId render_pass_id,
-                                ResourceProvider::ResourceId mask_resource_id,
-                                const gfx::Vector2dF& mask_uv_scale,
-                                const gfx::Size& mask_texture_size,
-                                const FilterOperations& filters,
-                                const gfx::Vector2dF& filters_scale,
-                                const FilterOperations& background_filters) {
-  DCHECK_GT(render_pass_id.layer_id, 0);
-  DCHECK_GE(render_pass_id.index, 0);
-
-  gfx::Rect opaque_rect;
-  bool needs_blending = false;
-  SetAll(shared_quad_state,
-         rect,
-         opaque_rect,
-         visible_rect,
-         needs_blending,
-         render_pass_id,
-         mask_resource_id,
-         mask_uv_scale,
-         mask_texture_size,
-         filters,
-         filters_scale,
-         background_filters);
-}
-
-void RenderPassDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                                const gfx::Rect& rect,
-                                const gfx::Rect& opaque_rect,
-                                const gfx::Rect& visible_rect,
-                                bool needs_blending,
-                                RenderPassId render_pass_id,
-                                ResourceProvider::ResourceId mask_resource_id,
-                                const gfx::Vector2dF& mask_uv_scale,
-                                const gfx::Size& mask_texture_size,
-                                const FilterOperations& filters,
-                                const gfx::Vector2dF& filters_scale,
-                                const FilterOperations& background_filters) {
-  DCHECK_GT(render_pass_id.layer_id, 0);
-  DCHECK_GE(render_pass_id.index, 0);
-
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::RENDER_PASS, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->render_pass_id = render_pass_id;
-  this->mask_resource_id = mask_resource_id;
-  this->mask_uv_scale = mask_uv_scale;
-  this->mask_texture_size = mask_texture_size;
-  this->filters = filters;
-  this->filters_scale = filters_scale;
-  this->background_filters = background_filters;
-}
-
-void RenderPassDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  if (mask_resource_id)
-    mask_resource_id = callback.Run(mask_resource_id);
-}
-
-gfx::RectF RenderPassDrawQuad::MaskUVRect() const {
-  gfx::RectF mask_uv_rect((mask_uv_scale.x() * rect.x()) / rect.width(),
-                          (mask_uv_scale.y() * rect.y()) / rect.height(),
-                          mask_uv_scale.x(),
-                          mask_uv_scale.y());
-  return mask_uv_rect;
-}
-
-const RenderPassDrawQuad* RenderPassDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK_EQ(quad->material, DrawQuad::RENDER_PASS);
-  return static_cast<const RenderPassDrawQuad*>(quad);
-}
-
-void RenderPassDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  TracedValue::SetIDRef(render_pass_id.AsTracingId(), value, "render_pass_id");
-  value->SetInteger("mask_resource_id", mask_resource_id);
-  MathUtil::AddToTracedValue("mask_texture_size", mask_texture_size, value);
-  MathUtil::AddToTracedValue("mask_uv_scale", mask_uv_scale, value);
-
-  value->BeginDictionary("filters");
-  filters.AsValueInto(value);
-  value->EndDictionary();
-  MathUtil::AddToTracedValue("filters_scale", filters_scale, value);
-
-  value->BeginDictionary("background_filters");
-  background_filters.AsValueInto(value);
-  value->EndDictionary();
-}
-
-}  // namespace cc
diff --git a/cc/quads/render_pass_draw_quad.h b/cc/quads/render_pass_draw_quad.h
deleted file mode 100644
index b2b5ef4..0000000
--- a/cc/quads/render_pass_draw_quad.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_QUADS_RENDER_PASS_DRAW_QUAD_H_
-#define CC_QUADS_RENDER_PASS_DRAW_QUAD_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/filter_operations.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass_id.h"
-#include "cc/resources/resource_provider.h"
-
-namespace cc {
-
-class RenderPassDrawQuad : public DrawQuad {
- public:
-  RenderPassDrawQuad();
-  ~RenderPassDrawQuad() override;
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& visible_rect,
-              RenderPassId render_pass_id,
-              ResourceProvider::ResourceId mask_resource_id,
-              const gfx::Vector2dF& mask_uv_scale,
-              const gfx::Size& mask_texture_size,
-              const FilterOperations& filters,
-              const gfx::Vector2dF& filters_scale,
-              const FilterOperations& background_filters);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              RenderPassId render_pass_id,
-              ResourceProvider::ResourceId mask_resource_id,
-              const gfx::Vector2dF& mask_uv_scale,
-              const gfx::Size& mask_texture_size,
-              const FilterOperations& filters,
-              const gfx::Vector2dF& filters_scale,
-              const FilterOperations& background_filters);
-
-  RenderPassId render_pass_id;
-  ResourceProvider::ResourceId mask_resource_id;
-  gfx::Vector2dF mask_uv_scale;
-  gfx::Size mask_texture_size;
-
-  // Post-processing filters, applied to the pixels in the render pass' texture.
-  FilterOperations filters;
-
-  // The scale from layer space of the root layer of the render pass to
-  // the render pass physical pixels. This scale is applied to the filter
-  // parameters for pixel-moving filters. This scale should include
-  // content-to-target-space scale, and device pixel ratio.
-  gfx::Vector2dF filters_scale;
-
-  // Post-processing filters, applied to the pixels showing through the
-  // background of the render pass, from behind it.
-  FilterOperations background_filters;
-
-  // Helper function to generate the normalized uv rect.
-  gfx::RectF MaskUVRect() const;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const RenderPassDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_RENDER_PASS_DRAW_QUAD_H_
diff --git a/cc/quads/render_pass_id.cc b/cc/quads/render_pass_id.cc
deleted file mode 100644
index a84582c..0000000
--- a/cc/quads/render_pass_id.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/render_pass_id.h"
-
-namespace cc {
-
-void* RenderPassId::AsTracingId() const {
-  static_assert(sizeof(size_t) <= sizeof(void*),  // NOLINT
-                "size of size_t should not be greater than that of a pointer");
-  return reinterpret_cast<void*>(base::HashPair(layer_id, index));
-}
-
-}  // namespace cc
diff --git a/cc/quads/render_pass_id.h b/cc/quads/render_pass_id.h
deleted file mode 100644
index b999ea7..0000000
--- a/cc/quads/render_pass_id.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_QUADS_RENDER_PASS_ID_H_
-#define CC_QUADS_RENDER_PASS_ID_H_
-
-#include "base/basictypes.h"
-#include "base/containers/hash_tables.h"
-
-namespace cc {
-
-class RenderPassId {
- public:
-  int layer_id;
-  int index;
-
-  RenderPassId(int layer_id, int index) : layer_id(layer_id), index(index) {}
-  void* AsTracingId() const;
-
-  bool operator==(const RenderPassId& other) const {
-    return layer_id == other.layer_id && index == other.index;
-  }
-  bool operator!=(const RenderPassId& other) const { return !(*this == other); }
-  bool operator<(const RenderPassId& other) const {
-    return layer_id < other.layer_id ||
-           (layer_id == other.layer_id && index < other.index);
-  }
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_RENDER_PASS_ID_H_
diff --git a/cc/quads/render_pass_unittest.cc b/cc/quads/render_pass_unittest.cc
deleted file mode 100644
index e6f39bc..0000000
--- a/cc/quads/render_pass_unittest.cc
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/render_pass.h"
-
-#include "cc/base/math_util.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/test/geometry_test_utils.h"
-#include "cc/test/render_pass_test_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/effects/SkBlurImageFilter.h"
-#include "ui/gfx/transform.h"
-
-using cc::TestRenderPass;
-
-namespace cc {
-namespace {
-
-struct RenderPassSize {
-  // If you add a new field to this class, make sure to add it to the
-  // Copy() tests.
-  RenderPassId id;
-  QuadList quad_list;
-  SharedQuadStateList shared_quad_state_list;
-  gfx::Transform transform_to_root_target;
-  gfx::Rect output_rect;
-  gfx::Rect damage_rect;
-  bool has_transparent_background;
-  ScopedPtrVector<CopyOutputRequest> copy_callbacks;
-};
-
-static void CompareRenderPassLists(const RenderPassList& expected_list,
-                                   const RenderPassList& actual_list) {
-  EXPECT_EQ(expected_list.size(), actual_list.size());
-  for (size_t i = 0; i < actual_list.size(); ++i) {
-    RenderPass* expected = expected_list[i];
-    RenderPass* actual = actual_list[i];
-
-    EXPECT_EQ(expected->id, actual->id);
-    EXPECT_EQ(expected->output_rect, actual->output_rect);
-    EXPECT_EQ(expected->transform_to_root_target,
-              actual->transform_to_root_target);
-    EXPECT_EQ(expected->damage_rect, actual->damage_rect);
-    EXPECT_EQ(expected->has_transparent_background,
-              actual->has_transparent_background);
-
-    EXPECT_EQ(expected->shared_quad_state_list.size(),
-              actual->shared_quad_state_list.size());
-    EXPECT_EQ(expected->quad_list.size(), actual->quad_list.size());
-
-    for (auto exp_iter = expected->quad_list.cbegin(),
-              act_iter = actual->quad_list.cbegin();
-         exp_iter != expected->quad_list.cend();
-         ++exp_iter, ++act_iter) {
-      EXPECT_EQ(exp_iter->rect.ToString(), act_iter->rect.ToString());
-      EXPECT_EQ(exp_iter->shared_quad_state->content_bounds.ToString(),
-                act_iter->shared_quad_state->content_bounds.ToString());
-    }
-  }
-}
-
-TEST(RenderPassTest, CopyShouldBeIdenticalExceptIdAndQuads) {
-  RenderPassId id(3, 2);
-  gfx::Rect output_rect(45, 22, 120, 13);
-  gfx::Transform transform_to_root =
-      gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0);
-  gfx::Rect damage_rect(56, 123, 19, 43);
-  bool has_transparent_background = true;
-
-  scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
-  pass->SetAll(id,
-               output_rect,
-               damage_rect,
-               transform_to_root,
-               has_transparent_background);
-  pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest());
-
-  // Stick a quad in the pass, this should not get copied.
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       gfx::Size(),
-                       gfx::Rect(),
-                       gfx::Rect(),
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-
-  CheckerboardDrawQuad* checkerboard_quad =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad->SetNew(pass->shared_quad_state_list.back(), gfx::Rect(),
-                            gfx::Rect(), SkColor(), 1.f);
-
-  RenderPassId new_id(63, 4);
-
-  scoped_ptr<RenderPass> copy = pass->Copy(new_id);
-  EXPECT_EQ(new_id, copy->id);
-  EXPECT_EQ(pass->output_rect, copy->output_rect);
-  EXPECT_EQ(pass->transform_to_root_target, copy->transform_to_root_target);
-  EXPECT_EQ(pass->damage_rect, copy->damage_rect);
-  EXPECT_EQ(pass->has_transparent_background, copy->has_transparent_background);
-  EXPECT_EQ(0u, copy->quad_list.size());
-
-  // The copy request should not be copied/duplicated.
-  EXPECT_EQ(1u, pass->copy_requests.size());
-  EXPECT_EQ(0u, copy->copy_requests.size());
-
-  EXPECT_EQ(sizeof(RenderPassSize), sizeof(RenderPass));
-}
-
-TEST(RenderPassTest, CopyAllShouldBeIdentical) {
-  RenderPassList pass_list;
-
-  RenderPassId id(3, 2);
-  gfx::Rect output_rect(45, 22, 120, 13);
-  gfx::Transform transform_to_root =
-      gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0);
-  gfx::Rect damage_rect(56, 123, 19, 43);
-  bool has_transparent_background = true;
-
-  scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
-  pass->SetAll(id,
-               output_rect,
-               damage_rect,
-               transform_to_root,
-               has_transparent_background);
-
-  // Two quads using one shared state.
-  SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState();
-  shared_state1->SetAll(gfx::Transform(),
-                        gfx::Size(1, 1),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  CheckerboardDrawQuad* checkerboard_quad1 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad1->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(1, 1, 1, 1), gfx::Rect(1, 1, 1, 1),
-                             SkColor(), 1.f);
-
-  CheckerboardDrawQuad* checkerboard_quad2 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad2->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(2, 2, 2, 2), gfx::Rect(2, 2, 2, 2),
-                             SkColor(), 1.f);
-
-  // And two quads using another shared state.
-  SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState();
-  shared_state2->SetAll(gfx::Transform(),
-                        gfx::Size(2, 2),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  CheckerboardDrawQuad* checkerboard_quad3 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad3->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(3, 3, 3, 3), gfx::Rect(3, 3, 3, 3),
-                             SkColor(), 1.f);
-
-  CheckerboardDrawQuad* checkerboard_quad4 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad4->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(4, 4, 4, 4), gfx::Rect(4, 4, 4, 4),
-                             SkColor(), 1.f);
-
-  // A second render pass with a quad.
-  RenderPassId contrib_id(4, 1);
-  gfx::Rect contrib_output_rect(10, 15, 12, 17);
-  gfx::Transform contrib_transform_to_root =
-      gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0);
-  gfx::Rect contrib_damage_rect(11, 16, 10, 15);
-  bool contrib_has_transparent_background = true;
-
-  scoped_ptr<TestRenderPass> contrib = TestRenderPass::Create();
-  contrib->SetAll(contrib_id,
-                  contrib_output_rect,
-                  contrib_damage_rect,
-                  contrib_transform_to_root,
-                  contrib_has_transparent_background);
-
-  SharedQuadState* contrib_shared_state =
-      contrib->CreateAndAppendSharedQuadState();
-  contrib_shared_state->SetAll(gfx::Transform(),
-                               gfx::Size(2, 2),
-                               gfx::Rect(),
-                               gfx::Rect(),
-                               false,
-                               1,
-                               SkXfermode::kSrcOver_Mode,
-                               0);
-
-  CheckerboardDrawQuad* contrib_quad =
-      contrib->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  contrib_quad->SetNew(contrib->shared_quad_state_list.back(),
-                       gfx::Rect(3, 3, 3, 3), gfx::Rect(3, 3, 3, 3), SkColor(),
-                       1.f);
-
-  // And a RenderPassDrawQuad for the contributing pass.
-  scoped_ptr<RenderPassDrawQuad> pass_quad =
-      make_scoped_ptr(new RenderPassDrawQuad);
-  pass_quad->SetNew(pass->shared_quad_state_list.back(),
-                    contrib_output_rect,
-                    contrib_output_rect,
-                    contrib_id,
-                    0,
-                    gfx::Vector2dF(),
-                    gfx::Size(),
-                    FilterOperations(),
-                    gfx::Vector2dF(),
-                    FilterOperations());
-
-  pass_list.push_back(pass.Pass());
-  pass_list.push_back(contrib.Pass());
-
-  // Make a copy with CopyAll().
-  RenderPassList copy_list;
-  RenderPass::CopyAll(pass_list, &copy_list);
-
-  CompareRenderPassLists(pass_list, copy_list);
-}
-
-TEST(RenderPassTest, CopyAllWithCulledQuads) {
-  RenderPassList pass_list;
-
-  RenderPassId id(3, 2);
-  gfx::Rect output_rect(45, 22, 120, 13);
-  gfx::Transform transform_to_root =
-      gfx::Transform(1.0, 0.5, 0.5, -0.5, -1.0, 0.0);
-  gfx::Rect damage_rect(56, 123, 19, 43);
-  bool has_transparent_background = true;
-
-  scoped_ptr<TestRenderPass> pass = TestRenderPass::Create();
-  pass->SetAll(id,
-               output_rect,
-               damage_rect,
-               transform_to_root,
-               has_transparent_background);
-
-  // A shared state with a quad.
-  SharedQuadState* shared_state1 = pass->CreateAndAppendSharedQuadState();
-  shared_state1->SetAll(gfx::Transform(),
-                        gfx::Size(1, 1),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  CheckerboardDrawQuad* checkerboard_quad1 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad1->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(1, 1, 1, 1), gfx::Rect(1, 1, 1, 1),
-                             SkColor(), 1.f);
-
-  // A shared state with no quads, they were culled.
-  SharedQuadState* shared_state2 = pass->CreateAndAppendSharedQuadState();
-  shared_state2->SetAll(gfx::Transform(),
-                        gfx::Size(2, 2),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  // A second shared state with no quads.
-  SharedQuadState* shared_state3 = pass->CreateAndAppendSharedQuadState();
-  shared_state3->SetAll(gfx::Transform(),
-                        gfx::Size(2, 2),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  // A last shared state with a quad again.
-  SharedQuadState* shared_state4 = pass->CreateAndAppendSharedQuadState();
-  shared_state4->SetAll(gfx::Transform(),
-                        gfx::Size(2, 2),
-                        gfx::Rect(),
-                        gfx::Rect(),
-                        false,
-                        1,
-                        SkXfermode::kSrcOver_Mode,
-                        0);
-
-  CheckerboardDrawQuad* checkerboard_quad2 =
-      pass->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad2->SetNew(pass->shared_quad_state_list.back(),
-                             gfx::Rect(3, 3, 3, 3), gfx::Rect(3, 3, 3, 3),
-                             SkColor(), 1.f);
-
-  pass_list.push_back(pass.Pass());
-
-  // Make a copy with CopyAll().
-  RenderPassList copy_list;
-  RenderPass::CopyAll(pass_list, &copy_list);
-
-  CompareRenderPassLists(pass_list, copy_list);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/quads/shared_quad_state.cc b/cc/quads/shared_quad_state.cc
deleted file mode 100644
index 5e46fcc..0000000
--- a/cc/quads/shared_quad_state.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/shared_quad_state.h"
-
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "cc/debug/traced_value.h"
-
-namespace cc {
-
-SharedQuadState::SharedQuadState()
-    : is_clipped(false),
-      opacity(0.f),
-      blend_mode(SkXfermode::kSrcOver_Mode),
-      sorting_context_id(0) {
-}
-
-SharedQuadState::~SharedQuadState() {
-  TRACE_EVENT_OBJECT_DELETED_WITH_ID(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
-      "cc::SharedQuadState", this);
-}
-
-void SharedQuadState::CopyFrom(const SharedQuadState* other) {
-  *this = *other;
-}
-
-void SharedQuadState::SetAll(const gfx::Transform& content_to_target_transform,
-                             const gfx::Size& content_bounds,
-                             const gfx::Rect& visible_content_rect,
-                             const gfx::Rect& clip_rect,
-                             bool is_clipped,
-                             float opacity,
-                             SkXfermode::Mode blend_mode,
-                             int sorting_context_id) {
-  this->content_to_target_transform = content_to_target_transform;
-  this->content_bounds = content_bounds;
-  this->visible_content_rect = visible_content_rect;
-  this->clip_rect = clip_rect;
-  this->is_clipped = is_clipped;
-  this->opacity = opacity;
-  this->blend_mode = blend_mode;
-  this->sorting_context_id = sorting_context_id;
-}
-
-void SharedQuadState::AsValueInto(base::trace_event::TracedValue* value) const {
-  MathUtil::AddToTracedValue("transform", content_to_target_transform, value);
-  MathUtil::AddToTracedValue("layer_content_bounds", content_bounds, value);
-  MathUtil::AddToTracedValue("layer_visible_content_rect", visible_content_rect,
-                             value);
-
-  value->SetBoolean("is_clipped", is_clipped);
-
-  MathUtil::AddToTracedValue("clip_rect", clip_rect, value);
-
-  value->SetDouble("opacity", opacity);
-  value->SetString("blend_mode", SkXfermode::ModeName(blend_mode));
-  TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.quads"),
-      value,
-      "cc::SharedQuadState",
-      this);
-}
-
-}  // namespace cc
diff --git a/cc/quads/shared_quad_state.h b/cc/quads/shared_quad_state.h
deleted file mode 100644
index 348a904..0000000
--- a/cc/quads/shared_quad_state.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_SHARED_QUAD_STATE_H_
-#define CC_QUADS_SHARED_QUAD_STATE_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "third_party/skia/include/core/SkXfermode.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/transform.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class Value;
-}
-
-namespace cc {
-
-// SharedQuadState holds a set of properties that are common across multiple
-// DrawQuads. It's purely an optimization - the properties behave in exactly the
-// same way as if they were replicated on each DrawQuad. A given SharedQuadState
-// can only be shared by DrawQuads that are adjacent in their RenderPass'
-// QuadList.
-class SharedQuadState {
- public:
-  SharedQuadState();
-  ~SharedQuadState();
-
-  void CopyFrom(const SharedQuadState* other);
-
-  void SetAll(const gfx::Transform& content_to_target_transform,
-              const gfx::Size& content_bounds,
-              const gfx::Rect& visible_content_rect,
-              const gfx::Rect& clip_rect,
-              bool is_clipped,
-              float opacity,
-              SkXfermode::Mode blend_mode,
-              int sorting_context_id);
-  void AsValueInto(base::trace_event::TracedValue* dict) const;
-
-  // Transforms from quad's original content space to its target content space.
-  gfx::Transform content_to_target_transform;
-  // This size lives in the content space for the quad's originating layer.
-  gfx::Size content_bounds;
-  // This rect lives in the content space for the quad's originating layer.
-  gfx::Rect visible_content_rect;
-  // This rect lives in the target content space.
-  gfx::Rect clip_rect;
-  bool is_clipped;
-  float opacity;
-  SkXfermode::Mode blend_mode;
-  int sorting_context_id;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_SHARED_QUAD_STATE_H_
diff --git a/cc/quads/solid_color_draw_quad.cc b/cc/quads/solid_color_draw_quad.cc
deleted file mode 100644
index 229e98b..0000000
--- a/cc/quads/solid_color_draw_quad.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/solid_color_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace cc {
-
-SolidColorDrawQuad::SolidColorDrawQuad()
-    : color(0), force_anti_aliasing_off(false) {}
-
-void SolidColorDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                                const gfx::Rect& rect,
-                                const gfx::Rect& visible_rect,
-                                SkColor color,
-                                bool force_anti_aliasing_off) {
-  gfx::Rect opaque_rect = SkColorGetA(color) == 255 ? rect : gfx::Rect();
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::SOLID_COLOR, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->force_anti_aliasing_off = force_anti_aliasing_off;
-}
-
-void SolidColorDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                                const gfx::Rect& rect,
-                                const gfx::Rect& opaque_rect,
-                                const gfx::Rect& visible_rect,
-                                bool needs_blending,
-                                SkColor color,
-                                bool force_anti_aliasing_off) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::SOLID_COLOR, rect, opaque_rect,
-                   visible_rect, needs_blending);
-  this->color = color;
-  this->force_anti_aliasing_off = force_anti_aliasing_off;
-}
-
-void SolidColorDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {}
-
-const SolidColorDrawQuad* SolidColorDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::SOLID_COLOR);
-  return static_cast<const SolidColorDrawQuad*>(quad);
-}
-
-void SolidColorDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  value->SetInteger("color", color);
-  value->SetBoolean("force_anti_aliasing_off", force_anti_aliasing_off);
-}
-
-}  // namespace cc
diff --git a/cc/quads/solid_color_draw_quad.h b/cc/quads/solid_color_draw_quad.h
deleted file mode 100644
index cf3ba07..0000000
--- a/cc/quads/solid_color_draw_quad.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_SOLID_COLOR_DRAW_QUAD_H_
-#define CC_QUADS_SOLID_COLOR_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-
-class SolidColorDrawQuad : public DrawQuad {
- public:
-  SolidColorDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& visible_rect,
-              SkColor color,
-              bool force_anti_aliasing_off);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              SkColor color,
-              bool force_anti_aliasing_off);
-
-  SkColor color;
-  bool force_anti_aliasing_off;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const SolidColorDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_SOLID_COLOR_DRAW_QUAD_H_
diff --git a/cc/quads/stream_video_draw_quad.cc b/cc/quads/stream_video_draw_quad.cc
deleted file mode 100644
index fb6f728..0000000
--- a/cc/quads/stream_video_draw_quad.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/stream_video_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-
-namespace cc {
-
-StreamVideoDrawQuad::StreamVideoDrawQuad() : resource_id(0) {}
-
-void StreamVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& opaque_rect,
-                                 const gfx::Rect& visible_rect,
-                                 unsigned resource_id,
-                                 const gfx::Transform& matrix) {
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->resource_id = resource_id;
-  this->matrix = matrix;
-}
-
-void StreamVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                                 const gfx::Rect& rect,
-                                 const gfx::Rect& opaque_rect,
-                                 const gfx::Rect& visible_rect,
-                                 bool needs_blending,
-                                 unsigned resource_id,
-                                 const gfx::Transform& matrix) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::STREAM_VIDEO_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->resource_id = resource_id;
-  this->matrix = matrix;
-}
-
-void StreamVideoDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  resource_id = callback.Run(resource_id);
-}
-
-const StreamVideoDrawQuad* StreamVideoDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::STREAM_VIDEO_CONTENT);
-  return static_cast<const StreamVideoDrawQuad*>(quad);
-}
-
-void StreamVideoDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  value->SetInteger("resource_id", resource_id);
-  MathUtil::AddToTracedValue("matrix", matrix, value);
-}
-
-}  // namespace cc
diff --git a/cc/quads/stream_video_draw_quad.h b/cc/quads/stream_video_draw_quad.h
deleted file mode 100644
index 0372d36..0000000
--- a/cc/quads/stream_video_draw_quad.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_STREAM_VIDEO_DRAW_QUAD_H_
-#define CC_QUADS_STREAM_VIDEO_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-class StreamVideoDrawQuad : public DrawQuad {
- public:
-  StreamVideoDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              unsigned resource_id,
-              const gfx::Transform& matrix);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              unsigned resource_id,
-              const gfx::Transform& matrix);
-
-  unsigned resource_id;
-  gfx::Transform matrix;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const StreamVideoDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_STREAM_VIDEO_DRAW_QUAD_H_
diff --git a/cc/quads/surface_draw_quad.cc b/cc/quads/surface_draw_quad.cc
deleted file mode 100644
index 5823558..0000000
--- a/cc/quads/surface_draw_quad.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/quads/surface_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace cc {
-
-SurfaceDrawQuad::SurfaceDrawQuad() {
-}
-
-void SurfaceDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                             const gfx::Rect& rect,
-                             const gfx::Rect& visible_rect,
-                             SurfaceId surface_id) {
-  gfx::Rect opaque_rect;
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::SURFACE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->surface_id = surface_id;
-}
-
-void SurfaceDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                             const gfx::Rect& rect,
-                             const gfx::Rect& opaque_rect,
-                             const gfx::Rect& visible_rect,
-                             bool needs_blending,
-                             SurfaceId surface_id) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::SURFACE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->surface_id = surface_id;
-}
-
-void SurfaceDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {}
-
-const SurfaceDrawQuad* SurfaceDrawQuad::MaterialCast(const DrawQuad* quad) {
-  DCHECK_EQ(quad->material, DrawQuad::SURFACE_CONTENT);
-  return static_cast<const SurfaceDrawQuad*>(quad);
-}
-
-void SurfaceDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
-  value->SetInteger("surface_id", surface_id.id);
-}
-
-
-}  // namespace cc
diff --git a/cc/quads/surface_draw_quad.h b/cc/quads/surface_draw_quad.h
deleted file mode 100644
index d1ca740..0000000
--- a/cc/quads/surface_draw_quad.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_QUADS_SURFACE_DRAW_QUAD_H_
-#define CC_QUADS_SURFACE_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/surfaces/surface_id.h"
-
-namespace cc {
-
-class SurfaceDrawQuad : public DrawQuad {
- public:
-  SurfaceDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& visible_rect,
-              SurfaceId surface_id);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              SurfaceId surface_id);
-
-  SurfaceId surface_id;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const SurfaceDrawQuad* MaterialCast(const DrawQuad* quad);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_SURFACE_DRAW_QUAD_H_
diff --git a/cc/quads/texture_draw_quad.cc b/cc/quads/texture_draw_quad.cc
deleted file mode 100644
index 318d4f8..0000000
--- a/cc/quads/texture_draw_quad.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/texture_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-#include "ui/gfx/geometry/vector2d_f.h"
-
-namespace cc {
-
-TextureDrawQuad::TextureDrawQuad()
-    : resource_id(0),
-      premultiplied_alpha(false),
-      background_color(SK_ColorTRANSPARENT),
-      flipped(false),
-      nearest_neighbor(false) {
-  this->vertex_opacity[0] = 0.f;
-  this->vertex_opacity[1] = 0.f;
-  this->vertex_opacity[2] = 0.f;
-  this->vertex_opacity[3] = 0.f;
-}
-
-void TextureDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                             const gfx::Rect& rect,
-                             const gfx::Rect& opaque_rect,
-                             const gfx::Rect& visible_rect,
-                             unsigned resource_id,
-                             bool premultiplied_alpha,
-                             const gfx::PointF& uv_top_left,
-                             const gfx::PointF& uv_bottom_right,
-                             SkColor background_color,
-                             const float vertex_opacity[4],
-                             bool flipped,
-                             bool nearest_neighbor) {
-  bool needs_blending = vertex_opacity[0] != 1.0f || vertex_opacity[1] != 1.0f
-      || vertex_opacity[2] != 1.0f || vertex_opacity[3] != 1.0f;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->resource_id = resource_id;
-  this->premultiplied_alpha = premultiplied_alpha;
-  this->uv_top_left = uv_top_left;
-  this->uv_bottom_right = uv_bottom_right;
-  this->background_color = background_color;
-  this->vertex_opacity[0] = vertex_opacity[0];
-  this->vertex_opacity[1] = vertex_opacity[1];
-  this->vertex_opacity[2] = vertex_opacity[2];
-  this->vertex_opacity[3] = vertex_opacity[3];
-  this->flipped = flipped;
-  this->nearest_neighbor = nearest_neighbor;
-}
-
-void TextureDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                             const gfx::Rect& rect,
-                             const gfx::Rect& opaque_rect,
-                             const gfx::Rect& visible_rect,
-                             bool needs_blending,
-                             unsigned resource_id,
-                             bool premultiplied_alpha,
-                             const gfx::PointF& uv_top_left,
-                             const gfx::PointF& uv_bottom_right,
-                             SkColor background_color,
-                             const float vertex_opacity[4],
-                             bool flipped,
-                             bool nearest_neighbor) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::TEXTURE_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->resource_id = resource_id;
-  this->premultiplied_alpha = premultiplied_alpha;
-  this->uv_top_left = uv_top_left;
-  this->uv_bottom_right = uv_bottom_right;
-  this->background_color = background_color;
-  this->vertex_opacity[0] = vertex_opacity[0];
-  this->vertex_opacity[1] = vertex_opacity[1];
-  this->vertex_opacity[2] = vertex_opacity[2];
-  this->vertex_opacity[3] = vertex_opacity[3];
-  this->flipped = flipped;
-  this->nearest_neighbor = nearest_neighbor;
-}
-
-void TextureDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  resource_id = callback.Run(resource_id);
-}
-
-const TextureDrawQuad* TextureDrawQuad::MaterialCast(const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::TEXTURE_CONTENT);
-  return static_cast<const TextureDrawQuad*>(quad);
-}
-
-void TextureDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
-  value->SetInteger("resource_id", resource_id);
-  value->SetBoolean("premultiplied_alpha", premultiplied_alpha);
-
-  MathUtil::AddToTracedValue("uv_top_left", uv_top_left, value);
-  MathUtil::AddToTracedValue("uv_bottom_right", uv_bottom_right, value);
-
-  value->SetInteger("background_color", background_color);
-
-  value->BeginArray("vertex_opacity");
-  for (size_t i = 0; i < 4; ++i)
-    value->AppendDouble(vertex_opacity[i]);
-  value->EndArray();
-
-  value->SetBoolean("flipped", flipped);
-  value->SetBoolean("nearest_neighbor", nearest_neighbor);
-}
-
-}  // namespace cc
diff --git a/cc/quads/texture_draw_quad.h b/cc/quads/texture_draw_quad.h
deleted file mode 100644
index 8b595d4..0000000
--- a/cc/quads/texture_draw_quad.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_TEXTURE_DRAW_QUAD_H_
-#define CC_QUADS_TEXTURE_DRAW_QUAD_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "ui/gfx/geometry/rect_f.h"
-
-namespace cc {
-
-class TextureDrawQuad : public DrawQuad {
- public:
-  TextureDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              unsigned resource_id,
-              bool premultiplied_alpha,
-              const gfx::PointF& uv_top_left,
-              const gfx::PointF& uv_bottom_right,
-              SkColor background_color,
-              const float vertex_opacity[4],
-              bool flipped,
-              bool nearest_neighbor);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              unsigned resource_id,
-              bool premultiplied_alpha,
-              const gfx::PointF& uv_top_left,
-              const gfx::PointF& uv_bottom_right,
-              SkColor background_color,
-              const float vertex_opacity[4],
-              bool flipped,
-              bool nearest_neighbor);
-
-  unsigned resource_id;
-  bool premultiplied_alpha;
-  gfx::PointF uv_top_left;
-  gfx::PointF uv_bottom_right;
-  SkColor background_color;
-  float vertex_opacity[4];
-  bool flipped;
-  bool nearest_neighbor;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const TextureDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_TEXTURE_DRAW_QUAD_H_
diff --git a/cc/quads/tile_draw_quad.cc b/cc/quads/tile_draw_quad.cc
deleted file mode 100644
index aa8f748..0000000
--- a/cc/quads/tile_draw_quad.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/tile_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-
-namespace cc {
-
-TileDrawQuad::TileDrawQuad()
-    : resource_id(0) {
-}
-
-TileDrawQuad::~TileDrawQuad() {
-}
-
-void TileDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                          const gfx::Rect& rect,
-                          const gfx::Rect& opaque_rect,
-                          const gfx::Rect& visible_rect,
-                          unsigned resource_id,
-                          const gfx::RectF& tex_coord_rect,
-                          const gfx::Size& texture_size,
-                          bool swizzle_contents,
-                          bool nearest_neighbor) {
-  ContentDrawQuadBase::SetNew(shared_quad_state,
-                              DrawQuad::TILED_CONTENT,
-                              rect,
-                              opaque_rect,
-                              visible_rect,
-                              tex_coord_rect,
-                              texture_size,
-                              swizzle_contents,
-                              nearest_neighbor);
-  this->resource_id = resource_id;
-}
-
-void TileDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                          const gfx::Rect& rect,
-                          const gfx::Rect& opaque_rect,
-                          const gfx::Rect& visible_rect,
-                          bool needs_blending,
-                          unsigned resource_id,
-                          const gfx::RectF& tex_coord_rect,
-                          const gfx::Size& texture_size,
-                          bool swizzle_contents,
-                          bool nearest_neighbor) {
-  ContentDrawQuadBase::SetAll(shared_quad_state, DrawQuad::TILED_CONTENT, rect,
-                              opaque_rect, visible_rect, needs_blending,
-                              tex_coord_rect, texture_size, swizzle_contents,
-                              nearest_neighbor);
-  this->resource_id = resource_id;
-}
-
-void TileDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  resource_id = callback.Run(resource_id);
-}
-
-const TileDrawQuad* TileDrawQuad::MaterialCast(const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::TILED_CONTENT);
-  return static_cast<const TileDrawQuad*>(quad);
-}
-
-void TileDrawQuad::ExtendValue(base::trace_event::TracedValue* value) const {
-  ContentDrawQuadBase::ExtendValue(value);
-  value->SetInteger("resource_id", resource_id);
-}
-
-}  // namespace cc
diff --git a/cc/quads/tile_draw_quad.h b/cc/quads/tile_draw_quad.h
deleted file mode 100644
index 8162987..0000000
--- a/cc/quads/tile_draw_quad.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_TILE_DRAW_QUAD_H_
-#define CC_QUADS_TILE_DRAW_QUAD_H_
-
-#include "cc/quads/content_draw_quad_base.h"
-
-namespace cc {
-
-class TileDrawQuad : public ContentDrawQuadBase {
- public:
-  TileDrawQuad();
-  ~TileDrawQuad() override;
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              unsigned resource_id,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& texture_size,
-              bool swizzle_contents,
-              bool nearest_neighbor);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              unsigned resource_id,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& texture_size,
-              bool swizzle_contents,
-              bool nearest_neighbor);
-
-  unsigned resource_id;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const TileDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_TILE_DRAW_QUAD_H_
diff --git a/cc/quads/yuv_video_draw_quad.cc b/cc/quads/yuv_video_draw_quad.cc
deleted file mode 100644
index 1d0e2f3..0000000
--- a/cc/quads/yuv_video_draw_quad.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/quads/yuv_video_draw_quad.h"
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "cc/base/math_util.h"
-
-namespace cc {
-
-YUVVideoDrawQuad::YUVVideoDrawQuad()
-    : y_plane_resource_id(0),
-      u_plane_resource_id(0),
-      v_plane_resource_id(0),
-      a_plane_resource_id(0) {}
-YUVVideoDrawQuad::~YUVVideoDrawQuad() {}
-
-void YUVVideoDrawQuad::SetNew(const SharedQuadState* shared_quad_state,
-                              const gfx::Rect& rect,
-                              const gfx::Rect& opaque_rect,
-                              const gfx::Rect& visible_rect,
-                              const gfx::RectF& tex_coord_rect,
-                              const gfx::Size& tex_size,
-                              unsigned y_plane_resource_id,
-                              unsigned u_plane_resource_id,
-                              unsigned v_plane_resource_id,
-                              unsigned a_plane_resource_id,
-                              ColorSpace color_space) {
-  bool needs_blending = false;
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->tex_coord_rect = tex_coord_rect;
-  this->tex_size = tex_size;
-  this->y_plane_resource_id = y_plane_resource_id;
-  this->u_plane_resource_id = u_plane_resource_id;
-  this->v_plane_resource_id = v_plane_resource_id;
-  this->a_plane_resource_id = a_plane_resource_id;
-  this->color_space = color_space;
-}
-
-void YUVVideoDrawQuad::SetAll(const SharedQuadState* shared_quad_state,
-                              const gfx::Rect& rect,
-                              const gfx::Rect& opaque_rect,
-                              const gfx::Rect& visible_rect,
-                              bool needs_blending,
-                              const gfx::RectF& tex_coord_rect,
-                              const gfx::Size& tex_size,
-                              unsigned y_plane_resource_id,
-                              unsigned u_plane_resource_id,
-                              unsigned v_plane_resource_id,
-                              unsigned a_plane_resource_id,
-                              ColorSpace color_space) {
-  DrawQuad::SetAll(shared_quad_state, DrawQuad::YUV_VIDEO_CONTENT, rect,
-                   opaque_rect, visible_rect, needs_blending);
-  this->tex_coord_rect = tex_coord_rect;
-  this->tex_size = tex_size;
-  this->y_plane_resource_id = y_plane_resource_id;
-  this->u_plane_resource_id = u_plane_resource_id;
-  this->v_plane_resource_id = v_plane_resource_id;
-  this->a_plane_resource_id = a_plane_resource_id;
-  this->color_space = color_space;
-}
-
-void YUVVideoDrawQuad::IterateResources(
-    const ResourceIteratorCallback& callback) {
-  y_plane_resource_id = callback.Run(y_plane_resource_id);
-  u_plane_resource_id = callback.Run(u_plane_resource_id);
-  v_plane_resource_id = callback.Run(v_plane_resource_id);
-  if (a_plane_resource_id)
-    a_plane_resource_id = callback.Run(a_plane_resource_id);
-}
-
-const YUVVideoDrawQuad* YUVVideoDrawQuad::MaterialCast(
-    const DrawQuad* quad) {
-  DCHECK(quad->material == DrawQuad::YUV_VIDEO_CONTENT);
-  return static_cast<const YUVVideoDrawQuad*>(quad);
-}
-
-void YUVVideoDrawQuad::ExtendValue(
-    base::trace_event::TracedValue* value) const {
-  MathUtil::AddToTracedValue("tex_coord_rect", tex_coord_rect, value);
-  MathUtil::AddToTracedValue("tex_size", tex_size, value);
-  value->SetInteger("y_plane_resource_id", y_plane_resource_id);
-  value->SetInteger("u_plane_resource_id", u_plane_resource_id);
-  value->SetInteger("v_plane_resource_id", v_plane_resource_id);
-  value->SetInteger("a_plane_resource_id", a_plane_resource_id);
-}
-
-}  // namespace cc
diff --git a/cc/quads/yuv_video_draw_quad.h b/cc/quads/yuv_video_draw_quad.h
deleted file mode 100644
index 20b019e..0000000
--- a/cc/quads/yuv_video_draw_quad.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_QUADS_YUV_VIDEO_DRAW_QUAD_H_
-#define CC_QUADS_YUV_VIDEO_DRAW_QUAD_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/draw_quad.h"
-
-namespace cc {
-
-class YUVVideoDrawQuad : public DrawQuad {
- public:
-  enum ColorSpace {
-    REC_601,  // SDTV standard with restricted "studio swing" color range.
-    REC_709,  // HDTV standard with restricted "studio swing" color range.
-    JPEG,     // Full color range [0, 255] JPEG color space.
-    COLOR_SPACE_LAST = JPEG
-  };
-
-  ~YUVVideoDrawQuad() override;
-
-  YUVVideoDrawQuad();
-
-  void SetNew(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& tex_size,
-              unsigned y_plane_resource_id,
-              unsigned u_plane_resource_id,
-              unsigned v_plane_resource_id,
-              unsigned a_plane_resource_id,
-              ColorSpace color_space);
-
-  void SetAll(const SharedQuadState* shared_quad_state,
-              const gfx::Rect& rect,
-              const gfx::Rect& opaque_rect,
-              const gfx::Rect& visible_rect,
-              bool needs_blending,
-              const gfx::RectF& tex_coord_rect,
-              const gfx::Size& tex_size,
-              unsigned y_plane_resource_id,
-              unsigned u_plane_resource_id,
-              unsigned v_plane_resource_id,
-              unsigned a_plane_resource_id,
-              ColorSpace color_space);
-
-  gfx::RectF tex_coord_rect;
-  // Empty texture size implies no clamping of texture coordinates.
-  gfx::Size tex_size;
-  unsigned y_plane_resource_id;
-  unsigned u_plane_resource_id;
-  unsigned v_plane_resource_id;
-  unsigned a_plane_resource_id;
-  ColorSpace color_space;
-
-  void IterateResources(const ResourceIteratorCallback& callback) override;
-
-  static const YUVVideoDrawQuad* MaterialCast(const DrawQuad*);
-
- private:
-  void ExtendValue(base::trace_event::TracedValue* value) const override;
-};
-
-}  // namespace cc
-
-#endif  // CC_QUADS_YUV_VIDEO_DRAW_QUAD_H_
diff --git a/cc/resources/layer_quad.cc b/cc/resources/layer_quad.cc
deleted file mode 100644
index ff336ba..0000000
--- a/cc/resources/layer_quad.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/resources/layer_quad.h"
-
-#include "base/logging.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-namespace cc {
-
-LayerQuad::Edge::Edge(const gfx::PointF& p, const gfx::PointF& q) {
-  if (p == q) {
-    degenerate_ = true;
-    return;
-  }
-  degenerate_ = false;
-  gfx::Vector2dF tangent(p.y() - q.y(), q.x() - p.x());
-  float cross2 = p.x() * q.y() - q.x() * p.y();
-
-  set(tangent.x(), tangent.y(), cross2);
-  scale(1.0f / tangent.Length());
-}
-
-gfx::PointF LayerQuad::Edge::Intersect(const LayerQuad::Edge& e) const {
-  DCHECK(!degenerate());
-  DCHECK(!e.degenerate());
-
-  return gfx::PointF((y() * e.z() - e.y() * z()) / (x() * e.y() - e.x() * y()),
-                     (x() * e.z() - e.x() * z()) / (e.x() * y() - x() * e.y()));
-}
-
-LayerQuad::LayerQuad(const gfx::QuadF& quad) {
-  // Create edges.
-  left_ = Edge(quad.p4(), quad.p1());
-  right_ = Edge(quad.p2(), quad.p3());
-  top_ = Edge(quad.p1(), quad.p2());
-  bottom_ = Edge(quad.p3(), quad.p4());
-
-  float sign = quad.IsCounterClockwise() ? -1 : 1;
-  left_.scale(sign);
-  right_.scale(sign);
-  top_.scale(sign);
-  bottom_.scale(sign);
-}
-
-LayerQuad::LayerQuad(const Edge& left,
-                     const Edge& top,
-                     const Edge& right,
-                     const Edge& bottom)
-    : left_(left),
-      top_(top),
-      right_(right),
-      bottom_(bottom) {}
-
-gfx::QuadF LayerQuad::ToQuadF() const {
-  size_t num_degenerate_edges = left_.degenerate() + right_.degenerate() +
-                                top_.degenerate() + bottom_.degenerate();
-  if (num_degenerate_edges > 1) {
-    return gfx::QuadF();
-  }
-
-  if (left_.degenerate()) {
-    return gfx::QuadF(top_.Intersect(bottom_), top_.Intersect(right_),
-                      right_.Intersect(bottom_), bottom_.Intersect(top_));
-  }
-  if (right_.degenerate()) {
-    return gfx::QuadF(left_.Intersect(top_), top_.Intersect(bottom_),
-                      bottom_.Intersect(top_), bottom_.Intersect(left_));
-  }
-  if (top_.degenerate()) {
-    return gfx::QuadF(left_.Intersect(right_), right_.Intersect(left_),
-                      right_.Intersect(bottom_), bottom_.Intersect(left_));
-  }
-  if (bottom_.degenerate()) {
-    return gfx::QuadF(left_.Intersect(top_), top_.Intersect(right_),
-                      right_.Intersect(left_), left_.Intersect(right_));
-  }
-  return gfx::QuadF(left_.Intersect(top_),
-                    top_.Intersect(right_),
-                    right_.Intersect(bottom_),
-                    bottom_.Intersect(left_));
-}
-
-void LayerQuad::ToFloatArray(float flattened[12]) const {
-  if (left_.degenerate()) {
-    flattened[0] = bottom_.x();
-    flattened[1] = bottom_.y();
-    flattened[2] = bottom_.z();
-  } else {
-    flattened[0] = left_.x();
-    flattened[1] = left_.y();
-    flattened[2] = left_.z();
-  }
-  if (top_.degenerate()) {
-    flattened[3] = left_.x();
-    flattened[4] = left_.y();
-    flattened[5] = left_.z();
-  } else {
-    flattened[3] = top_.x();
-    flattened[4] = top_.y();
-    flattened[5] = top_.z();
-  }
-  if (right_.degenerate()) {
-    flattened[6] = top_.x();
-    flattened[7] = top_.y();
-    flattened[8] = top_.z();
-  } else {
-    flattened[6] = right_.x();
-    flattened[7] = right_.y();
-    flattened[8] = right_.z();
-  }
-  if (bottom_.degenerate()) {
-    flattened[9] = right_.x();
-    flattened[10] = right_.y();
-    flattened[11] = right_.z();
-  } else {
-    flattened[9] = bottom_.x();
-    flattened[10] = bottom_.y();
-    flattened[11] = bottom_.z();
-  }
-}
-
-}  // namespace cc
diff --git a/cc/resources/layer_quad.h b/cc/resources/layer_quad.h
deleted file mode 100644
index 99ba054..0000000
--- a/cc/resources/layer_quad.h
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2011 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.
-
-
-#ifndef CC_RESOURCES_LAYER_QUAD_H_
-#define CC_RESOURCES_LAYER_QUAD_H_
-
-#include "base/basictypes.h"
-#include "ui/gfx/geometry/point_f.h"
-
-namespace gfx {
-class QuadF;
-}
-
-static const float kAntiAliasingInflateDistance = 0.5f;
-
-namespace cc {
-
-class LayerQuad {
- public:
-  class Edge {
-   public:
-    Edge() : x_(0), y_(0), z_(0), degenerate_(false) {}
-    Edge(const gfx::PointF& p, const gfx::PointF& q);
-
-    float x() const { return x_; }
-    float y() const { return y_; }
-    float z() const { return z_; }
-
-    void set_x(float x) { x_ = x; }
-    void set_y(float y) { y_ = y; }
-    void set_z(float z) { z_ = z; }
-    void set(float x, float y, float z) {
-      x_ = x;
-      y_ = y;
-      z_ = z;
-    }
-
-    void move_x(float dx) { x_ += dx; }
-    void move_y(float dy) { y_ += dy; }
-    void move_z(float dz) { z_ += dz; }
-    void move(float dx, float dy, float dz) {
-      x_ += dx;
-      y_ += dy;
-      z_ += dz;
-    }
-
-    void scale_x(float sx) { x_ *= sx; }
-    void scale_y(float sy) { y_ *= sy; }
-    void scale_z(float sz) { z_ *= sz; }
-    void scale(float sx, float sy, float sz) {
-      x_ *= sx;
-      y_ *= sy;
-      z_ *= sz;
-    }
-    void scale(float s) { scale(s, s, s); }
-
-    bool degenerate() const { return degenerate_; }
-
-    gfx::PointF Intersect(const Edge& e) const;
-
-   private:
-    float x_;
-    float y_;
-    float z_;
-    bool degenerate_;
-  };
-
-  LayerQuad(const Edge& left,
-            const Edge& top,
-            const Edge& right,
-            const Edge& bottom);
-  explicit LayerQuad(const gfx::QuadF& quad);
-
-  Edge left() const { return left_; }
-  Edge top() const { return top_; }
-  Edge right() const { return right_; }
-  Edge bottom() const { return bottom_; }
-
-  void InflateX(float dx) {
-    left_.move_z(dx);
-    right_.move_z(dx);
-  }
-  void InflateY(float dy) {
-    top_.move_z(dy);
-    bottom_.move_z(dy);
-  }
-  void Inflate(float d) {
-    InflateX(d);
-    InflateY(d);
-  }
-  void InflateAntiAliasingDistance() {
-    Inflate(kAntiAliasingInflateDistance);
-  }
-
-  gfx::QuadF ToQuadF() const;
-
-  void ToFloatArray(float flattened[12]) const;
-
- private:
-  Edge left_;
-  Edge top_;
-  Edge right_;
-  Edge bottom_;
-
-  DISALLOW_COPY_AND_ASSIGN(LayerQuad);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_LAYER_QUAD_H_
diff --git a/cc/resources/layer_quad_unittest.cc b/cc/resources/layer_quad_unittest.cc
deleted file mode 100644
index 90f61be..0000000
--- a/cc/resources/layer_quad_unittest.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/resources/layer_quad.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/quad_f.h"
-
-namespace cc {
-namespace {
-
-TEST(LayerQuadTest, QuadFConversion) {
-  gfx::PointF p1(-0.5f, -0.5f);
-  gfx::PointF p2(0.5f, -0.5f);
-  gfx::PointF p3(0.5f, 0.5f);
-  gfx::PointF p4(-0.5f, 0.5f);
-
-  gfx::QuadF quad_cw(p1, p2, p3, p4);
-  LayerQuad layer_quad_cw(quad_cw);
-  EXPECT_EQ(layer_quad_cw.ToQuadF(), quad_cw);
-
-  gfx::QuadF quad_ccw(p1, p4, p3, p2);
-  LayerQuad layer_quad_ccw(quad_ccw);
-  EXPECT_EQ(layer_quad_ccw.ToQuadF(), quad_ccw);
-}
-
-TEST(LayerQuadTest, Inflate) {
-  gfx::PointF p1(-0.5f, -0.5f);
-  gfx::PointF p2(0.5f, -0.5f);
-  gfx::PointF p3(0.5f, 0.5f);
-  gfx::PointF p4(-0.5f, 0.5f);
-
-  gfx::QuadF quad(p1, p2, p3, p4);
-  LayerQuad layer_quad(quad);
-  quad.Scale(2.f, 2.f);
-  layer_quad.Inflate(0.5f);
-  EXPECT_EQ(layer_quad.ToQuadF(), quad);
-}
-
-TEST(LayerQuadTest, Degenerate) {
-  gfx::QuadF quad;
-  gfx::PointF p1(1.0f, 1.0f);
-  gfx::PointF p2(0.0f, 1.0f);
-  gfx::PointF p3(1.0f, 0.0f);
-  gfx::QuadF triangle(p1, p2, p3, p1);
-
-  LayerQuad::Edge e1d(p1, p1);
-  LayerQuad::Edge e2d(p2, p2);
-  LayerQuad::Edge e2(p1, p2);
-  LayerQuad::Edge e3(p2, p3);
-  LayerQuad::Edge e4(p3, p1);
-  EXPECT_TRUE(e1d.degenerate());
-  EXPECT_TRUE(e2d.degenerate());
-  EXPECT_FALSE(e2.degenerate());
-  EXPECT_FALSE(e3.degenerate());
-  EXPECT_FALSE(e4.degenerate());
-
-  LayerQuad degenerate_quad(e1d, e2d, e2, e3);
-  // With more than one degenerate edge, we expect the quad to be zero.
-  EXPECT_EQ(quad, degenerate_quad.ToQuadF());
-
-  LayerQuad triangle_quad(e1d, e2, e3, e4);
-  // With only one degenerate edge, we expect the quad to be a triangle.
-  EXPECT_EQ(triangle, triangle_quad.ToQuadF());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/platform_color.h b/cc/resources/platform_color.h
deleted file mode 100644
index 17eddc1..0000000
--- a/cc/resources/platform_color.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_RESOURCES_PLATFORM_COLOR_H_
-#define CC_RESOURCES_PLATFORM_COLOR_H_
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "cc/resources/resource_format.h"
-#include "third_party/skia/include/core/SkTypes.h"
-
-namespace cc {
-
-class PlatformColor {
- public:
-  enum SourceDataFormat {
-    SOURCE_FORMAT_RGBA8,
-    SOURCE_FORMAT_BGRA8
-  };
-
-  static SourceDataFormat Format() {
-    return SK_B32_SHIFT ? SOURCE_FORMAT_RGBA8 : SOURCE_FORMAT_BGRA8;
-  }
-
-  // Returns the most efficient texture format for this platform.
-  static ResourceFormat BestTextureFormat(bool supports_bgra8888) {
-    switch (Format()) {
-      case SOURCE_FORMAT_BGRA8:
-        return (supports_bgra8888) ? BGRA_8888 : RGBA_8888;
-      case SOURCE_FORMAT_RGBA8:
-        return RGBA_8888;
-    }
-    NOTREACHED();
-    return RGBA_8888;
-  }
-
-  // Return true if the given texture format has the same component order
-  // as the color on this platform.
-  static bool SameComponentOrder(ResourceFormat format) {
-    switch (Format()) {
-      case SOURCE_FORMAT_RGBA8:
-        return format == RGBA_8888 || format == RGBA_4444;
-      case SOURCE_FORMAT_BGRA8:
-        return format == BGRA_8888 || format == RGBA_4444;
-    }
-    NOTREACHED();
-    return false;
-  }
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(PlatformColor);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_PLATFORM_COLOR_H_
diff --git a/cc/resources/platform_color_unittest.cc b/cc/resources/platform_color_unittest.cc
deleted file mode 100644
index 83b2a1e..0000000
--- a/cc/resources/platform_color_unittest.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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.
-
-#include "cc/resources/platform_color.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-// Verify SameComponentOrder on this platform.
-TEST(PlatformColorTest, SameComponentOrder) {
-  bool rgba = !!SK_B32_SHIFT;
-
-  for (size_t i = 0; i <= RESOURCE_FORMAT_MAX; ++i) {
-    ResourceFormat format = static_cast<ResourceFormat>(i);
-    switch (format) {
-      case RGBA_8888:
-        EXPECT_EQ(rgba, PlatformColor::SameComponentOrder(format));
-        break;
-      case RGBA_4444:
-        // RGBA_4444 indicates the number of bytes per pixel but the format
-        // doesn't actually imply RGBA ordering. It uses the native ordering.
-        EXPECT_EQ(true, PlatformColor::SameComponentOrder(format));
-        break;
-      case BGRA_8888:
-        EXPECT_NE(rgba, PlatformColor::SameComponentOrder(format));
-        break;
-      case ALPHA_8:
-      case LUMINANCE_8:
-      case RGB_565:
-      case ETC1:
-      case RED_8:
-        EXPECT_FALSE(PlatformColor::SameComponentOrder(format));
-        break;
-    }
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/release_callback.h b/cc/resources/release_callback.h
deleted file mode 100644
index b471381..0000000
--- a/cc/resources/release_callback.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_RELEASE_CALLBACK_H_
-#define CC_RESOURCES_RELEASE_CALLBACK_H_
-
-#include "base/callback.h"
-
-namespace cc {
-
-typedef base::Callback<void(uint32 sync_point, bool is_lost)> ReleaseCallback;
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RELEASE_CALLBACK_H_
diff --git a/cc/resources/release_callback_impl.h b/cc/resources/release_callback_impl.h
deleted file mode 100644
index 89f22b6..0000000
--- a/cc/resources/release_callback_impl.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_
-#define CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_
-
-#include "base/callback.h"
-
-namespace cc {
-class BlockingTaskRunner;
-
-typedef base::Callback<void(uint32 sync_point,
-                            bool is_lost,
-                            BlockingTaskRunner* main_thread_task_runner)>
-    ReleaseCallbackImpl;
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_
diff --git a/cc/resources/resource.cc b/cc/resources/resource.cc
deleted file mode 100644
index 9bbcd4f..0000000
--- a/cc/resources/resource.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/resource.h"
-
-namespace cc {
-
-size_t Resource::bytes() const {
-  if (size_.IsEmpty())
-    return 0;
-
-  return MemorySizeBytes(size_, format_);
-}
-
-
-}  // namespace cc
diff --git a/cc/resources/resource.h b/cc/resources/resource.h
deleted file mode 100644
index 642ba16..0000000
--- a/cc/resources/resource.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_RESOURCES_RESOURCE_H_
-#define CC_RESOURCES_RESOURCE_H_
-
-#include "cc/resources/resource_provider.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class Resource {
- public:
-  Resource() : id_(0) {}
-  Resource(unsigned id, const gfx::Size& size, ResourceFormat format)
-      : id_(id),
-        size_(size),
-        format_(format) {}
-
-  ResourceProvider::ResourceId id() const { return id_; }
-  gfx::Size size() const { return size_; }
-  ResourceFormat format() const { return format_; }
-  size_t bytes() const;
-
-  inline static size_t MemorySizeBytes(const gfx::Size& size,
-                                       ResourceFormat format) {
-    DCHECK_EQ(0u, (BitsPerPixel(format) * size.width() * size.height()) % 8);
-    return (BitsPerPixel(format) * size.width() * size.height()) / 8;
-  }
-
- protected:
-  void set_id(ResourceProvider::ResourceId id) { id_ = id; }
-  void set_dimensions(const gfx::Size& size, ResourceFormat format) {
-    size_ = size;
-    format_ = format;
-  }
-
- private:
-  ResourceProvider::ResourceId id_;
-  gfx::Size size_;
-  ResourceFormat format_;
-
-  DISALLOW_COPY_AND_ASSIGN(Resource);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RESOURCE_H_
diff --git a/cc/resources/resource_format.cc b/cc/resources/resource_format.cc
deleted file mode 100644
index 45581b8..0000000
--- a/cc/resources/resource_format.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/resource_format.h"
-
-namespace cc {
-
-SkColorType ResourceFormatToSkColorType(ResourceFormat format) {
-  switch (format) {
-    case RGBA_4444:
-      return kARGB_4444_SkColorType;
-    case RGBA_8888:
-    case BGRA_8888:
-      return kN32_SkColorType;
-    case ETC1:
-    case ALPHA_8:
-    case LUMINANCE_8:
-    case RGB_565:
-    case RED_8:
-      NOTREACHED();
-      break;
-  }
-  NOTREACHED();
-  return kN32_SkColorType;
-}
-
-}  // namespace cc
diff --git a/cc/resources/resource_format.h b/cc/resources/resource_format.h
deleted file mode 100644
index d785ab7..0000000
--- a/cc/resources/resource_format.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_RESOURCE_FORMAT_H_
-#define CC_RESOURCES_RESOURCE_FORMAT_H_
-
-#include "base/logging.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-// Keep in sync with arrays below.
-enum ResourceFormat {
-  RGBA_8888,
-  RGBA_4444,
-  BGRA_8888,
-  ALPHA_8,
-  LUMINANCE_8,
-  RGB_565,
-  ETC1,
-  RED_8,
-  RESOURCE_FORMAT_MAX = RED_8,
-};
-
-SkColorType ResourceFormatToSkColorType(ResourceFormat format);
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RESOURCE_FORMAT_H_
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc
deleted file mode 100644
index 2284780..0000000
--- a/cc/resources/resource_pool.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/resource_pool.h"
-
-#include "cc/resources/resource_provider.h"
-#include "cc/resources/scoped_resource.h"
-
-namespace cc {
-
-ResourcePool::ResourcePool(ResourceProvider* resource_provider, GLenum target)
-    : resource_provider_(resource_provider),
-      target_(target),
-      max_memory_usage_bytes_(0),
-      max_unused_memory_usage_bytes_(0),
-      max_resource_count_(0),
-      memory_usage_bytes_(0),
-      unused_memory_usage_bytes_(0),
-      resource_count_(0) {}
-
-ResourcePool::~ResourcePool() {
-  while (!busy_resources_.empty()) {
-    DidFinishUsingResource(busy_resources_.front());
-    busy_resources_.pop_front();
-  }
-
-  SetResourceUsageLimits(0, 0, 0);
-  DCHECK_EQ(0u, unused_resources_.size());
-  DCHECK_EQ(0u, memory_usage_bytes_);
-  DCHECK_EQ(0u, unused_memory_usage_bytes_);
-  DCHECK_EQ(0u, resource_count_);
-}
-
-scoped_ptr<ScopedResource> ResourcePool::AcquireResource(
-    const gfx::Size& size, ResourceFormat format) {
-  for (ResourceList::iterator it = unused_resources_.begin();
-       it != unused_resources_.end();
-       ++it) {
-    ScopedResource* resource = *it;
-    DCHECK(resource_provider_->CanLockForWrite(resource->id()));
-
-    if (resource->format() != format)
-      continue;
-    if (resource->size() != size)
-      continue;
-
-    unused_resources_.erase(it);
-    unused_memory_usage_bytes_ -= resource->bytes();
-    return make_scoped_ptr(resource);
-  }
-
-  scoped_ptr<ScopedResource> resource =
-      ScopedResource::Create(resource_provider_);
-  resource->AllocateManaged(size, target_, format);
-
-  memory_usage_bytes_ += resource->bytes();
-  ++resource_count_;
-  return resource.Pass();
-}
-
-void ResourcePool::ReleaseResource(scoped_ptr<ScopedResource> resource) {
-  busy_resources_.push_back(resource.release());
-}
-
-void ResourcePool::SetResourceUsageLimits(size_t max_memory_usage_bytes,
-                                          size_t max_unused_memory_usage_bytes,
-                                          size_t max_resource_count) {
-  max_memory_usage_bytes_ = max_memory_usage_bytes;
-  max_unused_memory_usage_bytes_ = max_unused_memory_usage_bytes;
-  max_resource_count_ = max_resource_count;
-
-  ReduceResourceUsage();
-}
-
-void ResourcePool::ReduceResourceUsage() {
-  while (!unused_resources_.empty()) {
-    if (!ResourceUsageTooHigh())
-      break;
-
-    // LRU eviction pattern. Most recently used might be blocked by
-    // a read lock fence but it's still better to evict the least
-    // recently used as it prevents a resource that is hard to reuse
-    // because of unique size from being kept around. Resources that
-    // can't be locked for write might also not be truly free-able.
-    // We can free the resource here but it doesn't mean that the
-    // memory is necessarily returned to the OS.
-    ScopedResource* resource = unused_resources_.front();
-    unused_resources_.pop_front();
-    memory_usage_bytes_ -= resource->bytes();
-    unused_memory_usage_bytes_ -= resource->bytes();
-    --resource_count_;
-    delete resource;
-  }
-}
-
-bool ResourcePool::ResourceUsageTooHigh() {
-  if (resource_count_ > max_resource_count_)
-    return true;
-  if (memory_usage_bytes_ > max_memory_usage_bytes_)
-    return true;
-  if (unused_memory_usage_bytes_ > max_unused_memory_usage_bytes_)
-    return true;
-  return false;
-}
-
-void ResourcePool::CheckBusyResources(bool wait_if_needed) {
-  ResourceList::iterator it = busy_resources_.begin();
-
-  while (it != busy_resources_.end()) {
-    ScopedResource* resource = *it;
-
-    if (wait_if_needed)
-      resource_provider_->WaitReadLockIfNeeded(resource->id());
-
-    if (resource_provider_->CanLockForWrite(resource->id())) {
-      DidFinishUsingResource(resource);
-      it = busy_resources_.erase(it);
-    } else {
-      ++it;
-    }
-  }
-}
-
-void ResourcePool::DidFinishUsingResource(ScopedResource* resource) {
-  unused_memory_usage_bytes_ += resource->bytes();
-  unused_resources_.push_back(resource);
-}
-
-}  // namespace cc
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h
deleted file mode 100644
index 30b28f7..0000000
--- a/cc/resources/resource_pool.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_RESOURCES_RESOURCE_POOL_H_
-#define CC_RESOURCES_RESOURCE_POOL_H_
-
-#include <list>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/renderer.h"
-#include "cc/resources/resource.h"
-#include "cc/resources/resource_format.h"
-
-namespace cc {
-class ScopedResource;
-
-class ResourcePool {
- public:
-  static scoped_ptr<ResourcePool> Create(ResourceProvider* resource_provider,
-                                         GLenum target) {
-    return make_scoped_ptr(new ResourcePool(resource_provider, target));
-  }
-
-  virtual ~ResourcePool();
-
-  scoped_ptr<ScopedResource> AcquireResource(const gfx::Size& size,
-                                             ResourceFormat format);
-  void ReleaseResource(scoped_ptr<ScopedResource>);
-
-  void SetResourceUsageLimits(size_t max_memory_usage_bytes,
-                              size_t max_unused_memory_usage_bytes,
-                              size_t max_resource_count);
-
-  void ReduceResourceUsage();
-  // This might block if |wait_if_needed| is true and one of the currently
-  // busy resources has a read lock fence that needs to be waited upon before
-  // it can be locked for write again.
-  void CheckBusyResources(bool wait_if_needed);
-
-  size_t total_memory_usage_bytes() const { return memory_usage_bytes_; }
-  size_t acquired_memory_usage_bytes() const {
-    return memory_usage_bytes_ - unused_memory_usage_bytes_;
-  }
-  size_t total_resource_count() const { return resource_count_; }
-  size_t acquired_resource_count() const {
-    return resource_count_ - unused_resources_.size();
-  }
-  size_t busy_resource_count() const { return busy_resources_.size(); }
-
- protected:
-  ResourcePool(ResourceProvider* resource_provider, GLenum target);
-
-  bool ResourceUsageTooHigh();
-
- private:
-  void DidFinishUsingResource(ScopedResource* resource);
-
-  ResourceProvider* resource_provider_;
-  const GLenum target_;
-  size_t max_memory_usage_bytes_;
-  size_t max_unused_memory_usage_bytes_;
-  size_t max_resource_count_;
-  size_t memory_usage_bytes_;
-  size_t unused_memory_usage_bytes_;
-  size_t resource_count_;
-
-  typedef std::list<ScopedResource*> ResourceList;
-  ResourceList unused_resources_;
-  ResourceList busy_resources_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResourcePool);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RESOURCE_POOL_H_
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
deleted file mode 100644
index b2bb61c..0000000
--- a/cc/resources/resource_provider.cc
+++ /dev/null
@@ -1,2172 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/resource_provider.h"
-
-#include <algorithm>
-#include <limits>
-
-#include "base/containers/hash_tables.h"
-#include "base/metrics/histogram.h"
-#include "base/stl_util.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/util.h"
-#include "cc/output/gl_renderer.h"  // For the GLC() macro.
-#include "cc/resources/platform_color.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/resources/shared_bitmap_manager.h"
-#include "cc/resources/texture_uploader.h"
-#include "cc/resources/transferable_resource.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/core/SkSurface.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "ui/gfx/frame_time.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace cc {
-
-class IdAllocator {
- public:
-  virtual ~IdAllocator() {}
-
-  virtual GLuint NextId() = 0;
-
- protected:
-  IdAllocator(GLES2Interface* gl, size_t id_allocation_chunk_size)
-      : gl_(gl),
-        id_allocation_chunk_size_(id_allocation_chunk_size),
-        ids_(new GLuint[id_allocation_chunk_size]),
-        next_id_index_(id_allocation_chunk_size) {
-    DCHECK(id_allocation_chunk_size_);
-  }
-
-  GLES2Interface* gl_;
-  const size_t id_allocation_chunk_size_;
-  scoped_ptr<GLuint[]> ids_;
-  size_t next_id_index_;
-};
-
-namespace {
-
-// Measured in seconds.
-const double kSoftwareUploadTickRate = 0.000250;
-const double kTextureUploadTickRate = 0.004;
-
-GLenum TextureToStorageFormat(ResourceFormat format) {
-  GLenum storage_format = GL_RGBA8_OES;
-  switch (format) {
-    case RGBA_8888:
-      break;
-    case BGRA_8888:
-      storage_format = GL_BGRA8_EXT;
-      break;
-    case RGBA_4444:
-    case ALPHA_8:
-    case LUMINANCE_8:
-    case RGB_565:
-    case ETC1:
-    case RED_8:
-      NOTREACHED();
-      break;
-  }
-
-  return storage_format;
-}
-
-bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) {
-  switch (format) {
-    case RGBA_8888:
-      return true;
-    case BGRA_8888:
-      return use_bgra;
-    case RGBA_4444:
-    case ALPHA_8:
-    case LUMINANCE_8:
-    case RGB_565:
-    case ETC1:
-    case RED_8:
-      return false;
-  }
-  return false;
-}
-
-GrPixelConfig ToGrPixelConfig(ResourceFormat format) {
-  switch (format) {
-    case RGBA_8888:
-      return kRGBA_8888_GrPixelConfig;
-    case BGRA_8888:
-      return kBGRA_8888_GrPixelConfig;
-    case RGBA_4444:
-      return kRGBA_4444_GrPixelConfig;
-    default:
-      break;
-  }
-  DCHECK(false) << "Unsupported resource format.";
-  return kSkia8888_GrPixelConfig;
-}
-
-gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) {
-  switch (format) {
-    case RGBA_8888:
-      return gfx::GpuMemoryBuffer::Format::RGBA_8888;
-    case BGRA_8888:
-      return gfx::GpuMemoryBuffer::Format::BGRA_8888;
-    case RGBA_4444:
-    case ALPHA_8:
-    case LUMINANCE_8:
-    case RGB_565:
-    case ETC1:
-    case RED_8:
-      break;
-  }
-  NOTREACHED();
-  return gfx::GpuMemoryBuffer::Format::RGBA_8888;
-}
-
-class ScopedSetActiveTexture {
- public:
-  ScopedSetActiveTexture(GLES2Interface* gl, GLenum unit)
-      : gl_(gl), unit_(unit) {
-    DCHECK_EQ(GL_TEXTURE0, ResourceProvider::GetActiveTextureUnit(gl_));
-
-    if (unit_ != GL_TEXTURE0)
-      GLC(gl_, gl_->ActiveTexture(unit_));
-  }
-
-  ~ScopedSetActiveTexture() {
-    // Active unit being GL_TEXTURE0 is effectively the ground state.
-    if (unit_ != GL_TEXTURE0)
-      GLC(gl_, gl_->ActiveTexture(GL_TEXTURE0));
-  }
-
- private:
-  GLES2Interface* gl_;
-  GLenum unit_;
-};
-
-class TextureIdAllocator : public IdAllocator {
- public:
-  TextureIdAllocator(GLES2Interface* gl,
-                     size_t texture_id_allocation_chunk_size)
-      : IdAllocator(gl, texture_id_allocation_chunk_size) {}
-  ~TextureIdAllocator() override {
-    gl_->DeleteTextures(id_allocation_chunk_size_ - next_id_index_,
-                        ids_.get() + next_id_index_);
-  }
-
-  // Overridden from IdAllocator:
-  GLuint NextId() override {
-    if (next_id_index_ == id_allocation_chunk_size_) {
-      gl_->GenTextures(id_allocation_chunk_size_, ids_.get());
-      next_id_index_ = 0;
-    }
-
-    return ids_[next_id_index_++];
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TextureIdAllocator);
-};
-
-class BufferIdAllocator : public IdAllocator {
- public:
-  BufferIdAllocator(GLES2Interface* gl, size_t buffer_id_allocation_chunk_size)
-      : IdAllocator(gl, buffer_id_allocation_chunk_size) {}
-  ~BufferIdAllocator() override {
-    gl_->DeleteBuffers(id_allocation_chunk_size_ - next_id_index_,
-                       ids_.get() + next_id_index_);
-  }
-
-  // Overridden from IdAllocator:
-  GLuint NextId() override {
-    if (next_id_index_ == id_allocation_chunk_size_) {
-      gl_->GenBuffers(id_allocation_chunk_size_, ids_.get());
-      next_id_index_ = 0;
-    }
-
-    return ids_[next_id_index_++];
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BufferIdAllocator);
-};
-
-// Query object based fence implementation used to detect completion of copy
-// texture operations. Fence has passed when query result is available.
-class CopyTextureFence : public ResourceProvider::Fence {
- public:
-  CopyTextureFence(gpu::gles2::GLES2Interface* gl, unsigned query_id)
-      : gl_(gl), query_id_(query_id) {}
-
-  // Overridden from ResourceProvider::Fence:
-  void Set() override {}
-  bool HasPassed() override {
-    unsigned available = 1;
-    gl_->GetQueryObjectuivEXT(
-        query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
-    if (!available)
-      return false;
-
-    ProcessResult();
-    return true;
-  }
-  void Wait() override {
-    // ProcessResult() will wait for result to become available.
-    ProcessResult();
-  }
-
- private:
-  ~CopyTextureFence() override {}
-
-  void ProcessResult() {
-    unsigned time_elapsed_us = 0;
-    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &time_elapsed_us);
-    UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.CopyTextureLatency", time_elapsed_us,
-                                0, 256000, 50);
-  }
-
-  gpu::gles2::GLES2Interface* gl_;
-  unsigned query_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(CopyTextureFence);
-};
-
-}  // namespace
-
-ResourceProvider::Resource::Resource()
-    : child_id(0),
-      gl_id(0),
-      gl_pixel_buffer_id(0),
-      gl_upload_query_id(0),
-      gl_read_lock_query_id(0),
-      pixels(NULL),
-      lock_for_read_count(0),
-      imported_count(0),
-      exported_count(0),
-      dirty_image(false),
-      locked_for_write(false),
-      lost(false),
-      marked_for_deletion(false),
-      pending_set_pixels(false),
-      set_pixels_completion_forced(false),
-      allocated(false),
-      read_lock_fences_enabled(false),
-      has_shared_bitmap_id(false),
-      allow_overlay(false),
-      read_lock_fence(NULL),
-      size(),
-      origin(INTERNAL),
-      target(0),
-      original_filter(0),
-      filter(0),
-      image_id(0),
-      bound_image_id(0),
-      texture_pool(0),
-      wrap_mode(0),
-      hint(TEXTURE_HINT_IMMUTABLE),
-      type(RESOURCE_TYPE_INVALID),
-      format(RGBA_8888),
-      shared_bitmap(NULL),
-      gpu_memory_buffer(NULL) {
-}
-
-ResourceProvider::Resource::~Resource() {}
-
-ResourceProvider::Resource::Resource(GLuint texture_id,
-                                     const gfx::Size& size,
-                                     Origin origin,
-                                     GLenum target,
-                                     GLenum filter,
-                                     GLenum texture_pool,
-                                     GLint wrap_mode,
-                                     TextureHint hint,
-                                     ResourceFormat format)
-    : child_id(0),
-      gl_id(texture_id),
-      gl_pixel_buffer_id(0),
-      gl_upload_query_id(0),
-      gl_read_lock_query_id(0),
-      pixels(NULL),
-      lock_for_read_count(0),
-      imported_count(0),
-      exported_count(0),
-      dirty_image(false),
-      locked_for_write(false),
-      lost(false),
-      marked_for_deletion(false),
-      pending_set_pixels(false),
-      set_pixels_completion_forced(false),
-      allocated(false),
-      read_lock_fences_enabled(false),
-      has_shared_bitmap_id(false),
-      allow_overlay(false),
-      read_lock_fence(NULL),
-      size(size),
-      origin(origin),
-      target(target),
-      original_filter(filter),
-      filter(filter),
-      image_id(0),
-      bound_image_id(0),
-      texture_pool(texture_pool),
-      wrap_mode(wrap_mode),
-      hint(hint),
-      type(RESOURCE_TYPE_GL_TEXTURE),
-      format(format),
-      shared_bitmap(NULL),
-      gpu_memory_buffer(NULL) {
-  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
-  DCHECK_EQ(origin == INTERNAL, !!texture_pool);
-}
-
-ResourceProvider::Resource::Resource(uint8_t* pixels,
-                                     SharedBitmap* bitmap,
-                                     const gfx::Size& size,
-                                     Origin origin,
-                                     GLenum filter,
-                                     GLint wrap_mode)
-    : child_id(0),
-      gl_id(0),
-      gl_pixel_buffer_id(0),
-      gl_upload_query_id(0),
-      gl_read_lock_query_id(0),
-      pixels(pixels),
-      lock_for_read_count(0),
-      imported_count(0),
-      exported_count(0),
-      dirty_image(false),
-      locked_for_write(false),
-      lost(false),
-      marked_for_deletion(false),
-      pending_set_pixels(false),
-      set_pixels_completion_forced(false),
-      allocated(false),
-      read_lock_fences_enabled(false),
-      has_shared_bitmap_id(!!bitmap),
-      allow_overlay(false),
-      read_lock_fence(NULL),
-      size(size),
-      origin(origin),
-      target(0),
-      original_filter(filter),
-      filter(filter),
-      image_id(0),
-      bound_image_id(0),
-      texture_pool(0),
-      wrap_mode(wrap_mode),
-      hint(TEXTURE_HINT_IMMUTABLE),
-      type(RESOURCE_TYPE_BITMAP),
-      format(RGBA_8888),
-      shared_bitmap(bitmap),
-      gpu_memory_buffer(NULL) {
-  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
-  DCHECK(origin == DELEGATED || pixels);
-  if (bitmap)
-    shared_bitmap_id = bitmap->id();
-}
-
-ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id,
-                                     const gfx::Size& size,
-                                     Origin origin,
-                                     GLenum filter,
-                                     GLint wrap_mode)
-    : child_id(0),
-      gl_id(0),
-      gl_pixel_buffer_id(0),
-      gl_upload_query_id(0),
-      gl_read_lock_query_id(0),
-      pixels(NULL),
-      lock_for_read_count(0),
-      imported_count(0),
-      exported_count(0),
-      dirty_image(false),
-      locked_for_write(false),
-      lost(false),
-      marked_for_deletion(false),
-      pending_set_pixels(false),
-      set_pixels_completion_forced(false),
-      allocated(false),
-      read_lock_fences_enabled(false),
-      has_shared_bitmap_id(true),
-      allow_overlay(false),
-      read_lock_fence(NULL),
-      size(size),
-      origin(origin),
-      target(0),
-      original_filter(filter),
-      filter(filter),
-      image_id(0),
-      bound_image_id(0),
-      texture_pool(0),
-      wrap_mode(wrap_mode),
-      hint(TEXTURE_HINT_IMMUTABLE),
-      type(RESOURCE_TYPE_BITMAP),
-      format(RGBA_8888),
-      shared_bitmap_id(bitmap_id),
-      shared_bitmap(NULL),
-      gpu_memory_buffer(NULL) {
-  DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
-}
-
-ResourceProvider::Child::Child() : marked_for_deletion(false) {}
-
-ResourceProvider::Child::~Child() {}
-
-scoped_ptr<ResourceProvider> ResourceProvider::Create(
-    OutputSurface* output_surface,
-    SharedBitmapManager* shared_bitmap_manager,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    BlockingTaskRunner* blocking_main_thread_task_runner,
-    int highp_threshold_min,
-    bool use_rgba_4444_texture_format,
-    size_t id_allocation_chunk_size) {
-  scoped_ptr<ResourceProvider> resource_provider(
-      new ResourceProvider(output_surface,
-                           shared_bitmap_manager,
-                           gpu_memory_buffer_manager,
-                           blocking_main_thread_task_runner,
-                           highp_threshold_min,
-                           use_rgba_4444_texture_format,
-                           id_allocation_chunk_size));
-
-  if (resource_provider->ContextGL())
-    resource_provider->InitializeGL();
-  else
-    resource_provider->InitializeSoftware();
-
-  DCHECK_NE(RESOURCE_TYPE_INVALID, resource_provider->default_resource_type());
-  return resource_provider.Pass();
-}
-
-ResourceProvider::~ResourceProvider() {
-  while (!children_.empty())
-    DestroyChildInternal(children_.begin(), FOR_SHUTDOWN);
-  while (!resources_.empty())
-    DeleteResourceInternal(resources_.begin(), FOR_SHUTDOWN);
-
-  CleanUpGLIfNeeded();
-}
-
-bool ResourceProvider::InUseByConsumer(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return resource->lock_for_read_count > 0 || resource->exported_count > 0 ||
-         resource->lost;
-}
-
-bool ResourceProvider::IsLost(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return resource->lost;
-}
-
-bool ResourceProvider::AllowOverlay(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return resource->allow_overlay;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateResource(
-    const gfx::Size& size,
-    GLint wrap_mode,
-    TextureHint hint,
-    ResourceFormat format) {
-  DCHECK(!size.IsEmpty());
-  switch (default_resource_type_) {
-    case RESOURCE_TYPE_GL_TEXTURE:
-      return CreateGLTexture(size,
-                             GL_TEXTURE_2D,
-                             GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
-                             wrap_mode,
-                             hint,
-                             format);
-    case RESOURCE_TYPE_BITMAP:
-      DCHECK_EQ(RGBA_8888, format);
-      return CreateBitmap(size, wrap_mode);
-    case RESOURCE_TYPE_INVALID:
-      break;
-  }
-
-  LOG(FATAL) << "Invalid default resource type.";
-  return 0;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
-    const gfx::Size& size,
-    GLenum target,
-    GLint wrap_mode,
-    TextureHint hint,
-    ResourceFormat format) {
-  DCHECK(!size.IsEmpty());
-  switch (default_resource_type_) {
-    case RESOURCE_TYPE_GL_TEXTURE:
-      return CreateGLTexture(size,
-                             target,
-                             GL_TEXTURE_POOL_MANAGED_CHROMIUM,
-                             wrap_mode,
-                             hint,
-                             format);
-    case RESOURCE_TYPE_BITMAP:
-      DCHECK_EQ(RGBA_8888, format);
-      return CreateBitmap(size, wrap_mode);
-    case RESOURCE_TYPE_INVALID:
-      break;
-  }
-
-  LOG(FATAL) << "Invalid default resource type.";
-  return 0;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
-    const gfx::Size& size,
-    GLenum target,
-    GLenum texture_pool,
-    GLint wrap_mode,
-    TextureHint hint,
-    ResourceFormat format) {
-  DCHECK_LE(size.width(), max_texture_size_);
-  DCHECK_LE(size.height(), max_texture_size_);
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  ResourceId id = next_id_++;
-  Resource resource(0, size, Resource::INTERNAL, target, GL_LINEAR,
-                    texture_pool, wrap_mode, hint, format);
-  resource.allocated = false;
-  resources_[id] = resource;
-  return id;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateBitmap(
-    const gfx::Size& size, GLint wrap_mode) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  scoped_ptr<SharedBitmap> bitmap =
-      shared_bitmap_manager_->AllocateSharedBitmap(size);
-  uint8_t* pixels = bitmap->pixels();
-  DCHECK(pixels);
-
-  ResourceId id = next_id_++;
-  Resource resource(pixels, bitmap.release(), size, Resource::INTERNAL,
-                    GL_LINEAR, wrap_mode);
-  resource.allocated = true;
-  resources_[id] = resource;
-  return id;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface(
-    const gfx::Size& size,
-    unsigned io_surface_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  ResourceId id = next_id_++;
-  Resource resource(0, gfx::Size(), Resource::INTERNAL,
-                    GL_TEXTURE_RECTANGLE_ARB, GL_LINEAR,
-                    GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, GL_CLAMP_TO_EDGE,
-                    TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-  LazyCreate(&resource);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  gl->BindTexture(GL_TEXTURE_RECTANGLE_ARB, resource.gl_id);
-  gl->TexImageIOSurface2DCHROMIUM(
-      GL_TEXTURE_RECTANGLE_ARB, size.width(), size.height(), io_surface_id, 0);
-  resource.allocated = true;
-  resources_[id] = resource;
-  return id;
-}
-
-ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox(
-    const TextureMailbox& mailbox,
-    scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  // Just store the information. Mailbox will be consumed in LockForRead().
-  ResourceId id = next_id_++;
-  DCHECK(mailbox.IsValid());
-  Resource& resource = resources_[id];
-  if (mailbox.IsTexture()) {
-    resource = Resource(0, gfx::Size(), Resource::EXTERNAL, mailbox.target(),
-                        mailbox.nearest_neighbor() ? GL_NEAREST : GL_LINEAR, 0,
-                        GL_CLAMP_TO_EDGE, TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-  } else {
-    DCHECK(mailbox.IsSharedMemory());
-    SharedBitmap* shared_bitmap = mailbox.shared_bitmap();
-    uint8_t* pixels = shared_bitmap->pixels();
-    DCHECK(pixels);
-    resource = Resource(pixels, shared_bitmap, mailbox.shared_memory_size(),
-                        Resource::EXTERNAL, GL_LINEAR, GL_CLAMP_TO_EDGE);
-  }
-  resource.allocated = true;
-  resource.mailbox = mailbox;
-  resource.release_callback_impl =
-      base::Bind(&SingleReleaseCallbackImpl::Run,
-                 base::Owned(release_callback_impl.release()));
-  resource.allow_overlay = mailbox.allow_overlay();
-  return id;
-}
-
-void ResourceProvider::DeleteResource(ResourceId id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  ResourceMap::iterator it = resources_.find(id);
-  CHECK(it != resources_.end());
-  Resource* resource = &it->second;
-  DCHECK(!resource->marked_for_deletion);
-  DCHECK_EQ(resource->imported_count, 0);
-  DCHECK(resource->pending_set_pixels || !resource->locked_for_write);
-
-  if (resource->exported_count > 0 || resource->lock_for_read_count > 0) {
-    resource->marked_for_deletion = true;
-    return;
-  } else {
-    DeleteResourceInternal(it, NORMAL);
-  }
-}
-
-void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it,
-                                              DeleteStyle style) {
-  TRACE_EVENT0("cc", "ResourceProvider::DeleteResourceInternal");
-  Resource* resource = &it->second;
-  bool lost_resource = resource->lost;
-
-  DCHECK(resource->exported_count == 0 || style != NORMAL);
-  if (style == FOR_SHUTDOWN && resource->exported_count > 0)
-    lost_resource = true;
-
-  if (resource->image_id) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    GLC(gl, gl->DestroyImageCHROMIUM(resource->image_id));
-  }
-  if (resource->gl_upload_query_id) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_upload_query_id));
-  }
-  if (resource->gl_read_lock_query_id) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    GLC(gl, gl->DeleteQueriesEXT(1, &resource->gl_read_lock_query_id));
-  }
-  if (resource->gl_pixel_buffer_id) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    GLC(gl, gl->DeleteBuffers(1, &resource->gl_pixel_buffer_id));
-  }
-  if (resource->origin == Resource::EXTERNAL) {
-    DCHECK(resource->mailbox.IsValid());
-    GLuint sync_point = resource->mailbox.sync_point();
-    if (resource->type == RESOURCE_TYPE_GL_TEXTURE) {
-      DCHECK(resource->mailbox.IsTexture());
-      lost_resource |= lost_output_surface_;
-      GLES2Interface* gl = ContextGL();
-      DCHECK(gl);
-      if (resource->gl_id) {
-        GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
-        resource->gl_id = 0;
-        if (!lost_resource)
-          sync_point = gl->InsertSyncPointCHROMIUM();
-      }
-    } else {
-      DCHECK(resource->mailbox.IsSharedMemory());
-      resource->shared_bitmap = nullptr;
-      resource->pixels = nullptr;
-    }
-    resource->release_callback_impl.Run(
-        sync_point, lost_resource, blocking_main_thread_task_runner_);
-  }
-  if (resource->gl_id) {
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    GLC(gl, gl->DeleteTextures(1, &resource->gl_id));
-    resource->gl_id = 0;
-  }
-  if (resource->shared_bitmap) {
-    DCHECK(resource->origin != Resource::EXTERNAL);
-    DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
-    delete resource->shared_bitmap;
-    resource->pixels = NULL;
-  }
-  if (resource->pixels) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    delete[] resource->pixels;
-    resource->pixels = NULL;
-  }
-  if (resource->gpu_memory_buffer) {
-    DCHECK(resource->origin == Resource::INTERNAL);
-    delete resource->gpu_memory_buffer;
-    resource->gpu_memory_buffer = NULL;
-  }
-  resources_.erase(it);
-}
-
-ResourceProvider::ResourceType ResourceProvider::GetResourceType(
-    ResourceId id) {
-  return GetResource(id)->type;
-}
-
-void ResourceProvider::SetPixels(ResourceId id,
-                                 const uint8_t* image,
-                                 const gfx::Rect& image_rect,
-                                 const gfx::Rect& source_rect,
-                                 const gfx::Vector2d& dest_offset) {
-  Resource* resource = GetResource(id);
-  DCHECK(!resource->locked_for_write);
-  DCHECK(!resource->lock_for_read_count);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(ReadLockFenceHasPassed(resource));
-  LazyAllocate(resource);
-
-  if (resource->type == RESOURCE_TYPE_GL_TEXTURE) {
-    DCHECK(resource->gl_id);
-    DCHECK(!resource->pending_set_pixels);
-    DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    DCHECK(texture_uploader_.get());
-    gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
-    texture_uploader_->Upload(image,
-                              image_rect,
-                              source_rect,
-                              dest_offset,
-                              resource->format,
-                              resource->size);
-  } else {
-    DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
-    DCHECK(resource->allocated);
-    DCHECK_EQ(RGBA_8888, resource->format);
-    DCHECK(source_rect.x() >= image_rect.x());
-    DCHECK(source_rect.y() >= image_rect.y());
-    DCHECK(source_rect.right() <= image_rect.right());
-    DCHECK(source_rect.bottom() <= image_rect.bottom());
-    SkImageInfo source_info =
-        SkImageInfo::MakeN32Premul(source_rect.width(), source_rect.height());
-    size_t image_row_bytes = image_rect.width() * 4;
-    gfx::Vector2d source_offset = source_rect.origin() - image_rect.origin();
-    image += source_offset.y() * image_row_bytes + source_offset.x() * 4;
-
-    ScopedWriteLockSoftware lock(this, id);
-    SkCanvas dest(lock.sk_bitmap());
-    dest.writePixels(source_info, image, image_row_bytes, dest_offset.x(),
-                     dest_offset.y());
-  }
-}
-
-void ResourceProvider::CopyToResource(ResourceId id,
-                                      const uint8_t* image,
-                                      const gfx::Size& image_size) {
-  Resource* resource = GetResource(id);
-  DCHECK(!resource->locked_for_write);
-  DCHECK(!resource->lock_for_read_count);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(ReadLockFenceHasPassed(resource));
-  LazyAllocate(resource);
-
-  DCHECK_EQ(image_size.width(), resource->size.width());
-  DCHECK_EQ(image_size.height(), resource->size.height());
-
-  if (resource->type == RESOURCE_TYPE_BITMAP) {
-    DCHECK_EQ(RESOURCE_TYPE_BITMAP, resource->type);
-    DCHECK(resource->allocated);
-    DCHECK_EQ(RGBA_8888, resource->format);
-    SkImageInfo source_info =
-        SkImageInfo::MakeN32Premul(image_size.width(), image_size.height());
-    size_t image_stride = image_size.width() * 4;
-
-    ScopedWriteLockSoftware lock(this, id);
-    SkCanvas dest(lock.sk_bitmap());
-    dest.writePixels(source_info, image, image_stride, 0, 0);
-  } else {
-    DCHECK(resource->gl_id);
-    DCHECK(!resource->pending_set_pixels);
-    DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    DCHECK(texture_uploader_.get());
-    gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
-
-    if (resource->format == ETC1) {
-      size_t num_bytes = static_cast<size_t>(image_size.width()) *
-                         image_size.height() * BitsPerPixel(ETC1) / 8;
-      gl->CompressedTexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(ETC1),
-                               image_size.width(), image_size.height(), 0,
-                               num_bytes, image);
-    } else {
-      gl->TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_size.width(),
-                        image_size.height(), GLDataFormat(resource->format),
-                        GLDataType(resource->format), image);
-    }
-  }
-}
-
-size_t ResourceProvider::NumBlockingUploads() {
-  if (!texture_uploader_)
-    return 0;
-
-  return texture_uploader_->NumBlockingUploads();
-}
-
-void ResourceProvider::MarkPendingUploadsAsNonBlocking() {
-  if (!texture_uploader_)
-    return;
-
-  texture_uploader_->MarkPendingUploadsAsNonBlocking();
-}
-
-size_t ResourceProvider::EstimatedUploadsPerTick() {
-  if (!texture_uploader_)
-    return 1u;
-
-  double textures_per_second = texture_uploader_->EstimatedTexturesPerSecond();
-  size_t textures_per_tick = floor(
-      kTextureUploadTickRate * textures_per_second);
-  return textures_per_tick ? textures_per_tick : 1u;
-}
-
-void ResourceProvider::FlushUploads() {
-  if (!texture_uploader_)
-    return;
-
-  texture_uploader_->Flush();
-}
-
-void ResourceProvider::ReleaseCachedData() {
-  if (!texture_uploader_)
-    return;
-
-  texture_uploader_->ReleaseCachedQueries();
-}
-
-base::TimeTicks ResourceProvider::EstimatedUploadCompletionTime(
-    size_t uploads_per_tick) {
-  if (lost_output_surface_)
-    return base::TimeTicks();
-
-  // Software resource uploads happen on impl thread, so don't bother batching
-  // them up and trying to wait for them to complete.
-  if (!texture_uploader_) {
-    return gfx::FrameTime::Now() + base::TimeDelta::FromMicroseconds(
-        base::Time::kMicrosecondsPerSecond * kSoftwareUploadTickRate);
-  }
-
-  base::TimeDelta upload_one_texture_time =
-      base::TimeDelta::FromMicroseconds(
-          base::Time::kMicrosecondsPerSecond * kTextureUploadTickRate) /
-      uploads_per_tick;
-
-  size_t total_uploads = NumBlockingUploads() + uploads_per_tick;
-  return gfx::FrameTime::Now() + upload_one_texture_time * total_uploads;
-}
-
-ResourceProvider::Resource* ResourceProvider::GetResource(ResourceId id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  ResourceMap::iterator it = resources_.find(id);
-  CHECK(it != resources_.end());
-  return &it->second;
-}
-
-const ResourceProvider::Resource* ResourceProvider::LockForRead(ResourceId id) {
-  Resource* resource = GetResource(id);
-  DCHECK(!resource->locked_for_write ||
-         resource->set_pixels_completion_forced) <<
-      "locked for write: " << resource->locked_for_write <<
-      " pixels completion forced: " << resource->set_pixels_completion_forced;
-  DCHECK_EQ(resource->exported_count, 0);
-  // Uninitialized! Call SetPixels or LockForWrite first.
-  DCHECK(resource->allocated);
-
-  LazyCreate(resource);
-
-  if (resource->type == RESOURCE_TYPE_GL_TEXTURE && !resource->gl_id) {
-    DCHECK(resource->origin != Resource::INTERNAL);
-    DCHECK(resource->mailbox.IsTexture());
-
-    // Mailbox sync_points must be processed by a call to
-    // WaitSyncPointIfNeeded() prior to calling LockForRead().
-    DCHECK(!resource->mailbox.sync_point());
-
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    resource->gl_id =
-        GLC(gl, gl->CreateAndConsumeTextureCHROMIUM(resource->mailbox.target(),
-                                                    resource->mailbox.name()));
-  }
-
-  if (!resource->pixels && resource->has_shared_bitmap_id &&
-      shared_bitmap_manager_) {
-    scoped_ptr<SharedBitmap> bitmap =
-        shared_bitmap_manager_->GetSharedBitmapFromId(
-            resource->size, resource->shared_bitmap_id);
-    if (bitmap) {
-      resource->shared_bitmap = bitmap.release();
-      resource->pixels = resource->shared_bitmap->pixels();
-    }
-  }
-
-  resource->lock_for_read_count++;
-  if (resource->read_lock_fences_enabled) {
-    if (current_read_lock_fence_.get())
-      current_read_lock_fence_->Set();
-    resource->read_lock_fence = current_read_lock_fence_;
-  }
-
-  return resource;
-}
-
-void ResourceProvider::UnlockForRead(ResourceId id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  ResourceMap::iterator it = resources_.find(id);
-  CHECK(it != resources_.end());
-
-  Resource* resource = &it->second;
-  DCHECK_GT(resource->lock_for_read_count, 0);
-  DCHECK_EQ(resource->exported_count, 0);
-  resource->lock_for_read_count--;
-  if (resource->marked_for_deletion && !resource->lock_for_read_count) {
-    if (!resource->child_id) {
-      // The resource belongs to this ResourceProvider, so it can be destroyed.
-      DeleteResourceInternal(it, NORMAL);
-    } else {
-      ChildMap::iterator child_it = children_.find(resource->child_id);
-      ResourceIdArray unused;
-      unused.push_back(id);
-      DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
-    }
-  }
-}
-
-ResourceProvider::Resource* ResourceProvider::LockForWrite(ResourceId id) {
-  Resource* resource = GetResource(id);
-  DCHECK(CanLockForWrite(id));
-
-  resource->locked_for_write = true;
-  return resource;
-}
-
-bool ResourceProvider::CanLockForWrite(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return !resource->locked_for_write && !resource->lock_for_read_count &&
-         !resource->exported_count && resource->origin == Resource::INTERNAL &&
-         !resource->lost && ReadLockFenceHasPassed(resource);
-}
-
-void ResourceProvider::UnlockForWrite(ResourceProvider::Resource* resource) {
-  DCHECK(resource->locked_for_write);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  resource->locked_for_write = false;
-}
-
-ResourceProvider::ScopedReadLockGL::ScopedReadLockGL(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_id_(resource_id),
-      texture_id_(resource_provider->LockForRead(resource_id)->gl_id) {
-  DCHECK(texture_id_);
-}
-
-ResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() {
-  resource_provider_->UnlockForRead(resource_id_);
-}
-
-ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id,
-    GLenum filter)
-    : ScopedReadLockGL(resource_provider, resource_id),
-      unit_(GL_TEXTURE0),
-      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
-}
-
-ResourceProvider::ScopedSamplerGL::ScopedSamplerGL(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id,
-    GLenum unit,
-    GLenum filter)
-    : ScopedReadLockGL(resource_provider, resource_id),
-      unit_(unit),
-      target_(resource_provider->BindForSampling(resource_id, unit_, filter)) {
-}
-
-ResourceProvider::ScopedSamplerGL::~ScopedSamplerGL() {
-}
-
-ResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_(resource_provider->LockForWrite(resource_id)) {
-  resource_provider_->LazyAllocate(resource_);
-  texture_id_ = resource_->gl_id;
-  DCHECK(texture_id_);
-}
-
-ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
-  resource_provider_->UnlockForWrite(resource_);
-}
-
-void ResourceProvider::PopulateSkBitmapWithResource(
-    SkBitmap* sk_bitmap, const Resource* resource) {
-  DCHECK_EQ(RGBA_8888, resource->format);
-  SkImageInfo info = SkImageInfo::MakeN32Premul(resource->size.width(),
-                                                resource->size.height());
-  sk_bitmap->installPixels(info, resource->pixels, info.minRowBytes());
-}
-
-ResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_id_(resource_id) {
-  const Resource* resource = resource_provider->LockForRead(resource_id);
-  wrap_mode_ = resource->wrap_mode;
-  ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource);
-}
-
-ResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() {
-  resource_provider_->UnlockForRead(resource_id_);
-}
-
-ResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_(resource_provider->LockForWrite(resource_id)) {
-  ResourceProvider::PopulateSkBitmapWithResource(&sk_bitmap_, resource_);
-  DCHECK(valid());
-}
-
-ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  resource_provider_->UnlockForWrite(resource_);
-}
-
-ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
-    ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
-                                   ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_(resource_provider->LockForWrite(resource_id)),
-      gpu_memory_buffer_manager_(resource_provider->gpu_memory_buffer_manager_),
-      gpu_memory_buffer_(nullptr),
-      size_(resource_->size),
-      format_(resource_->format) {
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource_->type);
-  std::swap(gpu_memory_buffer_, resource_->gpu_memory_buffer);
-}
-
-ResourceProvider::ScopedWriteLockGpuMemoryBuffer::
-    ~ScopedWriteLockGpuMemoryBuffer() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  resource_provider_->UnlockForWrite(resource_);
-  if (!gpu_memory_buffer_)
-    return;
-
-  if (!resource_->image_id) {
-    GLES2Interface* gl = resource_provider_->ContextGL();
-    DCHECK(gl);
-
-#if defined(OS_CHROMEOS)
-    // TODO(reveman): GL_COMMANDS_ISSUED_CHROMIUM is used for synchronization
-    // on ChromeOS to avoid some performance issues. This only works with
-    // shared memory backed buffers. crbug.com/436314
-    DCHECK_EQ(gpu_memory_buffer_->GetHandle().type, gfx::SHARED_MEMORY_BUFFER);
-#endif
-
-    resource_->image_id =
-        gl->CreateImageCHROMIUM(gpu_memory_buffer_->AsClientBuffer(),
-                                size_.width(),
-                                size_.height(),
-                                GL_RGBA);
-  }
-
-  std::swap(resource_->gpu_memory_buffer, gpu_memory_buffer_);
-  resource_->allocated = true;
-  resource_->dirty_image = true;
-
-  // GpuMemoryBuffer provides direct access to the memory used by the GPU.
-  // Read lock fences are required to ensure that we're not trying to map a
-  // buffer that is currently in-use by the GPU.
-  resource_->read_lock_fences_enabled = true;
-}
-
-gfx::GpuMemoryBuffer*
-ResourceProvider::ScopedWriteLockGpuMemoryBuffer::GetGpuMemoryBuffer() {
-  if (!gpu_memory_buffer_) {
-    scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
-        gpu_memory_buffer_manager_->AllocateGpuMemoryBuffer(
-            size_, ToGpuMemoryBufferFormat(format_), gfx::GpuMemoryBuffer::MAP);
-    gpu_memory_buffer_ = gpu_memory_buffer.release();
-  }
-
-  return gpu_memory_buffer_;
-}
-
-ResourceProvider::ScopedWriteLockGr::ScopedWriteLockGr(
-    ResourceProvider* resource_provider,
-    ResourceProvider::ResourceId resource_id)
-    : resource_provider_(resource_provider),
-      resource_(resource_provider->LockForWrite(resource_id)) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  resource_provider_->LazyAllocate(resource_);
-}
-
-ResourceProvider::ScopedWriteLockGr::~ScopedWriteLockGr() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(resource_->locked_for_write);
-  resource_provider_->UnlockForWrite(resource_);
-}
-
-void ResourceProvider::ScopedWriteLockGr::InitSkSurface(
-    bool use_worker_context,
-    bool use_distance_field_text,
-    bool can_use_lcd_text,
-    int msaa_sample_count) {
-  DCHECK(resource_->locked_for_write);
-
-  GrBackendTextureDesc desc;
-  desc.fFlags = kRenderTarget_GrBackendTextureFlag;
-  desc.fWidth = resource_->size.width();
-  desc.fHeight = resource_->size.height();
-  desc.fConfig = ToGrPixelConfig(resource_->format);
-  desc.fOrigin = kTopLeft_GrSurfaceOrigin;
-  desc.fTextureHandle = resource_->gl_id;
-  desc.fSampleCnt = msaa_sample_count;
-
-  class GrContext* gr_context =
-      resource_provider_->GrContext(use_worker_context);
-  skia::RefPtr<GrTexture> gr_texture =
-      skia::AdoptRef(gr_context->textureProvider()->wrapBackendTexture(desc));
-  if (gr_texture) {
-    uint32_t flags = use_distance_field_text
-                         ? SkSurfaceProps::kUseDistanceFieldFonts_Flag
-                         : 0;
-    // Use unknown pixel geometry to disable LCD text.
-    SkSurfaceProps surface_props(flags, kUnknown_SkPixelGeometry);
-    if (can_use_lcd_text) {
-      // LegacyFontHost will get LCD text and skia figures out what type to use.
-      surface_props =
-          SkSurfaceProps(flags, SkSurfaceProps::kLegacyFontHost_InitType);
-    }
-    sk_surface_ = skia::AdoptRef(SkSurface::NewRenderTargetDirect(
-        gr_texture->asRenderTarget(), &surface_props));
-    return;
-  }
-  sk_surface_.clear();
-}
-
-void ResourceProvider::ScopedWriteLockGr::ReleaseSkSurface() {
-  sk_surface_.clear();
-}
-
-ResourceProvider::SynchronousFence::SynchronousFence(
-    gpu::gles2::GLES2Interface* gl)
-    : gl_(gl), has_synchronized_(true) {
-}
-
-ResourceProvider::SynchronousFence::~SynchronousFence() {
-}
-
-void ResourceProvider::SynchronousFence::Set() {
-  has_synchronized_ = false;
-}
-
-bool ResourceProvider::SynchronousFence::HasPassed() {
-  if (!has_synchronized_) {
-    has_synchronized_ = true;
-    Synchronize();
-  }
-  return true;
-}
-
-void ResourceProvider::SynchronousFence::Wait() {
-  HasPassed();
-}
-
-void ResourceProvider::SynchronousFence::Synchronize() {
-  TRACE_EVENT0("cc", "ResourceProvider::SynchronousFence::Synchronize");
-  gl_->Finish();
-}
-
-ResourceProvider::ResourceProvider(
-    OutputSurface* output_surface,
-    SharedBitmapManager* shared_bitmap_manager,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    BlockingTaskRunner* blocking_main_thread_task_runner,
-    int highp_threshold_min,
-    bool use_rgba_4444_texture_format,
-    size_t id_allocation_chunk_size)
-    : output_surface_(output_surface),
-      shared_bitmap_manager_(shared_bitmap_manager),
-      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
-      blocking_main_thread_task_runner_(blocking_main_thread_task_runner),
-      lost_output_surface_(false),
-      highp_threshold_min_(highp_threshold_min),
-      next_id_(1),
-      next_child_(1),
-      default_resource_type_(RESOURCE_TYPE_INVALID),
-      use_texture_storage_ext_(false),
-      use_texture_format_bgra_(false),
-      use_texture_usage_hint_(false),
-      use_compressed_texture_etc1_(false),
-      yuv_resource_format_(LUMINANCE_8),
-      max_texture_size_(0),
-      best_texture_format_(RGBA_8888),
-      use_rgba_4444_texture_format_(use_rgba_4444_texture_format),
-      id_allocation_chunk_size_(id_allocation_chunk_size),
-      use_sync_query_(false) {
-  DCHECK(output_surface_->HasClient());
-  DCHECK(id_allocation_chunk_size_);
-}
-
-void ResourceProvider::InitializeSoftware() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK_NE(RESOURCE_TYPE_BITMAP, default_resource_type_);
-
-  CleanUpGLIfNeeded();
-
-  default_resource_type_ = RESOURCE_TYPE_BITMAP;
-  // Pick an arbitrary limit here similar to what hardware might.
-  max_texture_size_ = 16 * 1024;
-  best_texture_format_ = RGBA_8888;
-}
-
-void ResourceProvider::InitializeGL() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(!texture_uploader_);
-  DCHECK_NE(RESOURCE_TYPE_GL_TEXTURE, default_resource_type_);
-  DCHECK(!texture_id_allocator_);
-  DCHECK(!buffer_id_allocator_);
-
-  default_resource_type_ = RESOURCE_TYPE_GL_TEXTURE;
-
-  const ContextProvider::Capabilities& caps =
-      output_surface_->context_provider()->ContextCapabilities();
-
-  bool use_bgra = caps.gpu.texture_format_bgra8888;
-  use_texture_storage_ext_ = caps.gpu.texture_storage;
-  use_texture_format_bgra_ = caps.gpu.texture_format_bgra8888;
-  use_texture_usage_hint_ = caps.gpu.texture_usage;
-  use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1;
-  yuv_resource_format_ = caps.gpu.texture_rg ? RED_8 : LUMINANCE_8;
-  use_sync_query_ = caps.gpu.sync_query;
-
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-
-  texture_uploader_ = TextureUploader::Create(gl);
-  max_texture_size_ = 0;  // Context expects cleared value.
-  GLC(gl, gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size_));
-  best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra);
-
-  texture_id_allocator_.reset(
-      new TextureIdAllocator(gl, id_allocation_chunk_size_));
-  buffer_id_allocator_.reset(
-      new BufferIdAllocator(gl, id_allocation_chunk_size_));
-}
-
-void ResourceProvider::CleanUpGLIfNeeded() {
-  GLES2Interface* gl = ContextGL();
-  if (default_resource_type_ != RESOURCE_TYPE_GL_TEXTURE) {
-    // We are not in GL mode, but double check before returning.
-    DCHECK(!gl);
-    DCHECK(!texture_uploader_);
-    return;
-  }
-
-  DCHECK(gl);
-#if DCHECK_IS_ON()
-  // Check that all GL resources has been deleted.
-  for (ResourceMap::const_iterator itr = resources_.begin();
-       itr != resources_.end();
-       ++itr) {
-    DCHECK_NE(RESOURCE_TYPE_GL_TEXTURE, itr->second.type);
-  }
-#endif  // DCHECK_IS_ON()
-
-  texture_uploader_ = nullptr;
-  texture_id_allocator_ = nullptr;
-  buffer_id_allocator_ = nullptr;
-  gl->Finish();
-}
-
-int ResourceProvider::CreateChild(const ReturnCallback& return_callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  Child child_info;
-  child_info.return_callback = return_callback;
-
-  int child = next_child_++;
-  children_[child] = child_info;
-  return child;
-}
-
-void ResourceProvider::DestroyChild(int child_id) {
-  ChildMap::iterator it = children_.find(child_id);
-  DCHECK(it != children_.end());
-  DestroyChildInternal(it, NORMAL);
-}
-
-void ResourceProvider::DestroyChildInternal(ChildMap::iterator it,
-                                            DeleteStyle style) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  Child& child = it->second;
-  DCHECK(style == FOR_SHUTDOWN || !child.marked_for_deletion);
-
-  ResourceIdArray resources_for_child;
-
-  for (ResourceIdMap::iterator child_it = child.child_to_parent_map.begin();
-       child_it != child.child_to_parent_map.end();
-       ++child_it) {
-    ResourceId id = child_it->second;
-    resources_for_child.push_back(id);
-  }
-
-  // If the child is going away, don't consider any resources in use.
-  child.in_use_resources.clear();
-  child.marked_for_deletion = true;
-
-  DeleteAndReturnUnusedResourcesToChild(it, style, resources_for_child);
-}
-
-const ResourceProvider::ResourceIdMap& ResourceProvider::GetChildToParentMap(
-    int child) const {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  ChildMap::const_iterator it = children_.find(child);
-  DCHECK(it != children_.end());
-  DCHECK(!it->second.marked_for_deletion);
-  return it->second.child_to_parent_map;
-}
-
-void ResourceProvider::PrepareSendToParent(const ResourceIdArray& resources,
-                                           TransferableResourceArray* list) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  GLES2Interface* gl = ContextGL();
-  bool need_sync_point = false;
-  for (ResourceIdArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    TransferableResource resource;
-    TransferResource(gl, *it, &resource);
-    if (!resource.mailbox_holder.sync_point && !resource.is_software)
-      need_sync_point = true;
-    ++resources_.find(*it)->second.exported_count;
-    list->push_back(resource);
-  }
-  if (need_sync_point) {
-    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
-    for (TransferableResourceArray::iterator it = list->begin();
-         it != list->end();
-         ++it) {
-      if (!it->mailbox_holder.sync_point)
-        it->mailbox_holder.sync_point = sync_point;
-    }
-  }
-}
-
-void ResourceProvider::ReceiveFromChild(
-    int child, const TransferableResourceArray& resources) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  GLES2Interface* gl = ContextGL();
-  Child& child_info = children_.find(child)->second;
-  DCHECK(!child_info.marked_for_deletion);
-  for (TransferableResourceArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    ResourceIdMap::iterator resource_in_map_it =
-        child_info.child_to_parent_map.find(it->id);
-    if (resource_in_map_it != child_info.child_to_parent_map.end()) {
-      Resource& resource = resources_[resource_in_map_it->second];
-      resource.marked_for_deletion = false;
-      resource.imported_count++;
-      continue;
-    }
-
-    if ((!it->is_software && !gl) ||
-        (it->is_software && !shared_bitmap_manager_)) {
-      TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid");
-      ReturnedResourceArray to_return;
-      to_return.push_back(it->ToReturnedResource());
-      child_info.return_callback.Run(to_return,
-                                     blocking_main_thread_task_runner_);
-      continue;
-    }
-
-    ResourceId local_id = next_id_++;
-    Resource& resource = resources_[local_id];
-    if (it->is_software) {
-      resource =
-          Resource(it->mailbox_holder.mailbox, it->size, Resource::DELEGATED,
-                   GL_LINEAR, it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE);
-    } else {
-      resource = Resource(0, it->size, Resource::DELEGATED,
-                          it->mailbox_holder.texture_target, it->filter, 0,
-                          it->is_repeated ? GL_REPEAT : GL_CLAMP_TO_EDGE,
-                          TEXTURE_HINT_IMMUTABLE, it->format);
-      resource.mailbox = TextureMailbox(it->mailbox_holder.mailbox,
-                                        it->mailbox_holder.texture_target,
-                                        it->mailbox_holder.sync_point);
-    }
-    resource.child_id = child;
-    // Don't allocate a texture for a child.
-    resource.allocated = true;
-    resource.imported_count = 1;
-    resource.allow_overlay = it->allow_overlay;
-    child_info.parent_to_child_map[local_id] = it->id;
-    child_info.child_to_parent_map[it->id] = local_id;
-  }
-}
-
-void ResourceProvider::DeclareUsedResourcesFromChild(
-    int child,
-    const ResourceIdArray& resources_from_child) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  ChildMap::iterator child_it = children_.find(child);
-  DCHECK(child_it != children_.end());
-  Child& child_info = child_it->second;
-  DCHECK(!child_info.marked_for_deletion);
-  child_info.in_use_resources.clear();
-
-  for (size_t i = 0; i < resources_from_child.size(); ++i) {
-    ResourceIdMap::iterator it =
-        child_info.child_to_parent_map.find(resources_from_child[i]);
-    DCHECK(it != child_info.child_to_parent_map.end());
-
-    ResourceId local_id = it->second;
-    DCHECK(!resources_[local_id].marked_for_deletion);
-    child_info.in_use_resources.insert(local_id);
-  }
-
-  ResourceIdArray unused;
-  for (ResourceIdMap::iterator it = child_info.child_to_parent_map.begin();
-       it != child_info.child_to_parent_map.end();
-       ++it) {
-    ResourceId local_id = it->second;
-    bool resource_is_in_use = child_info.in_use_resources.count(local_id) > 0;
-    if (!resource_is_in_use)
-      unused.push_back(local_id);
-  }
-  DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused);
-}
-
-// static
-bool ResourceProvider::CompareResourceMapIteratorsByChildId(
-    const std::pair<ReturnedResource, ResourceMap::iterator>& a,
-    const std::pair<ReturnedResource, ResourceMap::iterator>& b) {
-  const ResourceMap::iterator& a_it = a.second;
-  const ResourceMap::iterator& b_it = b.second;
-  const Resource& a_resource = a_it->second;
-  const Resource& b_resource = b_it->second;
-  return a_resource.child_id < b_resource.child_id;
-}
-
-void ResourceProvider::ReceiveReturnsFromParent(
-    const ReturnedResourceArray& resources) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  GLES2Interface* gl = ContextGL();
-
-  int child_id = 0;
-  ResourceIdArray resources_for_child;
-
-  std::vector<std::pair<ReturnedResource, ResourceMap::iterator>>
-      sorted_resources;
-
-  for (ReturnedResourceArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    ResourceId local_id = it->id;
-    ResourceMap::iterator map_iterator = resources_.find(local_id);
-
-    // Resource was already lost (e.g. it belonged to a child that was
-    // destroyed).
-    if (map_iterator == resources_.end())
-      continue;
-
-    sorted_resources.push_back(
-        std::pair<ReturnedResource, ResourceMap::iterator>(*it, map_iterator));
-  }
-
-  std::sort(sorted_resources.begin(),
-            sorted_resources.end(),
-            CompareResourceMapIteratorsByChildId);
-
-  ChildMap::iterator child_it = children_.end();
-  for (size_t i = 0; i < sorted_resources.size(); ++i) {
-    ReturnedResource& returned = sorted_resources[i].first;
-    ResourceMap::iterator& map_iterator = sorted_resources[i].second;
-    ResourceId local_id = map_iterator->first;
-    Resource* resource = &map_iterator->second;
-
-    CHECK_GE(resource->exported_count, returned.count);
-    resource->exported_count -= returned.count;
-    resource->lost |= returned.lost;
-    if (resource->exported_count)
-      continue;
-
-    // Need to wait for the current read lock fence to pass before we can
-    // recycle this resource.
-    if (resource->read_lock_fences_enabled) {
-      if (current_read_lock_fence_.get())
-        current_read_lock_fence_->Set();
-      resource->read_lock_fence = current_read_lock_fence_;
-    }
-
-    if (returned.sync_point) {
-      DCHECK(!resource->has_shared_bitmap_id);
-      if (resource->origin == Resource::INTERNAL) {
-        DCHECK(resource->gl_id);
-        GLC(gl, gl->WaitSyncPointCHROMIUM(returned.sync_point));
-      } else {
-        DCHECK(!resource->gl_id);
-        resource->mailbox.set_sync_point(returned.sync_point);
-      }
-    }
-
-    if (!resource->marked_for_deletion)
-      continue;
-
-    if (!resource->child_id) {
-      // The resource belongs to this ResourceProvider, so it can be destroyed.
-      DeleteResourceInternal(map_iterator, NORMAL);
-      continue;
-    }
-
-    DCHECK(resource->origin == Resource::DELEGATED);
-    // Delete the resource and return it to the child it came from one.
-    if (resource->child_id != child_id) {
-      if (child_id) {
-        DCHECK_NE(resources_for_child.size(), 0u);
-        DCHECK(child_it != children_.end());
-        DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL,
-                                              resources_for_child);
-        resources_for_child.clear();
-      }
-
-      child_it = children_.find(resource->child_id);
-      DCHECK(child_it != children_.end());
-      child_id = resource->child_id;
-    }
-    resources_for_child.push_back(local_id);
-  }
-
-  if (child_id) {
-    DCHECK_NE(resources_for_child.size(), 0u);
-    DCHECK(child_it != children_.end());
-    DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL,
-                                          resources_for_child);
-  }
-}
-
-void ResourceProvider::TransferResource(GLES2Interface* gl,
-                                        ResourceId id,
-                                        TransferableResource* resource) {
-  Resource* source = GetResource(id);
-  DCHECK(!source->locked_for_write);
-  DCHECK(!source->lock_for_read_count);
-  DCHECK(source->origin != Resource::EXTERNAL || source->mailbox.IsValid());
-  DCHECK(source->allocated);
-  resource->id = id;
-  resource->format = source->format;
-  resource->mailbox_holder.texture_target = source->target;
-  resource->filter = source->filter;
-  resource->size = source->size;
-  resource->is_repeated = (source->wrap_mode == GL_REPEAT);
-  resource->allow_overlay = source->allow_overlay;
-
-  if (source->type == RESOURCE_TYPE_BITMAP) {
-    resource->mailbox_holder.mailbox = source->shared_bitmap_id;
-    resource->is_software = true;
-  } else if (!source->mailbox.IsValid()) {
-    LazyCreate(source);
-    DCHECK(source->gl_id);
-    DCHECK(source->origin == Resource::INTERNAL);
-    if (source->image_id) {
-      DCHECK(source->dirty_image);
-      BindImageForSampling(source);
-    }
-    // This is a resource allocated by the compositor, we need to produce it.
-    // Don't set a sync point, the caller will do it.
-    GLC(gl, gl->GenMailboxCHROMIUM(resource->mailbox_holder.mailbox.name));
-    GLC(gl, gl->ProduceTextureDirectCHROMIUM(
-                source->gl_id, resource->mailbox_holder.texture_target,
-                resource->mailbox_holder.mailbox.name));
-
-    source->mailbox = TextureMailbox(resource->mailbox_holder);
-  } else {
-    DCHECK(source->mailbox.IsTexture());
-    if (source->image_id && source->dirty_image) {
-      DCHECK(source->gl_id);
-      DCHECK(source->origin == Resource::INTERNAL);
-      GLC(gl,
-          gl->BindTexture(resource->mailbox_holder.texture_target,
-                          source->gl_id));
-      BindImageForSampling(source);
-    }
-    // This is either an external resource, or a compositor resource that we
-    // already exported. Make sure to forward the sync point that we were given.
-    resource->mailbox_holder.mailbox = source->mailbox.mailbox();
-    resource->mailbox_holder.texture_target = source->mailbox.target();
-    resource->mailbox_holder.sync_point = source->mailbox.sync_point();
-    source->mailbox.set_sync_point(0);
-  }
-}
-
-void ResourceProvider::DeleteAndReturnUnusedResourcesToChild(
-    ChildMap::iterator child_it,
-    DeleteStyle style,
-    const ResourceIdArray& unused) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(child_it != children_.end());
-  Child* child_info = &child_it->second;
-
-  if (unused.empty() && !child_info->marked_for_deletion)
-    return;
-
-  ReturnedResourceArray to_return;
-
-  GLES2Interface* gl = ContextGL();
-  bool need_sync_point = false;
-  for (size_t i = 0; i < unused.size(); ++i) {
-    ResourceId local_id = unused[i];
-
-    ResourceMap::iterator it = resources_.find(local_id);
-    CHECK(it != resources_.end());
-    Resource& resource = it->second;
-
-    DCHECK(!resource.locked_for_write);
-    DCHECK_EQ(0u, child_info->in_use_resources.count(local_id));
-    DCHECK(child_info->parent_to_child_map.count(local_id));
-
-    ResourceId child_id = child_info->parent_to_child_map[local_id];
-    DCHECK(child_info->child_to_parent_map.count(child_id));
-
-    bool is_lost =
-        resource.lost ||
-        (resource.type == RESOURCE_TYPE_GL_TEXTURE && lost_output_surface_);
-    if (resource.exported_count > 0 || resource.lock_for_read_count > 0) {
-      if (style != FOR_SHUTDOWN) {
-        // Defer this until we receive the resource back from the parent or
-        // the read lock is released.
-        resource.marked_for_deletion = true;
-        continue;
-      }
-
-      // We still have an exported_count, so we'll have to lose it.
-      is_lost = true;
-    }
-
-    if (gl && resource.filter != resource.original_filter) {
-      DCHECK(resource.target);
-      DCHECK(resource.gl_id);
-
-      GLC(gl, gl->BindTexture(resource.target, resource.gl_id));
-      GLC(gl,
-          gl->TexParameteri(resource.target,
-                            GL_TEXTURE_MIN_FILTER,
-                            resource.original_filter));
-      GLC(gl,
-          gl->TexParameteri(resource.target,
-                            GL_TEXTURE_MAG_FILTER,
-                            resource.original_filter));
-    }
-
-    ReturnedResource returned;
-    returned.id = child_id;
-    returned.sync_point = resource.mailbox.sync_point();
-    if (!returned.sync_point && resource.type == RESOURCE_TYPE_GL_TEXTURE)
-      need_sync_point = true;
-    returned.count = resource.imported_count;
-    returned.lost = is_lost;
-    to_return.push_back(returned);
-
-    child_info->parent_to_child_map.erase(local_id);
-    child_info->child_to_parent_map.erase(child_id);
-    resource.imported_count = 0;
-    DeleteResourceInternal(it, style);
-  }
-  if (need_sync_point) {
-    DCHECK(gl);
-    GLuint sync_point = gl->InsertSyncPointCHROMIUM();
-    for (size_t i = 0; i < to_return.size(); ++i) {
-      if (!to_return[i].sync_point)
-        to_return[i].sync_point = sync_point;
-    }
-  }
-
-  if (!to_return.empty())
-    child_info->return_callback.Run(to_return,
-                                    blocking_main_thread_task_runner_);
-
-  if (child_info->marked_for_deletion &&
-      child_info->parent_to_child_map.empty()) {
-    DCHECK(child_info->child_to_parent_map.empty());
-    children_.erase(child_it);
-  }
-}
-
-void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::AcquirePixelBuffer");
-
-  Resource* resource = GetResource(id);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(!resource->image_id);
-  DCHECK_NE(ETC1, resource->format);
-
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  if (!resource->gl_pixel_buffer_id)
-    resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId();
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->gl_pixel_buffer_id);
-  unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8;
-  gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->size.height() *
-                     RoundUp(bytes_per_pixel * resource->size.width(), 4u),
-                 NULL,
-                 GL_DYNAMIC_DRAW);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
-}
-
-void ResourceProvider::ReleasePixelBuffer(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::ReleasePixelBuffer");
-
-  Resource* resource = GetResource(id);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(!resource->image_id);
-
-  // The pixel buffer can be released while there is a pending "set pixels"
-  // if completion has been forced. Any shared memory associated with this
-  // pixel buffer will not be freed until the waitAsyncTexImage2DCHROMIUM
-  // command has been processed on the service side. It is also safe to
-  // reuse any query id associated with this resource before they complete
-  // as each new query has a unique submit count.
-  if (resource->pending_set_pixels) {
-    DCHECK(resource->set_pixels_completion_forced);
-    resource->pending_set_pixels = false;
-    resource->locked_for_write = false;
-  }
-
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
-  if (!resource->gl_pixel_buffer_id)
-    return;
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->gl_pixel_buffer_id);
-  gl->BufferData(
-      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0, NULL, GL_DYNAMIC_DRAW);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
-}
-
-uint8_t* ResourceProvider::MapPixelBuffer(ResourceId id, int* stride) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::MapPixelBuffer");
-
-  Resource* resource = GetResource(id);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(!resource->image_id);
-
-  *stride = 0;
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  DCHECK(resource->gl_pixel_buffer_id);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->gl_pixel_buffer_id);
-  uint8_t* image = static_cast<uint8_t*>(gl->MapBufferCHROMIUM(
-      GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, GL_WRITE_ONLY));
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
-  // Buffer is required to be 4-byte aligned.
-  CHECK(!(reinterpret_cast<intptr_t>(image) & 3));
-  return image;
-}
-
-void ResourceProvider::UnmapPixelBuffer(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::UnmapPixelBuffer");
-
-  Resource* resource = GetResource(id);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(!resource->image_id);
-
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  DCHECK(resource->gl_pixel_buffer_id);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->gl_pixel_buffer_id);
-  gl->UnmapBufferCHROMIUM(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
-}
-
-GLenum ResourceProvider::BindForSampling(ResourceId resource_id,
-                                         GLenum unit,
-                                         GLenum filter) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  GLES2Interface* gl = ContextGL();
-  ResourceMap::iterator it = resources_.find(resource_id);
-  DCHECK(it != resources_.end());
-  Resource* resource = &it->second;
-  DCHECK(resource->lock_for_read_count);
-  DCHECK(!resource->locked_for_write || resource->set_pixels_completion_forced);
-
-  ScopedSetActiveTexture scoped_active_tex(gl, unit);
-  GLenum target = resource->target;
-  GLC(gl, gl->BindTexture(target, resource->gl_id));
-  if (filter != resource->filter) {
-    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, filter));
-    GLC(gl, gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, filter));
-    resource->filter = filter;
-  }
-
-  if (resource->image_id && resource->dirty_image)
-    BindImageForSampling(resource);
-
-  return target;
-}
-
-void ResourceProvider::BeginSetPixels(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::BeginSetPixels");
-
-  Resource* resource = GetResource(id);
-  DCHECK(!resource->pending_set_pixels);
-
-  LazyCreate(resource);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK(resource->gl_id || resource->allocated);
-  DCHECK(ReadLockFenceHasPassed(resource));
-  DCHECK(!resource->image_id);
-
-  bool allocate = !resource->allocated;
-  resource->allocated = true;
-  LockForWrite(id);
-
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, resource->type);
-  DCHECK(resource->gl_id);
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  DCHECK(resource->gl_pixel_buffer_id);
-  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
-  gl->BindTexture(GL_TEXTURE_2D, resource->gl_id);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
-                 resource->gl_pixel_buffer_id);
-  if (!resource->gl_upload_query_id)
-    gl->GenQueriesEXT(1, &resource->gl_upload_query_id);
-  gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
-                    resource->gl_upload_query_id);
-  if (allocate) {
-    gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
-                                0, /* level */
-                                GLInternalFormat(resource->format),
-                                resource->size.width(),
-                                resource->size.height(),
-                                0, /* border */
-                                GLDataFormat(resource->format),
-                                GLDataType(resource->format),
-                                NULL);
-  } else {
-    gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
-                                   0, /* level */
-                                   0, /* x */
-                                   0, /* y */
-                                   resource->size.width(),
-                                   resource->size.height(),
-                                   GLDataFormat(resource->format),
-                                   GLDataType(resource->format),
-                                   NULL);
-  }
-  gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
-  gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
-
-  resource->pending_set_pixels = true;
-  resource->set_pixels_completion_forced = false;
-}
-
-void ResourceProvider::ForceSetPixelsToComplete(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::ForceSetPixelsToComplete");
-
-  Resource* resource = GetResource(id);
-
-  DCHECK(resource->locked_for_write);
-  DCHECK(resource->pending_set_pixels);
-  DCHECK(!resource->set_pixels_completion_forced);
-
-  if (resource->gl_id) {
-    GLES2Interface* gl = ContextGL();
-    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
-    GLC(gl, gl->WaitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D));
-    GLC(gl, gl->BindTexture(GL_TEXTURE_2D, 0));
-  }
-
-  resource->set_pixels_completion_forced = true;
-}
-
-bool ResourceProvider::DidSetPixelsComplete(ResourceId id) {
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "ResourceProvider::DidSetPixelsComplete");
-
-  Resource* resource = GetResource(id);
-
-  DCHECK(resource->locked_for_write);
-  DCHECK(resource->pending_set_pixels);
-
-  if (resource->gl_id) {
-    GLES2Interface* gl = ContextGL();
-    DCHECK(gl);
-    DCHECK(resource->gl_upload_query_id);
-    GLuint complete = 1;
-    gl->GetQueryObjectuivEXT(
-        resource->gl_upload_query_id, GL_QUERY_RESULT_AVAILABLE_EXT, &complete);
-    if (!complete)
-      return false;
-  }
-
-  resource->pending_set_pixels = false;
-  UnlockForWrite(resource);
-
-  // Async set pixels commands are not necessarily processed in-sequence with
-  // drawing commands. Read lock fences are required to ensure that async
-  // commands don't access the resource while used for drawing.
-  resource->read_lock_fences_enabled = true;
-
-  return true;
-}
-
-void ResourceProvider::CreateForTesting(ResourceId id) {
-  LazyCreate(GetResource(id));
-}
-
-GLenum ResourceProvider::TargetForTesting(ResourceId id) {
-  Resource* resource = GetResource(id);
-  return resource->target;
-}
-
-void ResourceProvider::LazyCreate(Resource* resource) {
-  if (resource->type != RESOURCE_TYPE_GL_TEXTURE ||
-      resource->origin != Resource::INTERNAL)
-    return;
-
-  if (resource->gl_id)
-    return;
-
-  DCHECK(resource->texture_pool);
-  DCHECK(resource->origin == Resource::INTERNAL);
-  DCHECK(!resource->mailbox.IsValid());
-  resource->gl_id = texture_id_allocator_->NextId();
-
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-
-  // Create and set texture properties. Allocation is delayed until needed.
-  GLC(gl, gl->BindTexture(resource->target, resource->gl_id));
-  GLC(gl,
-      gl->TexParameteri(
-          resource->target, GL_TEXTURE_MIN_FILTER, resource->original_filter));
-  GLC(gl,
-      gl->TexParameteri(
-          resource->target, GL_TEXTURE_MAG_FILTER, resource->original_filter));
-  GLC(gl,
-      gl->TexParameteri(
-          resource->target, GL_TEXTURE_WRAP_S, resource->wrap_mode));
-  GLC(gl,
-      gl->TexParameteri(
-          resource->target, GL_TEXTURE_WRAP_T, resource->wrap_mode));
-  GLC(gl,
-      gl->TexParameteri(
-          resource->target, GL_TEXTURE_POOL_CHROMIUM, resource->texture_pool));
-  if (use_texture_usage_hint_ && (resource->hint & TEXTURE_HINT_FRAMEBUFFER)) {
-    GLC(gl,
-        gl->TexParameteri(resource->target,
-                          GL_TEXTURE_USAGE_ANGLE,
-                          GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
-  }
-}
-
-void ResourceProvider::AllocateForTesting(ResourceId id) {
-  LazyAllocate(GetResource(id));
-}
-
-void ResourceProvider::LazyAllocate(Resource* resource) {
-  DCHECK(resource);
-  if (resource->allocated)
-    return;
-  LazyCreate(resource);
-  if (!resource->gl_id)
-    return;
-  resource->allocated = true;
-  GLES2Interface* gl = ContextGL();
-  gfx::Size& size = resource->size;
-  DCHECK_EQ(resource->target, static_cast<GLenum>(GL_TEXTURE_2D));
-  ResourceFormat format = resource->format;
-  GLC(gl, gl->BindTexture(GL_TEXTURE_2D, resource->gl_id));
-  if (use_texture_storage_ext_ &&
-      IsFormatSupportedForStorage(format, use_texture_format_bgra_) &&
-      (resource->hint & TEXTURE_HINT_IMMUTABLE)) {
-    GLenum storage_format = TextureToStorageFormat(format);
-    GLC(gl,
-        gl->TexStorage2DEXT(
-            GL_TEXTURE_2D, 1, storage_format, size.width(), size.height()));
-  } else {
-    // ETC1 does not support preallocation.
-    if (format != ETC1) {
-      GLC(gl,
-          gl->TexImage2D(GL_TEXTURE_2D,
-                         0,
-                         GLInternalFormat(format),
-                         size.width(),
-                         size.height(),
-                         0,
-                         GLDataFormat(format),
-                         GLDataType(format),
-                         NULL));
-    }
-  }
-}
-
-void ResourceProvider::BindImageForSampling(Resource* resource) {
-  GLES2Interface* gl = ContextGL();
-  DCHECK(resource->gl_id);
-  DCHECK(resource->image_id);
-
-  // Release image currently bound to texture.
-  if (resource->bound_image_id)
-    gl->ReleaseTexImage2DCHROMIUM(resource->target, resource->bound_image_id);
-  gl->BindTexImage2DCHROMIUM(resource->target, resource->image_id);
-  resource->bound_image_id = resource->image_id;
-  resource->dirty_image = false;
-}
-
-void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) {
-  TRACE_EVENT0("cc", "ResourceProvider::CopyResource");
-
-  Resource* source_resource = GetResource(source_id);
-  DCHECK(!source_resource->lock_for_read_count);
-  DCHECK(source_resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(source_resource->exported_count, 0);
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, source_resource->type);
-  DCHECK(source_resource->allocated);
-  LazyCreate(source_resource);
-
-  Resource* dest_resource = GetResource(dest_id);
-  DCHECK(!dest_resource->locked_for_write);
-  DCHECK(!dest_resource->lock_for_read_count);
-  DCHECK(dest_resource->origin == Resource::INTERNAL);
-  DCHECK_EQ(dest_resource->exported_count, 0);
-  DCHECK_EQ(RESOURCE_TYPE_GL_TEXTURE, dest_resource->type);
-  LazyAllocate(dest_resource);
-
-  DCHECK_EQ(source_resource->type, dest_resource->type);
-  DCHECK_EQ(source_resource->format, dest_resource->format);
-  DCHECK(source_resource->size == dest_resource->size);
-
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  if (source_resource->image_id && source_resource->dirty_image) {
-    gl->BindTexture(source_resource->target, source_resource->gl_id);
-    BindImageForSampling(source_resource);
-  }
-  if (use_sync_query_) {
-    if (!source_resource->gl_read_lock_query_id)
-      gl->GenQueriesEXT(1, &source_resource->gl_read_lock_query_id);
-#if defined(OS_CHROMEOS)
-    // TODO(reveman): This avoids a performance problem on some ChromeOS
-    // devices. This needs to be removed to support native GpuMemoryBuffer
-    // implementations. crbug.com/436314
-    gl->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM,
-                      source_resource->gl_read_lock_query_id);
-#else
-    gl->BeginQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM,
-                      source_resource->gl_read_lock_query_id);
-#endif
-  }
-  DCHECK(!dest_resource->image_id);
-  dest_resource->allocated = true;
-  gl->CopySubTextureCHROMIUM(dest_resource->target, source_resource->gl_id,
-                             dest_resource->gl_id, 0, 0);
-  if (source_resource->gl_read_lock_query_id) {
-    // End query and create a read lock fence that will prevent access to
-// source resource until CopySubTextureCHROMIUM command has completed.
-#if defined(OS_CHROMEOS)
-    gl->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
-#else
-    gl->EndQueryEXT(GL_COMMANDS_COMPLETED_CHROMIUM);
-#endif
-    source_resource->read_lock_fence = make_scoped_refptr(
-        new CopyTextureFence(gl, source_resource->gl_read_lock_query_id));
-  } else {
-    // Create a SynchronousFence when CHROMIUM_sync_query extension is missing.
-    // Try to use one synchronous fence for as many CopyResource operations as
-    // possible as that reduce the number of times we have to synchronize with
-    // the GL.
-    if (!synchronous_fence_.get() || synchronous_fence_->has_synchronized())
-      synchronous_fence_ = make_scoped_refptr(new SynchronousFence(gl));
-    source_resource->read_lock_fence = synchronous_fence_;
-    source_resource->read_lock_fence->Set();
-  }
-}
-
-void ResourceProvider::WaitSyncPointIfNeeded(ResourceId id) {
-  Resource* resource = GetResource(id);
-  DCHECK_EQ(resource->exported_count, 0);
-  DCHECK(resource->allocated);
-  if (resource->type != RESOURCE_TYPE_GL_TEXTURE || resource->gl_id)
-    return;
-  if (!resource->mailbox.sync_point())
-    return;
-  DCHECK(resource->mailbox.IsValid());
-  GLES2Interface* gl = ContextGL();
-  DCHECK(gl);
-  GLC(gl, gl->WaitSyncPointCHROMIUM(resource->mailbox.sync_point()));
-  resource->mailbox.set_sync_point(0);
-}
-
-void ResourceProvider::WaitReadLockIfNeeded(ResourceId id) {
-  Resource* resource = GetResource(id);
-  DCHECK_EQ(resource->exported_count, 0);
-  if (!resource->read_lock_fence.get())
-    return;
-
-  resource->read_lock_fence->Wait();
-}
-
-GLint ResourceProvider::GetActiveTextureUnit(GLES2Interface* gl) {
-  GLint active_unit = 0;
-  gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit);
-  return active_unit;
-}
-
-GLES2Interface* ResourceProvider::ContextGL() const {
-  ContextProvider* context_provider = output_surface_->context_provider();
-  return context_provider ? context_provider->ContextGL() : NULL;
-}
-
-class GrContext* ResourceProvider::GrContext(bool worker_context) const {
-  ContextProvider* context_provider =
-      worker_context ? output_surface_->worker_context_provider()
-                     : output_surface_->context_provider();
-  return context_provider ? context_provider->GrContext() : NULL;
-}
-
-}  // namespace cc
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
deleted file mode 100644
index 9116319..0000000
--- a/cc/resources/resource_provider.h
+++ /dev/null
@@ -1,668 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_RESOURCES_RESOURCE_PROVIDER_H_
-#define CC_RESOURCES_RESOURCE_PROVIDER_H_
-
-#include <deque>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/containers/hash_tables.h"
-#include "base/memory/linked_ptr.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/threading/thread_checker.h"
-#include "cc/output/context_provider.h"
-#include "cc/output/output_surface.h"
-#include "cc/resources/release_callback_impl.h"
-#include "cc/resources/resource_format.h"
-#include "cc/resources/return_callback.h"
-#include "cc/resources/shared_bitmap.h"
-#include "cc/resources/single_release_callback_impl.h"
-#include "cc/resources/texture_mailbox.h"
-#include "cc/resources/transferable_resource.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/geometry/size.h"
-
-class GrContext;
-
-namespace gpu {
-class GpuMemoryBufferManager;
-namespace gles {
-class GLES2Interface;
-}
-}
-
-namespace gfx {
-class GpuMemoryBuffer;
-class Rect;
-class Vector2d;
-}
-
-namespace cc {
-class BlockingTaskRunner;
-class IdAllocator;
-class SharedBitmap;
-class SharedBitmapManager;
-class TextureUploader;
-
-// This class is not thread-safe and can only be called from the thread it was
-// created on (in practice, the impl thread).
-class ResourceProvider {
- private:
-  struct Resource;
-
- public:
-  typedef unsigned ResourceId;
-  typedef std::vector<ResourceId> ResourceIdArray;
-  typedef std::set<ResourceId> ResourceIdSet;
-  typedef base::hash_map<ResourceId, ResourceId> ResourceIdMap;
-  enum TextureHint {
-    TEXTURE_HINT_DEFAULT = 0x0,
-    TEXTURE_HINT_IMMUTABLE = 0x1,
-    TEXTURE_HINT_FRAMEBUFFER = 0x2,
-    TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER =
-        TEXTURE_HINT_IMMUTABLE | TEXTURE_HINT_FRAMEBUFFER
-  };
-  enum ResourceType {
-    RESOURCE_TYPE_INVALID = 0,
-    RESOURCE_TYPE_GL_TEXTURE = 1,
-    RESOURCE_TYPE_BITMAP,
-  };
-
-  static scoped_ptr<ResourceProvider> Create(
-      OutputSurface* output_surface,
-      SharedBitmapManager* shared_bitmap_manager,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      BlockingTaskRunner* blocking_main_thread_task_runner,
-      int highp_threshold_min,
-      bool use_rgba_4444_texture_format,
-      size_t id_allocation_chunk_size);
-  virtual ~ResourceProvider();
-
-  void InitializeSoftware();
-  void InitializeGL();
-
-  void DidLoseOutputSurface() { lost_output_surface_ = true; }
-
-  int max_texture_size() const { return max_texture_size_; }
-  ResourceFormat memory_efficient_texture_format() const {
-    return use_rgba_4444_texture_format_ ? RGBA_4444 : best_texture_format_;
-  }
-  ResourceFormat best_texture_format() const { return best_texture_format_; }
-  ResourceFormat yuv_resource_format() const { return yuv_resource_format_; }
-  bool use_sync_query() const { return use_sync_query_; }
-  size_t num_resources() const { return resources_.size(); }
-
-  // Checks whether a resource is in use by a consumer.
-  bool InUseByConsumer(ResourceId id);
-
-  bool IsLost(ResourceId id);
-  bool AllowOverlay(ResourceId id);
-
-  // Producer interface.
-
-  ResourceType default_resource_type() const { return default_resource_type_; }
-  ResourceType GetResourceType(ResourceId id);
-
-  // Creates a resource of the default resource type.
-  ResourceId CreateResource(const gfx::Size& size,
-                            GLint wrap_mode,
-                            TextureHint hint,
-                            ResourceFormat format);
-
-  // Creates a resource which is tagged as being managed for GPU memory
-  // accounting purposes.
-  ResourceId CreateManagedResource(const gfx::Size& size,
-                                   GLenum target,
-                                   GLint wrap_mode,
-                                   TextureHint hint,
-                                   ResourceFormat format);
-
-  // You can also explicitly create a specific resource type.
-  ResourceId CreateGLTexture(const gfx::Size& size,
-                             GLenum target,
-                             GLenum texture_pool,
-                             GLint wrap_mode,
-                             TextureHint hint,
-                             ResourceFormat format);
-
-  ResourceId CreateBitmap(const gfx::Size& size, GLint wrap_mode);
-  // Wraps an IOSurface into a GL resource.
-  ResourceId CreateResourceFromIOSurface(const gfx::Size& size,
-                                         unsigned io_surface_id);
-
-  // Wraps an external texture mailbox into a GL resource.
-  ResourceId CreateResourceFromTextureMailbox(
-      const TextureMailbox& mailbox,
-      scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl);
-
-  void DeleteResource(ResourceId id);
-
-  // Update pixels from image, copying source_rect (in image) to dest_offset (in
-  // the resource).
-  // NOTE: DEPRECATED. Use CopyToResource() instead.
-  void SetPixels(ResourceId id,
-                 const uint8_t* image,
-                 const gfx::Rect& image_rect,
-                 const gfx::Rect& source_rect,
-                 const gfx::Vector2d& dest_offset);
-  void CopyToResource(ResourceId id,
-                      const uint8_t* image,
-                      const gfx::Size& image_size);
-
-  // Check upload status.
-  size_t NumBlockingUploads();
-  void MarkPendingUploadsAsNonBlocking();
-  size_t EstimatedUploadsPerTick();
-  void FlushUploads();
-  void ReleaseCachedData();
-  base::TimeTicks EstimatedUploadCompletionTime(size_t uploads_per_tick);
-
-  // Only flush the command buffer if supported.
-  // Returns true if the shallow flush occurred, false otherwise.
-  bool ShallowFlushIfSupported();
-
-  // Creates accounting for a child. Returns a child ID.
-  int CreateChild(const ReturnCallback& return_callback);
-
-  // Destroys accounting for the child, deleting all accounted resources.
-  void DestroyChild(int child);
-
-  // Gets the child->parent resource ID map.
-  const ResourceIdMap& GetChildToParentMap(int child) const;
-
-  // Prepares resources to be transfered to the parent, moving them to
-  // mailboxes and serializing meta-data into TransferableResources.
-  // Resources are not removed from the ResourceProvider, but are marked as
-  // "in use".
-  void PrepareSendToParent(const ResourceIdArray& resources,
-                           TransferableResourceArray* transferable_resources);
-
-  // Receives resources from a child, moving them from mailboxes. Resource IDs
-  // passed are in the child namespace, and will be translated to the parent
-  // namespace, added to the child->parent map.
-  // This adds the resources to the working set in the ResourceProvider without
-  // declaring which resources are in use. Use DeclareUsedResourcesFromChild
-  // after calling this method to do that. All calls to ReceiveFromChild should
-  // be followed by a DeclareUsedResourcesFromChild.
-  // NOTE: if the sync_point is set on any TransferableResource, this will
-  // wait on it.
-  void ReceiveFromChild(
-      int child, const TransferableResourceArray& transferable_resources);
-
-  // Once a set of resources have been received, they may or may not be used.
-  // This declares what set of resources are currently in use from the child,
-  // releasing any other resources back to the child.
-  void DeclareUsedResourcesFromChild(
-      int child,
-      const ResourceIdArray& resources_from_child);
-
-  // Receives resources from the parent, moving them from mailboxes. Resource
-  // IDs passed are in the child namespace.
-  // NOTE: if the sync_point is set on any TransferableResource, this will
-  // wait on it.
-  void ReceiveReturnsFromParent(
-      const ReturnedResourceArray& transferable_resources);
-
-  // The following lock classes are part of the ResourceProvider API and are
-  // needed to read and write the resource contents. The user must ensure
-  // that they only use GL locks on GL resources, etc, and this is enforced
-  // by assertions.
-  class ScopedReadLockGL {
-   public:
-    ScopedReadLockGL(ResourceProvider* resource_provider,
-                     ResourceProvider::ResourceId resource_id);
-    virtual ~ScopedReadLockGL();
-
-    unsigned texture_id() const { return texture_id_; }
-
-   protected:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::ResourceId resource_id_;
-
-   private:
-    unsigned texture_id_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedReadLockGL);
-  };
-
-  class ScopedSamplerGL : public ScopedReadLockGL {
-   public:
-    ScopedSamplerGL(ResourceProvider* resource_provider,
-                    ResourceProvider::ResourceId resource_id,
-                    GLenum filter);
-    ScopedSamplerGL(ResourceProvider* resource_provider,
-                    ResourceProvider::ResourceId resource_id,
-                    GLenum unit,
-                    GLenum filter);
-    ~ScopedSamplerGL() override;
-
-    GLenum target() const { return target_; }
-
-   private:
-    GLenum unit_;
-    GLenum target_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedSamplerGL);
-  };
-
-  class ScopedWriteLockGL {
-   public:
-    ScopedWriteLockGL(ResourceProvider* resource_provider,
-                      ResourceProvider::ResourceId resource_id);
-    ~ScopedWriteLockGL();
-
-    unsigned texture_id() const { return texture_id_; }
-
-   private:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::Resource* resource_;
-    unsigned texture_id_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGL);
-  };
-
-  class ScopedReadLockSoftware {
-   public:
-    ScopedReadLockSoftware(ResourceProvider* resource_provider,
-                           ResourceProvider::ResourceId resource_id);
-    ~ScopedReadLockSoftware();
-
-    const SkBitmap* sk_bitmap() const {
-      DCHECK(valid());
-      return &sk_bitmap_;
-    }
-    GLint wrap_mode() const { return wrap_mode_; }
-
-    bool valid() const { return !!sk_bitmap_.getPixels(); }
-
-   private:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::ResourceId resource_id_;
-    SkBitmap sk_bitmap_;
-    GLint wrap_mode_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedReadLockSoftware);
-  };
-
-  class ScopedWriteLockSoftware {
-   public:
-    ScopedWriteLockSoftware(ResourceProvider* resource_provider,
-                            ResourceProvider::ResourceId resource_id);
-    ~ScopedWriteLockSoftware();
-
-    SkBitmap& sk_bitmap() { return sk_bitmap_; }
-    bool valid() const { return !!sk_bitmap_.getPixels(); }
-
-   private:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::Resource* resource_;
-    SkBitmap sk_bitmap_;
-    base::ThreadChecker thread_checker_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockSoftware);
-  };
-
-  class ScopedWriteLockGpuMemoryBuffer {
-   public:
-    ScopedWriteLockGpuMemoryBuffer(ResourceProvider* resource_provider,
-                                   ResourceProvider::ResourceId resource_id);
-    ~ScopedWriteLockGpuMemoryBuffer();
-
-    gfx::GpuMemoryBuffer* GetGpuMemoryBuffer();
-
-   private:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::Resource* resource_;
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
-    gfx::GpuMemoryBuffer* gpu_memory_buffer_;
-    gfx::Size size_;
-    ResourceFormat format_;
-    base::ThreadChecker thread_checker_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGpuMemoryBuffer);
-  };
-
-  class ScopedWriteLockGr {
-   public:
-    ScopedWriteLockGr(ResourceProvider* resource_provider,
-                      ResourceProvider::ResourceId resource_id);
-    ~ScopedWriteLockGr();
-
-    void InitSkSurface(bool use_worker_context,
-                       bool use_distance_field_text,
-                       bool can_use_lcd_text,
-                       int msaa_sample_count);
-    void ReleaseSkSurface();
-
-    SkSurface* sk_surface() { return sk_surface_.get(); }
-    ResourceProvider::Resource* resource() { return resource_; }
-
-   private:
-    ResourceProvider* resource_provider_;
-    ResourceProvider::Resource* resource_;
-    base::ThreadChecker thread_checker_;
-    skia::RefPtr<SkSurface> sk_surface_;
-
-    DISALLOW_COPY_AND_ASSIGN(ScopedWriteLockGr);
-  };
-
-  class Fence : public base::RefCounted<Fence> {
-   public:
-    Fence() {}
-
-    virtual void Set() = 0;
-    virtual bool HasPassed() = 0;
-    virtual void Wait() = 0;
-
-   protected:
-    friend class base::RefCounted<Fence>;
-    virtual ~Fence() {}
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Fence);
-  };
-
-  class SynchronousFence : public ResourceProvider::Fence {
-   public:
-    explicit SynchronousFence(gpu::gles2::GLES2Interface* gl);
-
-    // Overridden from Fence:
-    void Set() override;
-    bool HasPassed() override;
-    void Wait() override;
-
-    // Returns true if fence has been set but not yet synchornized.
-    bool has_synchronized() const { return has_synchronized_; }
-
-   private:
-    ~SynchronousFence() override;
-
-    void Synchronize();
-
-    gpu::gles2::GLES2Interface* gl_;
-    bool has_synchronized_;
-
-    DISALLOW_COPY_AND_ASSIGN(SynchronousFence);
-  };
-
-  // Acquire pixel buffer for resource. The pixel buffer can be used to
-  // set resource pixels without performing unnecessary copying.
-  void AcquirePixelBuffer(ResourceId resource);
-  void ReleasePixelBuffer(ResourceId resource);
-  // Map/unmap the acquired pixel buffer.
-  uint8_t* MapPixelBuffer(ResourceId id, int* stride);
-  void UnmapPixelBuffer(ResourceId id);
-  // Asynchronously update pixels from acquired pixel buffer.
-  void BeginSetPixels(ResourceId id);
-  void ForceSetPixelsToComplete(ResourceId id);
-  bool DidSetPixelsComplete(ResourceId id);
-
-  // For tests only! This prevents detecting uninitialized reads.
-  // Use SetPixels or LockForWrite to allocate implicitly.
-  void AllocateForTesting(ResourceId id);
-
-  // For tests only!
-  void CreateForTesting(ResourceId id);
-
-  GLenum TargetForTesting(ResourceId id);
-
-  // Sets the current read fence. If a resource is locked for read
-  // and has read fences enabled, the resource will not allow writes
-  // until this fence has passed.
-  void SetReadLockFence(Fence* fence) { current_read_lock_fence_ = fence; }
-
-  // Indicates if we can currently lock this resource for write.
-  bool CanLockForWrite(ResourceId id);
-
-  // Copy pixels from source to destination.
-  void CopyResource(ResourceId source_id, ResourceId dest_id);
-
-  void WaitSyncPointIfNeeded(ResourceId id);
-
-  void WaitReadLockIfNeeded(ResourceId id);
-
-  static GLint GetActiveTextureUnit(gpu::gles2::GLES2Interface* gl);
-
-  OutputSurface* output_surface() { return output_surface_; }
-
- private:
-  struct Resource {
-    enum Origin { INTERNAL, EXTERNAL, DELEGATED };
-
-    Resource();
-    ~Resource();
-    Resource(unsigned texture_id,
-             const gfx::Size& size,
-             Origin origin,
-             GLenum target,
-             GLenum filter,
-             GLenum texture_pool,
-             GLint wrap_mode,
-             TextureHint hint,
-             ResourceFormat format);
-    Resource(uint8_t* pixels,
-             SharedBitmap* bitmap,
-             const gfx::Size& size,
-             Origin origin,
-             GLenum filter,
-             GLint wrap_mode);
-    Resource(const SharedBitmapId& bitmap_id,
-             const gfx::Size& size,
-             Origin origin,
-             GLenum filter,
-             GLint wrap_mode);
-
-    int child_id;
-    unsigned gl_id;
-    // Pixel buffer used for set pixels without unnecessary copying.
-    unsigned gl_pixel_buffer_id;
-    // Query used to determine when asynchronous set pixels complete.
-    unsigned gl_upload_query_id;
-    // Query used to determine when read lock fence has passed.
-    unsigned gl_read_lock_query_id;
-    TextureMailbox mailbox;
-    ReleaseCallbackImpl release_callback_impl;
-    uint8_t* pixels;
-    int lock_for_read_count;
-    int imported_count;
-    int exported_count;
-    bool dirty_image : 1;
-    bool locked_for_write : 1;
-    bool lost : 1;
-    bool marked_for_deletion : 1;
-    bool pending_set_pixels : 1;
-    bool set_pixels_completion_forced : 1;
-    bool allocated : 1;
-    bool read_lock_fences_enabled : 1;
-    bool has_shared_bitmap_id : 1;
-    bool allow_overlay : 1;
-    scoped_refptr<Fence> read_lock_fence;
-    gfx::Size size;
-    Origin origin;
-    GLenum target;
-    // TODO(skyostil): Use a separate sampler object for filter state.
-    GLenum original_filter;
-    GLenum filter;
-    unsigned image_id;
-    unsigned bound_image_id;
-    GLenum texture_pool;
-    GLint wrap_mode;
-    TextureHint hint;
-    ResourceType type;
-    ResourceFormat format;
-    SharedBitmapId shared_bitmap_id;
-    SharedBitmap* shared_bitmap;
-    gfx::GpuMemoryBuffer* gpu_memory_buffer;
-  };
-  typedef base::hash_map<ResourceId, Resource> ResourceMap;
-
-  static bool CompareResourceMapIteratorsByChildId(
-      const std::pair<ReturnedResource, ResourceMap::iterator>& a,
-      const std::pair<ReturnedResource, ResourceMap::iterator>& b);
-
-  struct Child {
-    Child();
-    ~Child();
-
-    ResourceIdMap child_to_parent_map;
-    ResourceIdMap parent_to_child_map;
-    ReturnCallback return_callback;
-    ResourceIdSet in_use_resources;
-    bool marked_for_deletion;
-  };
-  typedef base::hash_map<int, Child> ChildMap;
-
-  bool ReadLockFenceHasPassed(const Resource* resource) {
-    return !resource->read_lock_fence.get() ||
-           resource->read_lock_fence->HasPassed();
-  }
-
-  ResourceProvider(OutputSurface* output_surface,
-                   SharedBitmapManager* shared_bitmap_manager,
-                   gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-                   BlockingTaskRunner* blocking_main_thread_task_runner,
-                   int highp_threshold_min,
-                   bool use_rgba_4444_texture_format,
-                   size_t id_allocation_chunk_size);
-
-  void CleanUpGLIfNeeded();
-
-  Resource* GetResource(ResourceId id);
-  const Resource* LockForRead(ResourceId id);
-  void UnlockForRead(ResourceId id);
-  Resource* LockForWrite(ResourceId id);
-  void UnlockForWrite(Resource* resource);
-
-  static void PopulateSkBitmapWithResource(SkBitmap* sk_bitmap,
-                                           const Resource* resource);
-
-  void TransferResource(gpu::gles2::GLES2Interface* gl,
-                        ResourceId id,
-                        TransferableResource* resource);
-  enum DeleteStyle {
-    NORMAL,
-    FOR_SHUTDOWN,
-  };
-  void DeleteResourceInternal(ResourceMap::iterator it, DeleteStyle style);
-  void DeleteAndReturnUnusedResourcesToChild(ChildMap::iterator child_it,
-                                             DeleteStyle style,
-                                             const ResourceIdArray& unused);
-  void DestroyChildInternal(ChildMap::iterator it, DeleteStyle style);
-  void LazyCreate(Resource* resource);
-  void LazyAllocate(Resource* resource);
-
-  void BindImageForSampling(Resource* resource);
-  // Binds the given GL resource to a texture target for sampling using the
-  // specified filter for both minification and magnification. Returns the
-  // texture target used. The resource must be locked for reading.
-  GLenum BindForSampling(ResourceId resource_id, GLenum unit, GLenum filter);
-
-  // Returns NULL if the output_surface_ does not have a ContextProvider.
-  gpu::gles2::GLES2Interface* ContextGL() const;
-  class GrContext* GrContext(bool worker_context) const;
-
-  OutputSurface* output_surface_;
-  SharedBitmapManager* shared_bitmap_manager_;
-  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
-  BlockingTaskRunner* blocking_main_thread_task_runner_;
-  bool lost_output_surface_;
-  int highp_threshold_min_;
-  ResourceId next_id_;
-  ResourceMap resources_;
-  int next_child_;
-  ChildMap children_;
-
-  ResourceType default_resource_type_;
-  bool use_texture_storage_ext_;
-  bool use_texture_format_bgra_;
-  bool use_texture_usage_hint_;
-  bool use_compressed_texture_etc1_;
-  ResourceFormat yuv_resource_format_;
-  scoped_ptr<TextureUploader> texture_uploader_;
-  int max_texture_size_;
-  ResourceFormat best_texture_format_;
-
-  base::ThreadChecker thread_checker_;
-
-  scoped_refptr<Fence> current_read_lock_fence_;
-  bool use_rgba_4444_texture_format_;
-
-  const size_t id_allocation_chunk_size_;
-  scoped_ptr<IdAllocator> texture_id_allocator_;
-  scoped_ptr<IdAllocator> buffer_id_allocator_;
-
-  bool use_sync_query_;
-  // Fence used for CopyResource if CHROMIUM_sync_query is not supported.
-  scoped_refptr<SynchronousFence> synchronous_fence_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceProvider);
-};
-
-// TODO(epenner): Move these format conversions to resource_format.h
-// once that builds on mac (npapi.h currently #includes OpenGL.h).
-inline unsigned BitsPerPixel(ResourceFormat format) {
-  switch (format) {
-    case BGRA_8888:
-    case RGBA_8888:
-      return 32;
-    case RGBA_4444:
-    case RGB_565:
-      return 16;
-    case ALPHA_8:
-    case LUMINANCE_8:
-    case RED_8:
-      return 8;
-    case ETC1:
-      return 4;
-  }
-  NOTREACHED();
-  return 0;
-}
-
-inline GLenum GLDataType(ResourceFormat format) {
-  DCHECK_LE(format, RESOURCE_FORMAT_MAX);
-  static const unsigned format_gl_data_type[RESOURCE_FORMAT_MAX + 1] = {
-      GL_UNSIGNED_BYTE,           // RGBA_8888
-      GL_UNSIGNED_SHORT_4_4_4_4,  // RGBA_4444
-      GL_UNSIGNED_BYTE,           // BGRA_8888
-      GL_UNSIGNED_BYTE,           // ALPHA_8
-      GL_UNSIGNED_BYTE,           // LUMINANCE_8
-      GL_UNSIGNED_SHORT_5_6_5,    // RGB_565,
-      GL_UNSIGNED_BYTE,           // ETC1
-      GL_UNSIGNED_BYTE            // RED_8
-  };
-  return format_gl_data_type[format];
-}
-
-inline GLenum GLDataFormat(ResourceFormat format) {
-  DCHECK_LE(format, RESOURCE_FORMAT_MAX);
-  static const unsigned format_gl_data_format[RESOURCE_FORMAT_MAX + 1] = {
-      GL_RGBA,           // RGBA_8888
-      GL_RGBA,           // RGBA_4444
-      GL_BGRA_EXT,       // BGRA_8888
-      GL_ALPHA,          // ALPHA_8
-      GL_LUMINANCE,      // LUMINANCE_8
-      GL_RGB,            // RGB_565
-      GL_ETC1_RGB8_OES,  // ETC1
-      GL_RED_EXT         // RED_8
-  };
-  return format_gl_data_format[format];
-}
-
-inline GLenum GLInternalFormat(ResourceFormat format) {
-  return GLDataFormat(format);
-}
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RESOURCE_PROVIDER_H_
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc
deleted file mode 100644
index b33b4c3..0000000
--- a/cc/resources/resource_provider_unittest.cc
+++ /dev/null
@@ -1,3734 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/resource_provider.h"
-
-#include <algorithm>
-#include <map>
-#include <set>
-
-#include "base/bind.h"
-#include "base/containers/hash_tables.h"
-#include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "cc/base/blocking_task_runner.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/output/output_surface.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/resources/shared_bitmap_manager.h"
-#include "cc/resources/single_release_callback.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/test_gpu_memory_buffer_manager.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/test_texture.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-using testing::Mock;
-using testing::NiceMock;
-using testing::Return;
-using testing::SetArgPointee;
-using testing::StrictMock;
-using testing::_;
-
-namespace cc {
-namespace {
-
-static void EmptyReleaseCallback(uint32 sync_point,
-                                 bool lost_resource,
-                                 BlockingTaskRunner* main_thread_task_runner) {
-}
-
-static void ReleaseCallback(
-    uint32* release_sync_point,
-    bool* release_lost_resource,
-    BlockingTaskRunner** release_main_thread_task_runner,
-    uint32 sync_point,
-    bool lost_resource,
-    BlockingTaskRunner* main_thread_task_runner) {
-  *release_sync_point = sync_point;
-  *release_lost_resource = lost_resource;
-  *release_main_thread_task_runner = main_thread_task_runner;
-}
-
-static void SharedBitmapReleaseCallback(
-    scoped_ptr<SharedBitmap> bitmap,
-    uint32 sync_point,
-    bool lost_resource,
-    BlockingTaskRunner* main_thread_task_runner) {
-}
-
-static void ReleaseSharedBitmapCallback(
-    scoped_ptr<SharedBitmap> shared_bitmap,
-    bool* release_called,
-    uint32* release_sync_point,
-    bool* lost_resource_result,
-    uint32 sync_point,
-    bool lost_resource,
-    BlockingTaskRunner* main_thread_task_runner) {
-  *release_called = true;
-  *release_sync_point = sync_point;
-  *lost_resource_result = lost_resource;
-}
-
-static scoped_ptr<SharedBitmap> CreateAndFillSharedBitmap(
-    SharedBitmapManager* manager,
-    const gfx::Size& size,
-    uint32_t value) {
-  scoped_ptr<SharedBitmap> shared_bitmap = manager->AllocateSharedBitmap(size);
-  CHECK(shared_bitmap);
-  uint32_t* pixels = reinterpret_cast<uint32_t*>(shared_bitmap->pixels());
-  CHECK(pixels);
-  std::fill_n(pixels, size.GetArea(), value);
-  return shared_bitmap.Pass();
-}
-
-class TextureStateTrackingContext : public TestWebGraphicsContext3D {
- public:
-  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
-  MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param));
-  MOCK_METHOD1(waitSyncPoint, void(GLuint sync_point));
-  MOCK_METHOD0(insertSyncPoint, GLuint(void));
-  MOCK_METHOD3(produceTextureDirectCHROMIUM,
-               void(GLuint texture, GLenum target, const GLbyte* mailbox));
-  MOCK_METHOD2(createAndConsumeTextureCHROMIUM,
-               unsigned(GLenum target, const GLbyte* mailbox));
-
-  // Force all textures to be consecutive numbers starting at "1",
-  // so we easily can test for them.
-  GLuint NextTextureId() override {
-    base::AutoLock lock(namespace_->lock);
-    return namespace_->next_texture_id++;
-  }
-  void RetireTextureId(GLuint) override {}
-};
-
-// Shared data between multiple ResourceProviderContext. This contains mailbox
-// contents as well as information about sync points.
-class ContextSharedData {
- public:
-  static scoped_ptr<ContextSharedData> Create() {
-    return make_scoped_ptr(new ContextSharedData());
-  }
-
-  uint32 InsertSyncPoint() { return next_sync_point_++; }
-
-  void GenMailbox(GLbyte* mailbox) {
-    memset(mailbox, 0, GL_MAILBOX_SIZE_CHROMIUM);
-    memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
-    ++next_mailbox_;
-  }
-
-  void ProduceTexture(const GLbyte* mailbox_name,
-                      uint32 sync_point,
-                      scoped_refptr<TestTexture> texture) {
-    unsigned mailbox = 0;
-    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
-    ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
-    textures_[mailbox] = texture;
-    ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
-    sync_point_for_mailbox_[mailbox] = sync_point;
-  }
-
-  scoped_refptr<TestTexture> ConsumeTexture(const GLbyte* mailbox_name,
-                                            uint32 sync_point) {
-    unsigned mailbox = 0;
-    memcpy(&mailbox, mailbox_name, sizeof(mailbox));
-    DCHECK(mailbox && mailbox < next_mailbox_);
-
-    // If the latest sync point the context has waited on is before the sync
-    // point for when the mailbox was set, pretend we never saw that
-    // ProduceTexture.
-    if (sync_point_for_mailbox_[mailbox] > sync_point) {
-      NOTREACHED();
-      return scoped_refptr<TestTexture>();
-    }
-    return textures_[mailbox];
-  }
-
- private:
-  ContextSharedData() : next_sync_point_(1), next_mailbox_(1) {}
-
-  uint32 next_sync_point_;
-  unsigned next_mailbox_;
-  typedef base::hash_map<unsigned, scoped_refptr<TestTexture>> TextureMap;
-  TextureMap textures_;
-  base::hash_map<unsigned, uint32> sync_point_for_mailbox_;
-};
-
-class ResourceProviderContext : public TestWebGraphicsContext3D {
- public:
-  static scoped_ptr<ResourceProviderContext> Create(
-      ContextSharedData* shared_data) {
-    return make_scoped_ptr(new ResourceProviderContext(shared_data));
-  }
-
-  GLuint insertSyncPoint() override {
-    uint32 sync_point = shared_data_->InsertSyncPoint();
-    // Commit the produceTextureCHROMIUM calls at this point, so that
-    // they're associated with the sync point.
-    for (PendingProduceTextureList::iterator it =
-             pending_produce_textures_.begin();
-         it != pending_produce_textures_.end();
-         ++it) {
-      shared_data_->ProduceTexture(
-          (*it)->mailbox, sync_point, (*it)->texture);
-    }
-    pending_produce_textures_.clear();
-    return sync_point;
-  }
-
-  void waitSyncPoint(GLuint sync_point) override {
-    last_waited_sync_point_ = std::max(sync_point, last_waited_sync_point_);
-  }
-
-  unsigned last_waited_sync_point() const { return last_waited_sync_point_; }
-
-  void texStorage2DEXT(GLenum target,
-                       GLint levels,
-                       GLuint internalformat,
-                       GLint width,
-                       GLint height) override {
-    CheckTextureIsBound(target);
-    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
-    ASSERT_EQ(1, levels);
-    GLenum format = GL_RGBA;
-    switch (internalformat) {
-      case GL_RGBA8_OES:
-        break;
-      case GL_BGRA8_EXT:
-        format = GL_BGRA_EXT;
-        break;
-      default:
-        NOTREACHED();
-    }
-    AllocateTexture(gfx::Size(width, height), format);
-  }
-
-  void texImage2D(GLenum target,
-                  GLint level,
-                  GLenum internalformat,
-                  GLsizei width,
-                  GLsizei height,
-                  GLint border,
-                  GLenum format,
-                  GLenum type,
-                  const void* pixels) override {
-    CheckTextureIsBound(target);
-    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
-    ASSERT_FALSE(level);
-    ASSERT_EQ(internalformat, format);
-    ASSERT_FALSE(border);
-    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-    AllocateTexture(gfx::Size(width, height), format);
-    if (pixels)
-      SetPixels(0, 0, width, height, pixels);
-  }
-
-  void texSubImage2D(GLenum target,
-                     GLint level,
-                     GLint xoffset,
-                     GLint yoffset,
-                     GLsizei width,
-                     GLsizei height,
-                     GLenum format,
-                     GLenum type,
-                     const void* pixels) override {
-    CheckTextureIsBound(target);
-    ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
-    ASSERT_FALSE(level);
-    ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-    {
-      base::AutoLock lock_for_texture_access(namespace_->lock);
-      ASSERT_EQ(GLDataFormat(BoundTexture(target)->format), format);
-    }
-    ASSERT_TRUE(pixels);
-    SetPixels(xoffset, yoffset, width, height, pixels);
-  }
-
-  void genMailboxCHROMIUM(GLbyte* mailbox) override {
-    return shared_data_->GenMailbox(mailbox);
-  }
-
-  void produceTextureDirectCHROMIUM(GLuint texture,
-                                    GLenum target,
-                                    const GLbyte* mailbox) override {
-    // Delay moving the texture into the mailbox until the next
-    // InsertSyncPoint, so that it is not visible to other contexts that
-    // haven't waited on that sync point.
-    scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
-    memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
-    base::AutoLock lock_for_texture_access(namespace_->lock);
-    pending->texture = UnboundTexture(texture);
-    pending_produce_textures_.push_back(pending.Pass());
-  }
-
-  GLuint createAndConsumeTextureCHROMIUM(GLenum target,
-                                         const GLbyte* mailbox) override {
-    GLuint texture_id = createTexture();
-    base::AutoLock lock_for_texture_access(namespace_->lock);
-    scoped_refptr<TestTexture> texture =
-        shared_data_->ConsumeTexture(mailbox, last_waited_sync_point_);
-    namespace_->textures.Replace(texture_id, texture);
-    return texture_id;
-  }
-
-  void GetPixels(const gfx::Size& size,
-                 ResourceFormat format,
-                 uint8_t* pixels) {
-    CheckTextureIsBound(GL_TEXTURE_2D);
-    base::AutoLock lock_for_texture_access(namespace_->lock);
-    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
-    ASSERT_EQ(texture->size, size);
-    ASSERT_EQ(texture->format, format);
-    memcpy(pixels, texture->data.get(), TextureSizeBytes(size, format));
-  }
-
- protected:
-  explicit ResourceProviderContext(ContextSharedData* shared_data)
-      : shared_data_(shared_data),
-        last_waited_sync_point_(0) {}
-
- private:
-  void AllocateTexture(const gfx::Size& size, GLenum format) {
-    CheckTextureIsBound(GL_TEXTURE_2D);
-    ResourceFormat texture_format = RGBA_8888;
-    switch (format) {
-      case GL_RGBA:
-        texture_format = RGBA_8888;
-        break;
-      case GL_BGRA_EXT:
-        texture_format = BGRA_8888;
-        break;
-    }
-    base::AutoLock lock_for_texture_access(namespace_->lock);
-    BoundTexture(GL_TEXTURE_2D)->Reallocate(size, texture_format);
-  }
-
-  void SetPixels(int xoffset,
-                 int yoffset,
-                 int width,
-                 int height,
-                 const void* pixels) {
-    CheckTextureIsBound(GL_TEXTURE_2D);
-    base::AutoLock lock_for_texture_access(namespace_->lock);
-    scoped_refptr<TestTexture> texture = BoundTexture(GL_TEXTURE_2D);
-    ASSERT_TRUE(texture->data.get());
-    ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
-    ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
-    ASSERT_TRUE(pixels);
-    size_t in_pitch = TextureSizeBytes(gfx::Size(width, 1), texture->format);
-    size_t out_pitch =
-        TextureSizeBytes(gfx::Size(texture->size.width(), 1), texture->format);
-    uint8_t* dest = texture->data.get() + yoffset * out_pitch +
-                    TextureSizeBytes(gfx::Size(xoffset, 1), texture->format);
-    const uint8_t* src = static_cast<const uint8_t*>(pixels);
-    for (int i = 0; i < height; ++i) {
-      memcpy(dest, src, in_pitch);
-      dest += out_pitch;
-      src += in_pitch;
-    }
-  }
-
-  struct PendingProduceTexture {
-    GLbyte mailbox[GL_MAILBOX_SIZE_CHROMIUM];
-    scoped_refptr<TestTexture> texture;
-  };
-  typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
-  ContextSharedData* shared_data_;
-  GLuint last_waited_sync_point_;
-  PendingProduceTextureList pending_produce_textures_;
-};
-
-void GetResourcePixels(ResourceProvider* resource_provider,
-                       ResourceProviderContext* context,
-                       ResourceProvider::ResourceId id,
-                       const gfx::Size& size,
-                       ResourceFormat format,
-                       uint8_t* pixels) {
-  resource_provider->WaitSyncPointIfNeeded(id);
-  switch (resource_provider->default_resource_type()) {
-    case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: {
-      ResourceProvider::ScopedReadLockGL lock_gl(resource_provider, id);
-      ASSERT_NE(0U, lock_gl.texture_id());
-      context->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
-      context->GetPixels(size, format, pixels);
-      break;
-    }
-    case ResourceProvider::RESOURCE_TYPE_BITMAP: {
-      ResourceProvider::ScopedReadLockSoftware lock_software(resource_provider,
-                                                             id);
-      memcpy(pixels,
-             lock_software.sk_bitmap()->getPixels(),
-             lock_software.sk_bitmap()->getSize());
-      break;
-    }
-    case ResourceProvider::RESOURCE_TYPE_INVALID:
-      NOTREACHED();
-      break;
-  }
-}
-
-class ResourceProviderTest
-    : public testing::TestWithParam<ResourceProvider::ResourceType> {
- public:
-  ResourceProviderTest()
-      : shared_data_(ContextSharedData::Create()),
-        context3d_(NULL),
-        child_context_(NULL),
-        main_thread_task_runner_(BlockingTaskRunner::Create(NULL)) {
-    switch (GetParam()) {
-      case ResourceProvider::RESOURCE_TYPE_GL_TEXTURE: {
-        scoped_ptr<ResourceProviderContext> context3d(
-            ResourceProviderContext::Create(shared_data_.get()));
-        context3d_ = context3d.get();
-
-        scoped_refptr<TestContextProvider> context_provider =
-            TestContextProvider::Create(context3d.Pass());
-
-        output_surface_ = FakeOutputSurface::Create3d(context_provider);
-
-        scoped_ptr<ResourceProviderContext> child_context_owned =
-            ResourceProviderContext::Create(shared_data_.get());
-        child_context_ = child_context_owned.get();
-        child_output_surface_ =
-            FakeOutputSurface::Create3d(child_context_owned.Pass());
-        break;
-      }
-      case ResourceProvider::RESOURCE_TYPE_BITMAP:
-        output_surface_ = FakeOutputSurface::CreateSoftware(
-            make_scoped_ptr(new SoftwareOutputDevice));
-        child_output_surface_ = FakeOutputSurface::CreateSoftware(
-            make_scoped_ptr(new SoftwareOutputDevice));
-        break;
-      case ResourceProvider::RESOURCE_TYPE_INVALID:
-        NOTREACHED();
-        break;
-    }
-    CHECK(output_surface_->BindToClient(&output_surface_client_));
-    CHECK(child_output_surface_->BindToClient(&child_output_surface_client_));
-
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-    gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager);
-
-    resource_provider_ =
-        ResourceProvider::Create(output_surface_.get(),
-                                 shared_bitmap_manager_.get(),
-                                 gpu_memory_buffer_manager_.get(),
-                                 main_thread_task_runner_.get(),
-                                 0,
-                                 false,
-                                 1);
-    child_resource_provider_ =
-        ResourceProvider::Create(child_output_surface_.get(),
-                                 shared_bitmap_manager_.get(),
-                                 gpu_memory_buffer_manager_.get(),
-                                 main_thread_task_runner_.get(),
-                                 0,
-                                 false,
-                                 1);
-  }
-
-  static void CollectResources(ReturnedResourceArray* array,
-                               const ReturnedResourceArray& returned,
-                               BlockingTaskRunner* main_thread_task_runner) {
-    array->insert(array->end(), returned.begin(), returned.end());
-  }
-
-  static ReturnCallback GetReturnCallback(ReturnedResourceArray* array) {
-    return base::Bind(&ResourceProviderTest::CollectResources, array);
-  }
-
-  static void SetResourceFilter(ResourceProvider* resource_provider,
-                                ResourceProvider::ResourceId id,
-                                GLenum filter) {
-    ResourceProvider::ScopedSamplerGL sampler(
-        resource_provider, id, GL_TEXTURE_2D, filter);
-  }
-
-  ResourceProviderContext* context() { return context3d_; }
-
-  ResourceProvider::ResourceId CreateChildMailbox(uint32* release_sync_point,
-                                                  bool* lost_resource,
-                                                  bool* release_called,
-                                                  uint32* sync_point) {
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      unsigned texture = child_context_->createTexture();
-      gpu::Mailbox gpu_mailbox;
-      child_context_->genMailboxCHROMIUM(gpu_mailbox.name);
-      child_context_->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D,
-                                                   gpu_mailbox.name);
-      *sync_point = child_context_->insertSyncPoint();
-      EXPECT_LT(0u, *sync_point);
-
-      scoped_ptr<SharedBitmap> shared_bitmap;
-      scoped_ptr<SingleReleaseCallbackImpl> callback =
-          SingleReleaseCallbackImpl::Create(base::Bind(
-              ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
-              release_called, release_sync_point, lost_resource));
-      return child_resource_provider_->CreateResourceFromTextureMailbox(
-          TextureMailbox(gpu_mailbox, GL_TEXTURE_2D, *sync_point),
-          callback.Pass());
-    } else {
-      gfx::Size size(64, 64);
-      scoped_ptr<SharedBitmap> shared_bitmap(
-          CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, 0));
-
-      SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
-      scoped_ptr<SingleReleaseCallbackImpl> callback =
-          SingleReleaseCallbackImpl::Create(base::Bind(
-              ReleaseSharedBitmapCallback, base::Passed(&shared_bitmap),
-              release_called, release_sync_point, lost_resource));
-      return child_resource_provider_->CreateResourceFromTextureMailbox(
-          TextureMailbox(shared_bitmap_ptr, size), callback.Pass());
-    }
-  }
-
- protected:
-  scoped_ptr<ContextSharedData> shared_data_;
-  ResourceProviderContext* context3d_;
-  ResourceProviderContext* child_context_;
-  FakeOutputSurfaceClient output_surface_client_;
-  FakeOutputSurfaceClient child_output_surface_client_;
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<OutputSurface> child_output_surface_;
-  scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<ResourceProvider> child_resource_provider_;
-  scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
-};
-
-void CheckCreateResource(ResourceProvider::ResourceType expected_default_type,
-                         ResourceProvider* resource_provider,
-                         ResourceProviderContext* context) {
-  DCHECK_EQ(expected_default_type, resource_provider->default_resource_type());
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  EXPECT_EQ(1, static_cast<int>(resource_provider->num_resources()));
-  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    EXPECT_EQ(0u, context->NumTextures());
-
-  uint8_t data[4] = { 1, 2, 3, 4 };
-  resource_provider->CopyToResource(id, data, size);
-  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    EXPECT_EQ(1u, context->NumTextures());
-
-  uint8_t result[4] = { 0 };
-  GetResourcePixels(resource_provider, context, id, size, format, result);
-  EXPECT_EQ(0, memcmp(data, result, pixel_size));
-
-  resource_provider->DeleteResource(id);
-  EXPECT_EQ(0, static_cast<int>(resource_provider->num_resources()));
-  if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    EXPECT_EQ(0u, context->NumTextures());
-}
-
-TEST_P(ResourceProviderTest, Basic) {
-  CheckCreateResource(GetParam(), resource_provider_.get(), context());
-}
-
-TEST_P(ResourceProviderTest, Upload) {
-  gfx::Size size(2, 2);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(16U, pixel_size);
-
-  ResourceProvider::ResourceId id = resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  uint8_t image[16] = { 0 };
-  gfx::Rect image_rect(size);
-  resource_provider_->SetPixels(
-      id, image, image_rect, image_rect, gfx::Vector2d());
-
-  for (uint8_t i = 0; i < pixel_size; ++i)
-    image[i] = i;
-
-  uint8_t result[16] = { 0 };
-  {
-    gfx::Rect source_rect(0, 0, 1, 1);
-    gfx::Vector2d dest_offset(0, 0);
-    resource_provider_->SetPixels(
-        id, image, image_rect, source_rect, dest_offset);
-
-    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    GetResourcePixels(
-        resource_provider_.get(), context(), id, size, format, result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-  {
-    gfx::Rect source_rect(0, 0, 1, 1);
-    gfx::Vector2d dest_offset(1, 1);
-    resource_provider_->SetPixels(
-        id, image, image_rect, source_rect, dest_offset);
-
-    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
-    GetResourcePixels(
-        resource_provider_.get(), context(), id, size, format, result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-  {
-    gfx::Rect source_rect(1, 0, 1, 1);
-    gfx::Vector2d dest_offset(0, 1);
-    resource_provider_->SetPixels(
-        id, image, image_rect, source_rect, dest_offset);
-
-    uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3 };
-    GetResourcePixels(
-        resource_provider_.get(), context(), id, size, format, result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-  {
-    gfx::Rect offset_image_rect(gfx::Point(100, 100), size);
-    gfx::Rect source_rect(100, 100, 1, 1);
-    gfx::Vector2d dest_offset(1, 0);
-    resource_provider_->SetPixels(
-        id, image, offset_image_rect, source_rect, dest_offset);
-
-    uint8_t expected[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
-    GetResourcePixels(
-        resource_provider_.get(), context(), id, size, format, result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-
-  resource_provider_->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, SimpleUpload) {
-  gfx::Size size(2, 2);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(16U, pixel_size);
-
-  ResourceProvider::ResourceId id = resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  uint8_t image[16] = {0};
-  resource_provider_->CopyToResource(id, image, size);
-  {
-    uint8_t result[16] = {0};
-    uint8_t expected[16] = {0};
-    GetResourcePixels(resource_provider_.get(), context(), id, size, format,
-                      result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-
-  for (uint8_t i = 0; i < pixel_size; ++i)
-    image[i] = i;
-  resource_provider_->CopyToResource(id, image, size);
-  {
-    uint8_t result[16] = {0};
-    uint8_t expected[16] = {
-        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
-    GetResourcePixels(resource_provider_.get(), context(), id, size, format,
-                      result);
-    EXPECT_EQ(0, memcmp(expected, result, pixel_size));
-  }
-}
-
-TEST_P(ResourceProviderTest, TransferGLResources) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = { 1, 2, 3, 4 };
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data2[4] = { 5, 5, 5, 5 };
-  child_resource_provider_->CopyToResource(id2, data2, size);
-
-  ResourceProvider::ResourceId id3 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  {
-    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
-        child_resource_provider_.get(), id3);
-    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
-  }
-
-  GLuint external_texture_id = child_context_->createExternalTexture();
-
-  gpu::Mailbox external_mailbox;
-  child_context_->genMailboxCHROMIUM(external_mailbox.name);
-  child_context_->produceTextureDirectCHROMIUM(
-      external_texture_id, GL_TEXTURE_EXTERNAL_OES, external_mailbox.name);
-  const GLuint external_sync_point = child_context_->insertSyncPoint();
-  ResourceProvider::ResourceId id4 =
-      child_resource_provider_->CreateResourceFromTextureMailbox(
-          TextureMailbox(
-              external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point),
-          SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)));
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resources to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    resource_ids_to_transfer.push_back(id3);
-    resource_ids_to_transfer.push_back(id4);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(4u, list.size());
-    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    EXPECT_EQ(list[0].mailbox_holder.sync_point,
-              list[1].mailbox_holder.sync_point);
-    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
-    EXPECT_EQ(list[0].mailbox_holder.sync_point,
-              list[2].mailbox_holder.sync_point);
-    EXPECT_EQ(external_sync_point, list[3].mailbox_holder.sync_point);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[0].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[1].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[2].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
-              list[3].mailbox_holder.texture_target);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    EXPECT_NE(list[0].mailbox_holder.sync_point,
-              context3d_->last_waited_sync_point());
-    {
-      resource_provider_->WaitSyncPointIfNeeded(list[0].id);
-      ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
-                                              list[0].id);
-    }
-    EXPECT_EQ(list[0].mailbox_holder.sync_point,
-              context3d_->last_waited_sync_point());
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(4u, resource_provider_->num_resources());
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
-  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
-  ResourceProvider::ResourceId mapped_id4 = resource_map[id4];
-  EXPECT_NE(0u, mapped_id1);
-  EXPECT_NE(0u, mapped_id2);
-  EXPECT_NE(0u, mapped_id3);
-  EXPECT_NE(0u, mapped_id4);
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id4));
-
-  uint8_t result[4] = { 0 };
-  GetResourcePixels(
-      resource_provider_.get(), context(), mapped_id1, size, format, result);
-  EXPECT_EQ(0, memcmp(data1, result, pixel_size));
-
-  GetResourcePixels(
-      resource_provider_.get(), context(), mapped_id2, size, format, result);
-  EXPECT_EQ(0, memcmp(data2, result, pixel_size));
-
-  {
-    // Check that transfering again the same resource from the child to the
-    // parent works.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    resource_ids_to_transfer.push_back(id3);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(3u, list.size());
-    EXPECT_EQ(id1, list[0].id);
-    EXPECT_EQ(id2, list[1].id);
-    EXPECT_EQ(id3, list[2].id);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[0].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[1].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[2].mailbox_holder.texture_target);
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    child_resource_provider_->ReceiveReturnsFromParent(returned);
-    // ids were exported twice, we returned them only once, they should still
-    // be in-use.
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
-  }
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    ASSERT_EQ(4u, returned_to_child.size());
-    EXPECT_NE(0u, returned_to_child[0].sync_point);
-    EXPECT_NE(0u, returned_to_child[1].sync_point);
-    EXPECT_NE(0u, returned_to_child[2].sync_point);
-    EXPECT_NE(0u, returned_to_child[3].sync_point);
-    EXPECT_FALSE(returned_to_child[0].lost);
-    EXPECT_FALSE(returned_to_child[1].lost);
-    EXPECT_FALSE(returned_to_child[2].lost);
-    EXPECT_FALSE(returned_to_child[3].lost);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id4));
-
-  {
-    child_resource_provider_->WaitSyncPointIfNeeded(id1);
-    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
-                                            id1);
-    ASSERT_NE(0U, lock.texture_id());
-    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
-    child_context_->GetPixels(size, format, result);
-    EXPECT_EQ(0, memcmp(data1, result, pixel_size));
-  }
-  {
-    child_resource_provider_->WaitSyncPointIfNeeded(id2);
-    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
-                                            id2);
-    ASSERT_NE(0U, lock.texture_id());
-    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
-    child_context_->GetPixels(size, format, result);
-    EXPECT_EQ(0, memcmp(data2, result, pixel_size));
-  }
-  {
-    child_resource_provider_->WaitSyncPointIfNeeded(id3);
-    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
-                                            id3);
-    ASSERT_NE(0U, lock.texture_id());
-    child_context_->bindTexture(GL_TEXTURE_2D, lock.texture_id());
-  }
-  {
-    // Transfer resources to the parent again.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    resource_ids_to_transfer.push_back(id3);
-    resource_ids_to_transfer.push_back(id4);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(4u, list.size());
-    EXPECT_EQ(id1, list[0].id);
-    EXPECT_EQ(id2, list[1].id);
-    EXPECT_EQ(id3, list[2].id);
-    EXPECT_EQ(id4, list[3].id);
-    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-    EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    EXPECT_NE(0u, list[2].mailbox_holder.sync_point);
-    EXPECT_NE(0u, list[3].mailbox_holder.sync_point);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[0].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[1].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[2].mailbox_holder.texture_target);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES),
-              list[3].mailbox_holder.texture_target);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id4));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(0u, returned_to_child.size());
-
-  EXPECT_EQ(4u, resource_provider_->num_resources());
-  resource_provider_->DestroyChild(child_id);
-  EXPECT_EQ(0u, resource_provider_->num_resources());
-
-  ASSERT_EQ(4u, returned_to_child.size());
-  EXPECT_NE(0u, returned_to_child[0].sync_point);
-  EXPECT_NE(0u, returned_to_child[1].sync_point);
-  EXPECT_NE(0u, returned_to_child[2].sync_point);
-  EXPECT_NE(0u, returned_to_child[3].sync_point);
-  EXPECT_FALSE(returned_to_child[0].lost);
-  EXPECT_FALSE(returned_to_child[1].lost);
-  EXPECT_FALSE(returned_to_child[2].lost);
-  EXPECT_FALSE(returned_to_child[3].lost);
-}
-
-TEST_P(ResourceProviderTest, ReadLockCountStopsReturnToChildOrDelete) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = {1, 2, 3, 4};
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resources to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(1u, list.size());
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-
-    resource_provider_->ReceiveFromChild(child_id, list);
-
-    resource_provider_->WaitSyncPointIfNeeded(list[0].id);
-    ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(),
-                                            list[0].id);
-
-    resource_provider_->DeclareUsedResourcesFromChild(
-        child_id, ResourceProvider::ResourceIdArray());
-    EXPECT_EQ(0u, returned_to_child.size());
-  }
-
-  EXPECT_EQ(1u, returned_to_child.size());
-  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-
-  {
-    child_resource_provider_->WaitSyncPointIfNeeded(id1);
-    ResourceProvider::ScopedReadLockGL lock(child_resource_provider_.get(),
-                                            id1);
-    child_resource_provider_->DeleteResource(id1);
-    EXPECT_EQ(1u, child_resource_provider_->num_resources());
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-  }
-
-  EXPECT_EQ(0u, child_resource_provider_->num_resources());
-  resource_provider_->DestroyChild(child_id);
-}
-
-TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) {
-  // Overlays only supported on the GL path.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  uint32 sync_point = 0;
-  TextureMailbox mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
-  mailbox.set_allow_overlay(true);
-  scoped_ptr<SingleReleaseCallbackImpl> release_callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-  ResourceProvider::ResourceId id1 =
-      child_resource_provider_->CreateResourceFromTextureMailbox(
-          mailbox, release_callback.Pass());
-
-  TextureMailbox mailbox2(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point);
-  mailbox2.set_allow_overlay(false);
-  scoped_ptr<SingleReleaseCallbackImpl> release_callback2 =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-  ResourceProvider::ResourceId id2 =
-      child_resource_provider_->CreateResourceFromTextureMailbox(
-          mailbox2, release_callback2.Pass());
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-
-  // Transfer some resources to the parent.
-  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(id1);
-  resource_ids_to_transfer.push_back(id2);
-  TransferableResourceArray list;
-  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                &list);
-  ASSERT_EQ(2u, list.size());
-  resource_provider_->ReceiveFromChild(child_id, list);
-  EXPECT_TRUE(resource_provider_->AllowOverlay(list[0].id));
-  EXPECT_FALSE(resource_provider_->AllowOverlay(list[1].id));
-
-  resource_provider_->DeclareUsedResourcesFromChild(
-      child_id, ResourceProvider::ResourceIdArray());
-
-  EXPECT_EQ(2u, returned_to_child.size());
-  child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-
-  child_resource_provider_->DeleteResource(id1);
-  child_resource_provider_->DeleteResource(id2);
-  EXPECT_EQ(0u, child_resource_provider_->num_resources());
-
-  resource_provider_->DestroyChild(child_id);
-}
-
-TEST_P(ResourceProviderTest, TransferSoftwareResources) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
-    return;
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = { 1, 2, 3, 4 };
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data2[4] = { 5, 5, 5, 5 };
-  child_resource_provider_->CopyToResource(id2, data2, size);
-
-  scoped_ptr<SharedBitmap> shared_bitmap(CreateAndFillSharedBitmap(
-      shared_bitmap_manager_.get(), gfx::Size(1, 1), 0));
-  SharedBitmap* shared_bitmap_ptr = shared_bitmap.get();
-  ResourceProvider::ResourceId id3 =
-      child_resource_provider_->CreateResourceFromTextureMailbox(
-          TextureMailbox(shared_bitmap_ptr, gfx::Size(1, 1)),
-          SingleReleaseCallbackImpl::Create(base::Bind(
-              &SharedBitmapReleaseCallback, base::Passed(&shared_bitmap))));
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resources to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    resource_ids_to_transfer.push_back(id3);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(3u, list.size());
-    EXPECT_EQ(0u, list[0].mailbox_holder.sync_point);
-    EXPECT_EQ(0u, list[1].mailbox_holder.sync_point);
-    EXPECT_EQ(0u, list[2].mailbox_holder.sync_point);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(3u, resource_provider_->num_resources());
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
-  ResourceProvider::ResourceId mapped_id3 = resource_map[id3];
-  EXPECT_NE(0u, mapped_id1);
-  EXPECT_NE(0u, mapped_id2);
-  EXPECT_NE(0u, mapped_id3);
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id3));
-
-  uint8_t result[4] = { 0 };
-  GetResourcePixels(
-      resource_provider_.get(), context(), mapped_id1, size, format, result);
-  EXPECT_EQ(0, memcmp(data1, result, pixel_size));
-
-  GetResourcePixels(
-      resource_provider_.get(), context(), mapped_id2, size, format, result);
-  EXPECT_EQ(0, memcmp(data2, result, pixel_size));
-
-  {
-    // Check that transfering again the same resource from the child to the
-    // parent works.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(2u, list.size());
-    EXPECT_EQ(id1, list[0].id);
-    EXPECT_EQ(id2, list[1].id);
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    child_resource_provider_->ReceiveReturnsFromParent(returned);
-    // ids were exported twice, we returned them only once, they should still
-    // be in-use.
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-  }
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    ASSERT_EQ(3u, returned_to_child.size());
-    EXPECT_EQ(0u, returned_to_child[0].sync_point);
-    EXPECT_EQ(0u, returned_to_child[1].sync_point);
-    EXPECT_EQ(0u, returned_to_child[2].sync_point);
-    std::set<ResourceProvider::ResourceId> expected_ids;
-    expected_ids.insert(id1);
-    expected_ids.insert(id2);
-    expected_ids.insert(id3);
-    std::set<ResourceProvider::ResourceId> returned_ids;
-    for (unsigned i = 0; i < 3; i++)
-      returned_ids.insert(returned_to_child[i].id);
-    EXPECT_EQ(expected_ids, returned_ids);
-    EXPECT_FALSE(returned_to_child[0].lost);
-    EXPECT_FALSE(returned_to_child[1].lost);
-    EXPECT_FALSE(returned_to_child[2].lost);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id2));
-  EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id3));
-
-  {
-    ResourceProvider::ScopedReadLockSoftware lock(
-        child_resource_provider_.get(), id1);
-    const SkBitmap* sk_bitmap = lock.sk_bitmap();
-    EXPECT_EQ(sk_bitmap->width(), size.width());
-    EXPECT_EQ(sk_bitmap->height(), size.height());
-    EXPECT_EQ(0, memcmp(data1, sk_bitmap->getPixels(), pixel_size));
-  }
-  {
-    ResourceProvider::ScopedReadLockSoftware lock(
-        child_resource_provider_.get(), id2);
-    const SkBitmap* sk_bitmap = lock.sk_bitmap();
-    EXPECT_EQ(sk_bitmap->width(), size.width());
-    EXPECT_EQ(sk_bitmap->height(), size.height());
-    EXPECT_EQ(0, memcmp(data2, sk_bitmap->getPixels(), pixel_size));
-  }
-  {
-    // Transfer resources to the parent again.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    resource_ids_to_transfer.push_back(id3);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(3u, list.size());
-    EXPECT_EQ(id1, list[0].id);
-    EXPECT_EQ(id2, list[1].id);
-    EXPECT_EQ(id3, list[2].id);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id3));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(0u, returned_to_child.size());
-
-  EXPECT_EQ(3u, resource_provider_->num_resources());
-  resource_provider_->DestroyChild(child_id);
-  EXPECT_EQ(0u, resource_provider_->num_resources());
-
-  ASSERT_EQ(3u, returned_to_child.size());
-  EXPECT_EQ(0u, returned_to_child[0].sync_point);
-  EXPECT_EQ(0u, returned_to_child[1].sync_point);
-  EXPECT_EQ(0u, returned_to_child[2].sync_point);
-  std::set<ResourceProvider::ResourceId> expected_ids;
-  expected_ids.insert(id1);
-  expected_ids.insert(id2);
-  expected_ids.insert(id3);
-  std::set<ResourceProvider::ResourceId> returned_ids;
-  for (unsigned i = 0; i < 3; i++)
-    returned_ids.insert(returned_to_child[i].id);
-  EXPECT_EQ(expected_ids, returned_ids);
-  EXPECT_FALSE(returned_to_child[0].lost);
-  EXPECT_FALSE(returned_to_child[1].lost);
-  EXPECT_FALSE(returned_to_child[2].lost);
-}
-
-TEST_P(ResourceProviderTest, TransferGLToSoftware) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
-    return;
-
-  scoped_ptr<ResourceProviderContext> child_context_owned(
-      ResourceProviderContext::Create(shared_data_.get()));
-
-  FakeOutputSurfaceClient child_output_surface_client;
-  scoped_ptr<OutputSurface> child_output_surface(
-      FakeOutputSurface::Create3d(child_context_owned.Pass()));
-  CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-
-  scoped_ptr<ResourceProvider> child_resource_provider(
-      ResourceProvider::Create(child_output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = { 1, 2, 3, 4 };
-  child_resource_provider->CopyToResource(id1, data1, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    TransferableResourceArray list;
-    child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
-                                                 &list);
-    ASSERT_EQ(1u, list.size());
-    EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-    EXPECT_EQ(static_cast<GLenum>(GL_TEXTURE_2D),
-              list[0].mailbox_holder.texture_target);
-    EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
-    resource_provider_->ReceiveFromChild(child_id, list);
-  }
-
-  EXPECT_EQ(0u, resource_provider_->num_resources());
-  ASSERT_EQ(1u, returned_to_child.size());
-  EXPECT_EQ(returned_to_child[0].id, id1);
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  EXPECT_EQ(0u, mapped_id1);
-
-  resource_provider_->DestroyChild(child_id);
-  EXPECT_EQ(0u, resource_provider_->num_resources());
-
-  ASSERT_EQ(1u, returned_to_child.size());
-  EXPECT_FALSE(returned_to_child[0].lost);
-}
-
-TEST_P(ResourceProviderTest, TransferInvalidSoftware) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
-    return;
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = { 1, 2, 3, 4 };
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(1u, list.size());
-    // Make invalid.
-    list[0].mailbox_holder.mailbox.name[1] = 5;
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    resource_provider_->ReceiveFromChild(child_id, list);
-  }
-
-  EXPECT_EQ(1u, resource_provider_->num_resources());
-  EXPECT_EQ(0u, returned_to_child.size());
-
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  EXPECT_NE(0u, mapped_id1);
-  {
-    ResourceProvider::ScopedReadLockSoftware lock(resource_provider_.get(),
-                                                  mapped_id1);
-    EXPECT_FALSE(lock.valid());
-  }
-
-  resource_provider_->DestroyChild(child_id);
-  EXPECT_EQ(0u, resource_provider_->num_resources());
-
-  ASSERT_EQ(1u, returned_to_child.size());
-  EXPECT_FALSE(returned_to_child[0].lost);
-}
-
-TEST_P(ResourceProviderTest, DeleteExportedResources) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = { 1, 2, 3, 4 };
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data2[4] = {5, 5, 5, 5};
-  child_resource_provider_->CopyToResource(id2, data2, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resources to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(2u, list.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    }
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(2u, resource_provider_->num_resources());
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
-  EXPECT_NE(0u, mapped_id1);
-  EXPECT_NE(0u, mapped_id2);
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
-
-  {
-    // The parent transfers the resources to the grandparent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(mapped_id1);
-    resource_ids_to_transfer.push_back(mapped_id2);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-
-    ASSERT_EQ(2u, list.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    }
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
-
-    // Release the resource in the parent. Set no resources as being in use. The
-    // resources are exported so that can't be transferred back yet.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    EXPECT_EQ(0u, returned_to_child.size());
-    EXPECT_EQ(2u, resource_provider_->num_resources());
-
-    // Return the resources from the grandparent to the parent. They should be
-    // returned to the child then.
-    EXPECT_EQ(2u, list.size());
-    EXPECT_EQ(mapped_id1, list[0].id);
-    EXPECT_EQ(mapped_id2, list[1].id);
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-
-    EXPECT_EQ(0u, resource_provider_->num_resources());
-    ASSERT_EQ(2u, returned_to_child.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, returned_to_child[0].sync_point);
-      EXPECT_NE(0u, returned_to_child[1].sync_point);
-    }
-    EXPECT_FALSE(returned_to_child[0].lost);
-    EXPECT_FALSE(returned_to_child[1].lost);
-  }
-}
-
-TEST_P(ResourceProviderTest, DestroyChildWithExportedResources) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data1[4] = {1, 2, 3, 4};
-  child_resource_provider_->CopyToResource(id1, data1, size);
-
-  ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data2[4] = {5, 5, 5, 5};
-  child_resource_provider_->CopyToResource(id2, data2, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resources to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id1);
-    resource_ids_to_transfer.push_back(id2);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(2u, list.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    }
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id2));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  EXPECT_EQ(2u, resource_provider_->num_resources());
-  ResourceProvider::ResourceIdMap resource_map =
-      resource_provider_->GetChildToParentMap(child_id);
-  ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
-  ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
-  EXPECT_NE(0u, mapped_id1);
-  EXPECT_NE(0u, mapped_id2);
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
-  EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
-
-  {
-    // The parent transfers the resources to the grandparent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(mapped_id1);
-    resource_ids_to_transfer.push_back(mapped_id2);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-
-    ASSERT_EQ(2u, list.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-      EXPECT_NE(0u, list[1].mailbox_holder.sync_point);
-    }
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(id1));
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(id2));
-
-    // Release the resource in the parent. Set no resources as being in use. The
-    // resources are exported so that can't be transferred back yet.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    // Destroy the child, the resources should not be returned yet.
-    EXPECT_EQ(0u, returned_to_child.size());
-    EXPECT_EQ(2u, resource_provider_->num_resources());
-
-    resource_provider_->DestroyChild(child_id);
-
-    EXPECT_EQ(2u, resource_provider_->num_resources());
-    ASSERT_EQ(0u, returned_to_child.size());
-
-    // Return a resource from the grandparent, it should be returned at this
-    // point.
-    EXPECT_EQ(2u, list.size());
-    EXPECT_EQ(mapped_id1, list[0].id);
-    EXPECT_EQ(mapped_id2, list[1].id);
-    TransferableResourceArray return_list;
-    return_list.push_back(list[1]);
-    list.pop_back();
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(return_list, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-
-    EXPECT_EQ(1u, resource_provider_->num_resources());
-    ASSERT_EQ(1u, returned_to_child.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, returned_to_child[0].sync_point);
-    }
-    EXPECT_FALSE(returned_to_child[0].lost);
-    returned_to_child.clear();
-
-    // Destroy the parent resource provider. The resource that's left should be
-    // lost at this point, and returned.
-    resource_provider_ = nullptr;
-    ASSERT_EQ(1u, returned_to_child.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-      EXPECT_NE(0u, returned_to_child[0].sync_point);
-    }
-    EXPECT_TRUE(returned_to_child[0].lost);
-  }
-}
-
-TEST_P(ResourceProviderTest, DeleteTransferredResources) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data[4] = { 1, 2, 3, 4 };
-  child_resource_provider_->CopyToResource(id, data, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer some resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    ASSERT_EQ(1u, list.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-      EXPECT_NE(0u, list[0].mailbox_holder.sync_point);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  // Delete textures in the child, while they are transfered.
-  child_resource_provider_->DeleteResource(id);
-  EXPECT_EQ(1u, child_resource_provider_->num_resources());
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    ASSERT_EQ(1u, returned_to_child.size());
-    if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-      EXPECT_NE(0u, returned_to_child[0].sync_point);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-  }
-  EXPECT_EQ(0u, child_resource_provider_->num_resources());
-}
-
-TEST_P(ResourceProviderTest, UnuseTransferredResources) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  size_t pixel_size = TextureSizeBytes(size, format);
-  ASSERT_EQ(4U, pixel_size);
-
-  ResourceProvider::ResourceId id = child_resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  uint8_t data[4] = {1, 2, 3, 4};
-  child_resource_provider_->CopyToResource(id, data, size);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  const ResourceProvider::ResourceIdMap& map =
-      resource_provider_->GetChildToParentMap(child_id);
-  {
-    // Transfer some resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-  TransferableResourceArray sent_to_top_level;
-  {
-    // Parent transfers to top-level.
-    ASSERT_TRUE(map.find(id) != map.end());
-    ResourceProvider::ResourceId parent_id = map.find(id)->second;
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(parent_id);
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                            &sent_to_top_level);
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
-  }
-  {
-    // Stop using resource.
-    ResourceProvider::ResourceIdArray empty;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
-    // Resource is not yet returned to the child, since it's in use by the
-    // top-level.
-    EXPECT_TRUE(returned_to_child.empty());
-  }
-  {
-    // Send the resource to the parent again.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(id);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id));
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-  {
-    // Receive returns back from top-level.
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(sent_to_top_level, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-    // Resource is still not yet returned to the child, since it's declared used
-    // in the parent.
-    EXPECT_TRUE(returned_to_child.empty());
-    ASSERT_TRUE(map.find(id) != map.end());
-    ResourceProvider::ResourceId parent_id = map.find(id)->second;
-    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
-  }
-  {
-    sent_to_top_level.clear();
-    // Parent transfers again to top-level.
-    ASSERT_TRUE(map.find(id) != map.end());
-    ResourceProvider::ResourceId parent_id = map.find(id)->second;
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(parent_id);
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                            &sent_to_top_level);
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_id));
-  }
-  {
-    // Receive returns back from top-level.
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(sent_to_top_level, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-    // Resource is still not yet returned to the child, since it's still
-    // declared used in the parent.
-    EXPECT_TRUE(returned_to_child.empty());
-    ASSERT_TRUE(map.find(id) != map.end());
-    ResourceProvider::ResourceId parent_id = map.find(id)->second;
-    EXPECT_FALSE(resource_provider_->InUseByConsumer(parent_id));
-  }
-  {
-    // Stop using resource.
-    ResourceProvider::ResourceIdArray empty;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, empty);
-    // Resource should have been returned to the child, since it's no longer in
-    // use by the top-level.
-    ASSERT_EQ(1u, returned_to_child.size());
-    EXPECT_EQ(id, returned_to_child[0].id);
-    EXPECT_EQ(2, returned_to_child[0].count);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-    EXPECT_FALSE(child_resource_provider_->InUseByConsumer(id));
-  }
-}
-
-class ResourceProviderTestTextureFilters : public ResourceProviderTest {
- public:
-  static void RunTest(GLenum child_filter, GLenum parent_filter) {
-    scoped_ptr<TextureStateTrackingContext> child_context_owned(
-        new TextureStateTrackingContext);
-    TextureStateTrackingContext* child_context = child_context_owned.get();
-
-    FakeOutputSurfaceClient child_output_surface_client;
-    scoped_ptr<OutputSurface> child_output_surface(
-        FakeOutputSurface::Create3d(child_context_owned.Pass()));
-    CHECK(child_output_surface->BindToClient(&child_output_surface_client));
-    scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-        new TestSharedBitmapManager());
-
-    scoped_ptr<ResourceProvider> child_resource_provider(
-        ResourceProvider::Create(child_output_surface.get(),
-                                 shared_bitmap_manager.get(),
-                                 NULL,
-                                 NULL,
-                                 0,
-                                 false,
-                                 1));
-
-    scoped_ptr<TextureStateTrackingContext> parent_context_owned(
-        new TextureStateTrackingContext);
-    TextureStateTrackingContext* parent_context = parent_context_owned.get();
-
-    FakeOutputSurfaceClient parent_output_surface_client;
-    scoped_ptr<OutputSurface> parent_output_surface(
-        FakeOutputSurface::Create3d(parent_context_owned.Pass()));
-    CHECK(parent_output_surface->BindToClient(&parent_output_surface_client));
-
-    scoped_ptr<ResourceProvider> parent_resource_provider(
-        ResourceProvider::Create(parent_output_surface.get(),
-                                 shared_bitmap_manager.get(),
-                                 NULL,
-                                 NULL,
-                                 0,
-                                 false,
-                                 1));
-
-    gfx::Size size(1, 1);
-    ResourceFormat format = RGBA_8888;
-    int child_texture_id = 1;
-    int parent_texture_id = 2;
-
-    size_t pixel_size = TextureSizeBytes(size, format);
-    ASSERT_EQ(4U, pixel_size);
-
-    ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
-        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-        format);
-
-    // The new texture is created with GL_LINEAR.
-    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id))
-        .Times(2);  // Once to create and once to allocate.
-    EXPECT_CALL(*child_context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    EXPECT_CALL(*child_context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    EXPECT_CALL(
-        *child_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-    EXPECT_CALL(
-        *child_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-    EXPECT_CALL(*child_context,
-                texParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_POOL_CHROMIUM,
-                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
-    child_resource_provider->AllocateForTesting(id);
-    Mock::VerifyAndClearExpectations(child_context);
-
-    uint8_t data[4] = { 1, 2, 3, 4 };
-
-    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
-    child_resource_provider->CopyToResource(id, data, size);
-    Mock::VerifyAndClearExpectations(child_context);
-
-    // The texture is set to |child_filter| in the child.
-    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
-    if (child_filter != GL_LINEAR) {
-      EXPECT_CALL(
-          *child_context,
-          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
-      EXPECT_CALL(
-          *child_context,
-          texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));
-    }
-    SetResourceFilter(child_resource_provider.get(), id, child_filter);
-    Mock::VerifyAndClearExpectations(child_context);
-
-    ReturnedResourceArray returned_to_child;
-    int child_id = parent_resource_provider->CreateChild(
-        GetReturnCallback(&returned_to_child));
-    {
-      // Transfer some resource to the parent.
-      ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-      resource_ids_to_transfer.push_back(id);
-      TransferableResourceArray list;
-
-      EXPECT_CALL(*child_context,
-                  produceTextureDirectCHROMIUM(_, GL_TEXTURE_2D, _));
-      EXPECT_CALL(*child_context, insertSyncPoint());
-      child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
-                                                   &list);
-      Mock::VerifyAndClearExpectations(child_context);
-
-      ASSERT_EQ(1u, list.size());
-      EXPECT_EQ(static_cast<unsigned>(child_filter), list[0].filter);
-
-      EXPECT_CALL(*parent_context,
-                  createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, _))
-          .WillOnce(Return(parent_texture_id));
-
-      parent_resource_provider->ReceiveFromChild(child_id, list);
-      {
-        parent_resource_provider->WaitSyncPointIfNeeded(list[0].id);
-        ResourceProvider::ScopedReadLockGL lock(parent_resource_provider.get(),
-                                                list[0].id);
-      }
-      Mock::VerifyAndClearExpectations(parent_context);
-
-      parent_resource_provider->DeclareUsedResourcesFromChild(
-          child_id, resource_ids_to_transfer);
-      Mock::VerifyAndClearExpectations(parent_context);
-    }
-    ResourceProvider::ResourceIdMap resource_map =
-        parent_resource_provider->GetChildToParentMap(child_id);
-    ResourceProvider::ResourceId mapped_id = resource_map[id];
-    EXPECT_NE(0u, mapped_id);
-
-    // The texture is set to |parent_filter| in the parent.
-    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
-    EXPECT_CALL(
-        *parent_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, parent_filter));
-    EXPECT_CALL(
-        *parent_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, parent_filter));
-    SetResourceFilter(parent_resource_provider.get(), mapped_id, parent_filter);
-    Mock::VerifyAndClearExpectations(parent_context);
-
-    // The texture should be reset to |child_filter| in the parent when it is
-    // returned, since that is how it was received.
-    EXPECT_CALL(*parent_context, bindTexture(GL_TEXTURE_2D, parent_texture_id));
-    EXPECT_CALL(
-        *parent_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, child_filter));
-    EXPECT_CALL(
-        *parent_context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, child_filter));
-
-    {
-      EXPECT_EQ(0u, returned_to_child.size());
-
-      // Transfer resources back from the parent to the child. Set no resources
-      // as being in use.
-      ResourceProvider::ResourceIdArray no_resources;
-      EXPECT_CALL(*parent_context, insertSyncPoint());
-      parent_resource_provider->DeclareUsedResourcesFromChild(child_id,
-                                                              no_resources);
-      Mock::VerifyAndClearExpectations(parent_context);
-
-      ASSERT_EQ(1u, returned_to_child.size());
-      child_resource_provider->ReceiveReturnsFromParent(returned_to_child);
-    }
-
-    // The child remembers the texture filter is set to |child_filter|.
-    EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id));
-    SetResourceFilter(child_resource_provider.get(), id, child_filter);
-    Mock::VerifyAndClearExpectations(child_context);
-  }
-};
-
-TEST_P(ResourceProviderTest, TextureFilters_ChildNearestParentLinear) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  ResourceProviderTestTextureFilters::RunTest(GL_NEAREST, GL_LINEAR);
-}
-
-TEST_P(ResourceProviderTest, TextureFilters_ChildLinearParentNearest) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  ResourceProviderTestTextureFilters::RunTest(GL_LINEAR, GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, TransferMailboxResources) {
-  // Other mailbox transfers tested elsewhere.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  unsigned texture = context()->createTexture();
-  context()->bindTexture(GL_TEXTURE_2D, texture);
-  uint8_t data[4] = { 1, 2, 3, 4 };
-  context()->texImage2D(
-      GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
-  gpu::Mailbox mailbox;
-  context()->genMailboxCHROMIUM(mailbox.name);
-  context()->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D, mailbox.name);
-  uint32 sync_point = context()->insertSyncPoint();
-
-  // All the logic below assumes that the sync points are all positive.
-  EXPECT_LT(0u, sync_point);
-
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  BlockingTaskRunner* main_thread_task_runner = NULL;
-  ReleaseCallbackImpl callback = base::Bind(ReleaseCallback,
-                                            &release_sync_point,
-                                            &lost_resource,
-                                            &main_thread_task_runner);
-  ResourceProvider::ResourceId resource =
-      resource_provider_->CreateResourceFromTextureMailbox(
-          TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
-          SingleReleaseCallbackImpl::Create(callback));
-  EXPECT_EQ(1u, context()->NumTextures());
-  EXPECT_EQ(0u, release_sync_point);
-  {
-    // Transfer the resource, expect the sync points to be consistent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-    ASSERT_EQ(1u, list.size());
-    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
-    EXPECT_EQ(0,
-              memcmp(mailbox.name,
-                     list[0].mailbox_holder.mailbox.name,
-                     sizeof(mailbox.name)));
-    EXPECT_EQ(0u, release_sync_point);
-
-    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
-    unsigned other_texture =
-        context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
-    uint8_t test_data[4] = { 0 };
-    context()->GetPixels(
-        gfx::Size(1, 1), RGBA_8888, test_data);
-    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
-
-    context()->produceTextureDirectCHROMIUM(other_texture, GL_TEXTURE_2D,
-                                            mailbox.name);
-    context()->deleteTexture(other_texture);
-    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
-    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);
-
-    // Receive the resource, then delete it, expect the sync points to be
-    // consistent.
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-    EXPECT_EQ(1u, context()->NumTextures());
-    EXPECT_EQ(0u, release_sync_point);
-
-    resource_provider_->DeleteResource(resource);
-    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
-    EXPECT_FALSE(lost_resource);
-    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
-  }
-
-  // We're going to do the same thing as above, but testing the case where we
-  // delete the resource before we receive it back.
-  sync_point = release_sync_point;
-  EXPECT_LT(0u, sync_point);
-  release_sync_point = 0;
-  resource = resource_provider_->CreateResourceFromTextureMailbox(
-      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point),
-      SingleReleaseCallbackImpl::Create(callback));
-  EXPECT_EQ(1u, context()->NumTextures());
-  EXPECT_EQ(0u, release_sync_point);
-  {
-    // Transfer the resource, expect the sync points to be consistent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-    ASSERT_EQ(1u, list.size());
-    EXPECT_LE(sync_point, list[0].mailbox_holder.sync_point);
-    EXPECT_EQ(0,
-              memcmp(mailbox.name,
-                     list[0].mailbox_holder.mailbox.name,
-                     sizeof(mailbox.name)));
-    EXPECT_EQ(0u, release_sync_point);
-
-    context()->waitSyncPoint(list[0].mailbox_holder.sync_point);
-    unsigned other_texture =
-        context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
-    uint8_t test_data[4] = { 0 };
-    context()->GetPixels(
-        gfx::Size(1, 1), RGBA_8888, test_data);
-    EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
-
-    context()->produceTextureDirectCHROMIUM(other_texture, GL_TEXTURE_2D,
-                                            mailbox.name);
-    context()->deleteTexture(other_texture);
-    list[0].mailbox_holder.sync_point = context()->insertSyncPoint();
-    EXPECT_LT(0u, list[0].mailbox_holder.sync_point);
-
-    // Delete the resource, which shouldn't do anything.
-    resource_provider_->DeleteResource(resource);
-    EXPECT_EQ(1u, context()->NumTextures());
-    EXPECT_EQ(0u, release_sync_point);
-
-    // Then receive the resource which should release the mailbox, expect the
-    // sync points to be consistent.
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    resource_provider_->ReceiveReturnsFromParent(returned);
-    EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point);
-    EXPECT_FALSE(lost_resource);
-    EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
-  }
-
-  context()->waitSyncPoint(release_sync_point);
-  texture =
-      context()->createAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
-  context()->deleteTexture(texture);
-}
-
-TEST_P(ResourceProviderTest, LostResourceInParent) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId resource =
-      child_resource_provider_->CreateResource(
-          size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-          format);
-  child_resource_provider_->AllocateForTesting(resource);
-  // Expect a GL resource to be lost.
-  bool should_lose_resource =
-      GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE;
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer the resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(1u, list.size());
-
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  // Lose the output surface in the parent.
-  resource_provider_->DidLoseOutputSurface();
-
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    // Expect a GL resource to be lost.
-    ASSERT_EQ(1u, returned_to_child.size());
-    EXPECT_EQ(should_lose_resource, returned_to_child[0].lost);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-
-  // A GL resource should be lost.
-  EXPECT_EQ(should_lose_resource, child_resource_provider_->IsLost(resource));
-
-  // Lost resources stay in use in the parent forever.
-  EXPECT_EQ(should_lose_resource,
-            child_resource_provider_->InUseByConsumer(resource));
-}
-
-TEST_P(ResourceProviderTest, LostResourceInGrandParent) {
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId resource =
-      child_resource_provider_->CreateResource(
-          size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-          format);
-  child_resource_provider_->AllocateForTesting(resource);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer the resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(1u, list.size());
-
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  {
-    ResourceProvider::ResourceIdMap resource_map =
-        resource_provider_->GetChildToParentMap(child_id);
-    ResourceProvider::ResourceId parent_resource = resource_map[resource];
-    EXPECT_NE(0u, parent_resource);
-
-    // Transfer to a grandparent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(parent_resource);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-
-    // Receive back a lost resource from the grandparent.
-    EXPECT_EQ(1u, list.size());
-    EXPECT_EQ(parent_resource, list[0].id);
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    EXPECT_EQ(1u, returned.size());
-    EXPECT_EQ(parent_resource, returned[0].id);
-    returned[0].lost = true;
-    resource_provider_->ReceiveReturnsFromParent(returned);
-
-    // The resource should be lost.
-    EXPECT_TRUE(resource_provider_->IsLost(parent_resource));
-
-    // Lost resources stay in use in the parent forever.
-    EXPECT_TRUE(resource_provider_->InUseByConsumer(parent_resource));
-  }
-
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    // Expect the resource to be lost.
-    ASSERT_EQ(1u, returned_to_child.size());
-    EXPECT_TRUE(returned_to_child[0].lost);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-
-  // The resource should be lost.
-  EXPECT_TRUE(child_resource_provider_->IsLost(resource));
-
-  // Lost resources stay in use in the parent forever.
-  EXPECT_TRUE(child_resource_provider_->InUseByConsumer(resource));
-}
-
-TEST_P(ResourceProviderTest, LostMailboxInParent) {
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  bool release_called = false;
-  uint32 sync_point = 0;
-  ResourceProvider::ResourceId resource = CreateChildMailbox(
-      &release_sync_point, &lost_resource, &release_called, &sync_point);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer the resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(1u, list.size());
-
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  // Lose the output surface in the parent.
-  resource_provider_->DidLoseOutputSurface();
-
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    ASSERT_EQ(1u, returned_to_child.size());
-    // Losing an output surface only loses hardware resources.
-    EXPECT_EQ(returned_to_child[0].lost,
-              GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-
-  // Delete the resource in the child. Expect the resource to be lost if it's
-  // a GL texture.
-  child_resource_provider_->DeleteResource(resource);
-  EXPECT_EQ(lost_resource,
-            GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE);
-}
-
-TEST_P(ResourceProviderTest, LostMailboxInGrandParent) {
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  bool release_called = false;
-  uint32 sync_point = 0;
-  ResourceProvider::ResourceId resource = CreateChildMailbox(
-      &release_sync_point, &lost_resource, &release_called, &sync_point);
-
-  ReturnedResourceArray returned_to_child;
-  int child_id =
-      resource_provider_->CreateChild(GetReturnCallback(&returned_to_child));
-  {
-    // Transfer the resource to the parent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(resource);
-    TransferableResourceArray list;
-    child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                  &list);
-    EXPECT_EQ(1u, list.size());
-
-    resource_provider_->ReceiveFromChild(child_id, list);
-    resource_provider_->DeclareUsedResourcesFromChild(child_id,
-                                                      resource_ids_to_transfer);
-  }
-
-  {
-    ResourceProvider::ResourceIdMap resource_map =
-        resource_provider_->GetChildToParentMap(child_id);
-    ResourceProvider::ResourceId parent_resource = resource_map[resource];
-    EXPECT_NE(0u, parent_resource);
-
-    // Transfer to a grandparent.
-    ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-    resource_ids_to_transfer.push_back(parent_resource);
-    TransferableResourceArray list;
-    resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
-
-    // Receive back a lost resource from the grandparent.
-    EXPECT_EQ(1u, list.size());
-    EXPECT_EQ(parent_resource, list[0].id);
-    ReturnedResourceArray returned;
-    TransferableResource::ReturnResources(list, &returned);
-    EXPECT_EQ(1u, returned.size());
-    EXPECT_EQ(parent_resource, returned[0].id);
-    returned[0].lost = true;
-    resource_provider_->ReceiveReturnsFromParent(returned);
-  }
-
-  {
-    EXPECT_EQ(0u, returned_to_child.size());
-
-    // Transfer resources back from the parent to the child. Set no resources as
-    // being in use.
-    ResourceProvider::ResourceIdArray no_resources;
-    resource_provider_->DeclareUsedResourcesFromChild(child_id, no_resources);
-
-    // Expect the resource to be lost.
-    ASSERT_EQ(1u, returned_to_child.size());
-    EXPECT_TRUE(returned_to_child[0].lost);
-    child_resource_provider_->ReceiveReturnsFromParent(returned_to_child);
-    returned_to_child.clear();
-  }
-
-  // Delete the resource in the child. Expect the resource to be lost.
-  child_resource_provider_->DeleteResource(resource);
-  EXPECT_TRUE(lost_resource);
-}
-
-TEST_P(ResourceProviderTest, Shutdown) {
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  bool release_called = false;
-  uint32 sync_point = 0;
-  CreateChildMailbox(
-      &release_sync_point, &lost_resource, &release_called, &sync_point);
-
-  EXPECT_EQ(0u, release_sync_point);
-  EXPECT_FALSE(lost_resource);
-
-  child_resource_provider_ = nullptr;
-
-  if (GetParam() == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) {
-    EXPECT_LE(sync_point, release_sync_point);
-  }
-  EXPECT_TRUE(release_called);
-  EXPECT_FALSE(lost_resource);
-}
-
-TEST_P(ResourceProviderTest, ShutdownWithExportedResource) {
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  bool release_called = false;
-  uint32 sync_point = 0;
-  ResourceProvider::ResourceId resource = CreateChildMailbox(
-      &release_sync_point, &lost_resource, &release_called, &sync_point);
-
-  // Transfer the resource, so we can't release it properly on shutdown.
-  ResourceProvider::ResourceIdArray resource_ids_to_transfer;
-  resource_ids_to_transfer.push_back(resource);
-  TransferableResourceArray list;
-  child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer,
-                                                &list);
-
-  EXPECT_EQ(0u, release_sync_point);
-  EXPECT_FALSE(lost_resource);
-
-  child_resource_provider_ = nullptr;
-
-  // Since the resource is in the parent, the child considers it lost.
-  EXPECT_EQ(0u, release_sync_point);
-  EXPECT_TRUE(lost_resource);
-}
-
-TEST_P(ResourceProviderTest, LostContext) {
-  // TextureMailbox callbacks only exist for GL textures for now.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  unsigned texture = context()->createTexture();
-  context()->bindTexture(GL_TEXTURE_2D, texture);
-  gpu::Mailbox mailbox;
-  context()->genMailboxCHROMIUM(mailbox.name);
-  context()->produceTextureDirectCHROMIUM(texture, GL_TEXTURE_2D, mailbox.name);
-  uint32 sync_point = context()->insertSyncPoint();
-
-  EXPECT_LT(0u, sync_point);
-
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  BlockingTaskRunner* main_thread_task_runner = NULL;
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(ReleaseCallback,
-                                                   &release_sync_point,
-                                                   &lost_resource,
-                                                   &main_thread_task_runner));
-  resource_provider_->CreateResourceFromTextureMailbox(
-      TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), callback.Pass());
-
-  EXPECT_EQ(0u, release_sync_point);
-  EXPECT_FALSE(lost_resource);
-  EXPECT_EQ(NULL, main_thread_task_runner);
-
-  resource_provider_->DidLoseOutputSurface();
-  resource_provider_ = nullptr;
-
-  EXPECT_LE(sync_point, release_sync_point);
-  EXPECT_TRUE(lost_resource);
-  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
-}
-
-TEST_P(ResourceProviderTest, ScopedSampler) {
-  // Sampling is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  int texture_id = 1;
-
-  ResourceProvider::ResourceId id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  // Check that the texture gets created with the right sampler settings.
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id))
-      .Times(2);  // Once to create and once to allocate.
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-  EXPECT_CALL(
-      *context,
-      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(
-      *context,
-      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D,
-                            GL_TEXTURE_POOL_CHROMIUM,
-                            GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
-
-  resource_provider->AllocateForTesting(id);
-  Mock::VerifyAndClearExpectations(context);
-
-  // Creating a sampler with the default filter should not change any texture
-  // parameters.
-  {
-    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-    ResourceProvider::ScopedSamplerGL sampler(
-        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
-    Mock::VerifyAndClearExpectations(context);
-  }
-
-  // Using a different filter should be reflected in the texture parameters.
-  {
-    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
-    ResourceProvider::ScopedSamplerGL sampler(
-        resource_provider.get(), id, GL_TEXTURE_2D, GL_NEAREST);
-    Mock::VerifyAndClearExpectations(context);
-  }
-
-  // Test resetting to the default filter.
-  {
-    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    ResourceProvider::ScopedSamplerGL sampler(
-        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
-    Mock::VerifyAndClearExpectations(context);
-  }
-}
-
-TEST_P(ResourceProviderTest, ManagedResource) {
-  // Sampling is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  int texture_id = 1;
-
-  // Check that the texture gets created with the right sampler settings.
-  ResourceProvider::ResourceId id = resource_provider->CreateManagedResource(
-      size, GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-  EXPECT_CALL(
-      *context,
-      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(
-      *context,
-      texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-  EXPECT_CALL(*context,
-              texParameteri(GL_TEXTURE_2D,
-                            GL_TEXTURE_POOL_CHROMIUM,
-                            GL_TEXTURE_POOL_MANAGED_CHROMIUM));
-  resource_provider->CreateForTesting(id);
-  EXPECT_NE(0u, id);
-
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, TextureWrapMode) {
-  // Sampling is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;
-
-  for (int texture_id = 1; texture_id <= 2; ++texture_id) {
-    GLint wrap_mode = texture_id == 1 ? GL_CLAMP_TO_EDGE : GL_REPEAT;
-    // Check that the texture gets created with the right sampler settings.
-    ResourceProvider::ResourceId id = resource_provider->CreateGLTexture(
-        size, GL_TEXTURE_2D, texture_pool, wrap_mode,
-        ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_mode));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_mode));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_POOL_CHROMIUM,
-                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
-    resource_provider->CreateForTesting(id);
-    EXPECT_NE(0u, id);
-
-    Mock::VerifyAndClearExpectations(context);
-  }
-}
-
-TEST_P(ResourceProviderTest, TextureHint) {
-  // Sampling is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-  context->set_support_texture_storage(true);
-  context->set_support_texture_usage(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-  GLenum texture_pool = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;
-
-  const ResourceProvider::TextureHint hints[4] = {
-      ResourceProvider::TEXTURE_HINT_DEFAULT,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
-  };
-  for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
-    // Check that the texture gets created with the right sampler settings.
-    ResourceProvider::ResourceId id =
-        resource_provider->CreateGLTexture(size,
-                                           GL_TEXTURE_2D,
-                                           texture_pool,
-                                           GL_CLAMP_TO_EDGE,
-                                           hints[texture_id - 1],
-                                           format);
-    EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
-    EXPECT_CALL(
-        *context,
-        texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_POOL_CHROMIUM,
-                              GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
-    // Check only TEXTURE_HINT_FRAMEBUFFER set GL_TEXTURE_USAGE_ANGLE.
-    bool is_framebuffer_hint =
-        hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_FRAMEBUFFER;
-    EXPECT_CALL(*context,
-                texParameteri(GL_TEXTURE_2D,
-                              GL_TEXTURE_USAGE_ANGLE,
-                              GL_FRAMEBUFFER_ATTACHMENT_ANGLE))
-        .Times(is_framebuffer_hint ? 1 : 0);
-    resource_provider->CreateForTesting(id);
-    EXPECT_NE(0u, id);
-
-    Mock::VerifyAndClearExpectations(context);
-  }
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_BITMAP)
-    return;
-
-  gfx::Size size(64, 64);
-  const uint32_t kBadBeef = 0xbadbeef;
-  scoped_ptr<SharedBitmap> shared_bitmap(
-      CreateAndFillSharedBitmap(shared_bitmap_manager_.get(), size, kBadBeef));
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::CreateSoftware(make_scoped_ptr(
-          new SoftwareOutputDevice)));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               main_thread_task_runner_.get(),
-                               0,
-                               false,
-                               1));
-
-  uint32 release_sync_point = 0;
-  bool lost_resource = false;
-  BlockingTaskRunner* main_thread_task_runner = NULL;
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
-                                                   &release_sync_point,
-                                                   &lost_resource,
-                                                   &main_thread_task_runner));
-  TextureMailbox mailbox(shared_bitmap.get(), size);
-
-  ResourceProvider::ResourceId id =
-      resource_provider->CreateResourceFromTextureMailbox(
-          mailbox, callback.Pass());
-  EXPECT_NE(0u, id);
-
-  {
-    ResourceProvider::ScopedReadLockSoftware lock(resource_provider.get(), id);
-    const SkBitmap* sk_bitmap = lock.sk_bitmap();
-    EXPECT_EQ(sk_bitmap->width(), size.width());
-    EXPECT_EQ(sk_bitmap->height(), size.height());
-    EXPECT_EQ(*sk_bitmap->getAddr32(16, 16), kBadBeef);
-  }
-
-  resource_provider->DeleteResource(id);
-  EXPECT_EQ(0u, release_sync_point);
-  EXPECT_FALSE(lost_resource);
-  EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner);
-}
-
-class ResourceProviderTestTextureMailboxGLFilters
-    : public ResourceProviderTest {
- public:
-  static void RunTest(TestSharedBitmapManager* shared_bitmap_manager,
-                      TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
-                      BlockingTaskRunner* main_thread_task_runner,
-                      bool mailbox_nearest_neighbor,
-                      GLenum sampler_filter) {
-    scoped_ptr<TextureStateTrackingContext> context_owned(
-        new TextureStateTrackingContext);
-    TextureStateTrackingContext* context = context_owned.get();
-
-    FakeOutputSurfaceClient output_surface_client;
-    scoped_ptr<OutputSurface> output_surface(
-        FakeOutputSurface::Create3d(context_owned.Pass()));
-    CHECK(output_surface->BindToClient(&output_surface_client));
-
-    scoped_ptr<ResourceProvider> resource_provider(
-        ResourceProvider::Create(output_surface.get(),
-                                 shared_bitmap_manager,
-                                 gpu_memory_buffer_manager,
-                                 main_thread_task_runner,
-                                 0,
-                                 false,
-                                 1));
-
-    unsigned texture_id = 1;
-    uint32 sync_point = 30;
-    unsigned target = GL_TEXTURE_2D;
-
-    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-
-    gpu::Mailbox gpu_mailbox;
-    memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
-    uint32 release_sync_point = 0;
-    bool lost_resource = false;
-    BlockingTaskRunner* mailbox_task_runner = NULL;
-    scoped_ptr<SingleReleaseCallbackImpl> callback =
-        SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback,
-                                                     &release_sync_point,
-                                                     &lost_resource,
-                                                     &mailbox_task_runner));
-
-    TextureMailbox mailbox(gpu_mailbox, target, sync_point);
-    mailbox.set_nearest_neighbor(mailbox_nearest_neighbor);
-
-    ResourceProvider::ResourceId id =
-        resource_provider->CreateResourceFromTextureMailbox(mailbox,
-                                                            callback.Pass());
-    EXPECT_NE(0u, id);
-
-    Mock::VerifyAndClearExpectations(context);
-
-    {
-      // Mailbox sync point WaitSyncPoint before using the texture.
-      EXPECT_CALL(*context, waitSyncPoint(sync_point));
-      resource_provider->WaitSyncPointIfNeeded(id);
-      Mock::VerifyAndClearExpectations(context);
-
-      EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(target, _))
-          .WillOnce(Return(texture_id));
-      EXPECT_CALL(*context, bindTexture(target, texture_id));
-
-      EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-      EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-
-      // The sampler will reset these if |mailbox_nearest_neighbor| does not
-      // match |sampler_filter|.
-      if (mailbox_nearest_neighbor != (sampler_filter == GL_NEAREST)) {
-        EXPECT_CALL(*context, texParameteri(
-            GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, sampler_filter));
-        EXPECT_CALL(*context, texParameteri(
-            GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, sampler_filter));
-      }
-
-      ResourceProvider::ScopedSamplerGL lock(
-          resource_provider.get(), id, sampler_filter);
-      Mock::VerifyAndClearExpectations(context);
-
-      // When done with it, a sync point should be inserted, but no produce is
-      // necessary.
-      EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-      EXPECT_CALL(*context, insertSyncPoint());
-      EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-
-      EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-      EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-    }
-
-    resource_provider->DeleteResource(id);
-    EXPECT_EQ(0u, release_sync_point);
-    EXPECT_FALSE(lost_resource);
-    EXPECT_EQ(main_thread_task_runner, mailbox_task_runner);
-  }
-};
-
-TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_LinearToLinear) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  ResourceProviderTestTextureMailboxGLFilters::RunTest(
-      shared_bitmap_manager_.get(),
-      gpu_memory_buffer_manager_.get(),
-      main_thread_task_runner_.get(),
-      false,
-      GL_LINEAR);
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_NearestToNearest) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  ResourceProviderTestTextureMailboxGLFilters::RunTest(
-      shared_bitmap_manager_.get(),
-      gpu_memory_buffer_manager_.get(),
-      main_thread_task_runner_.get(),
-      true,
-      GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_NearestToLinear) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  ResourceProviderTestTextureMailboxGLFilters::RunTest(
-      shared_bitmap_manager_.get(),
-      gpu_memory_buffer_manager_.get(),
-      main_thread_task_runner_.get(),
-      true,
-      GL_LINEAR);
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D_LinearToNearest) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  ResourceProviderTestTextureMailboxGLFilters::RunTest(
-      shared_bitmap_manager_.get(),
-      gpu_memory_buffer_manager_.get(),
-      main_thread_task_runner_.get(),
-      false,
-      GL_NEAREST);
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  uint32 sync_point = 30;
-  unsigned target = GL_TEXTURE_EXTERNAL_OES;
-
-  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-
-  gpu::Mailbox gpu_mailbox;
-  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-
-  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
-
-  ResourceProvider::ResourceId id =
-      resource_provider->CreateResourceFromTextureMailbox(
-          mailbox, callback.Pass());
-  EXPECT_NE(0u, id);
-
-  Mock::VerifyAndClearExpectations(context);
-
-  {
-    // Mailbox sync point WaitSyncPoint before using the texture.
-    EXPECT_CALL(*context, waitSyncPoint(sync_point));
-    resource_provider->WaitSyncPointIfNeeded(id);
-    Mock::VerifyAndClearExpectations(context);
-
-    unsigned texture_id = 1;
-
-    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(target, _))
-        .WillOnce(Return(texture_id));
-
-    EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-
-    ResourceProvider::ScopedReadLockGL lock(resource_provider.get(), id);
-    Mock::VerifyAndClearExpectations(context);
-
-    // When done with it, a sync point should be inserted, but no produce is
-    // necessary.
-    EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-    EXPECT_CALL(*context, insertSyncPoint());
-    EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-
-    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-    EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-  }
-}
-
-TEST_P(ResourceProviderTest,
-       TextureMailbox_WaitSyncPointIfNeeded_WithSyncPoint) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  uint32 sync_point = 30;
-  unsigned target = GL_TEXTURE_2D;
-
-  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-
-  gpu::Mailbox gpu_mailbox;
-  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-
-  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
-
-  ResourceProvider::ResourceId id =
-      resource_provider->CreateResourceFromTextureMailbox(mailbox,
-                                                          callback.Pass());
-  EXPECT_NE(0u, id);
-
-  Mock::VerifyAndClearExpectations(context);
-
-  {
-    // First call to WaitSyncPointIfNeeded should call waitSyncPoint.
-    EXPECT_CALL(*context, waitSyncPoint(sync_point));
-    resource_provider->WaitSyncPointIfNeeded(id);
-    Mock::VerifyAndClearExpectations(context);
-
-    // Subsequent calls to WaitSyncPointIfNeeded shouldn't call waitSyncPoint.
-    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-    resource_provider->WaitSyncPointIfNeeded(id);
-    Mock::VerifyAndClearExpectations(context);
-  }
-}
-
-TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) {
-  // Mailboxing is only supported for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<TextureStateTrackingContext> context_owned(
-      new TextureStateTrackingContext);
-  TextureStateTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  uint32 sync_point = 0;
-  unsigned target = GL_TEXTURE_2D;
-
-  EXPECT_CALL(*context, bindTexture(_, _)).Times(0);
-  EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-  EXPECT_CALL(*context, insertSyncPoint()).Times(0);
-  EXPECT_CALL(*context, produceTextureDirectCHROMIUM(_, _, _)).Times(0);
-  EXPECT_CALL(*context, createAndConsumeTextureCHROMIUM(_, _)).Times(0);
-
-  gpu::Mailbox gpu_mailbox;
-  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-
-  TextureMailbox mailbox(gpu_mailbox, target, sync_point);
-
-  ResourceProvider::ResourceId id =
-      resource_provider->CreateResourceFromTextureMailbox(mailbox,
-                                                          callback.Pass());
-  EXPECT_NE(0u, id);
-
-  Mock::VerifyAndClearExpectations(context);
-
-  {
-    // WaitSyncPointIfNeeded with sync_point == 0 shouldn't call waitSyncPoint.
-    EXPECT_CALL(*context, waitSyncPoint(_)).Times(0);
-    resource_provider->WaitSyncPointIfNeeded(id);
-    Mock::VerifyAndClearExpectations(context);
-  }
-}
-
-class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
- public:
-  MOCK_METHOD0(NextTextureId, GLuint());
-  MOCK_METHOD1(RetireTextureId, void(GLuint id));
-  MOCK_METHOD2(bindTexture, void(GLenum target, GLuint texture));
-  MOCK_METHOD5(texStorage2DEXT,
-               void(GLenum target,
-                    GLint levels,
-                    GLuint internalformat,
-                    GLint width,
-                    GLint height));
-  MOCK_METHOD9(texImage2D,
-               void(GLenum target,
-                    GLint level,
-                    GLenum internalformat,
-                    GLsizei width,
-                    GLsizei height,
-                    GLint border,
-                    GLenum format,
-                    GLenum type,
-                    const void* pixels));
-  MOCK_METHOD9(texSubImage2D,
-               void(GLenum target,
-                    GLint level,
-                    GLint xoffset,
-                    GLint yoffset,
-                    GLsizei width,
-                    GLsizei height,
-                    GLenum format,
-                    GLenum type,
-                    const void* pixels));
-  MOCK_METHOD9(asyncTexImage2DCHROMIUM,
-               void(GLenum target,
-                    GLint level,
-                    GLenum internalformat,
-                    GLsizei width,
-                    GLsizei height,
-                    GLint border,
-                    GLenum format,
-                    GLenum type,
-                    const void* pixels));
-  MOCK_METHOD9(asyncTexSubImage2DCHROMIUM,
-               void(GLenum target,
-                    GLint level,
-                    GLint xoffset,
-                    GLint yoffset,
-                    GLsizei width,
-                    GLsizei height,
-                    GLenum format,
-                    GLenum type,
-                    const void* pixels));
-  MOCK_METHOD8(compressedTexImage2D,
-               void(GLenum target,
-                    GLint level,
-                    GLenum internalformat,
-                    GLsizei width,
-                    GLsizei height,
-                    GLint border,
-                    GLsizei image_size,
-                    const void* data));
-  MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(GLenum));
-  MOCK_METHOD4(createImageCHROMIUM,
-               GLuint(ClientBuffer, GLsizei, GLsizei, GLenum));
-  MOCK_METHOD1(destroyImageCHROMIUM, void(GLuint));
-  MOCK_METHOD2(bindTexImage2DCHROMIUM, void(GLenum, GLint));
-  MOCK_METHOD2(releaseTexImage2DCHROMIUM, void(GLenum, GLint));
-
-  // We're mocking bindTexture, so we override
-  // TestWebGraphicsContext3D::texParameteri to avoid assertions related to the
-  // currently bound texture.
-  virtual void texParameteri(GLenum target, GLenum pname, GLint param) {}
-};
-
-TEST_P(ResourceProviderTest, TextureAllocation) {
-  // Only for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(2, 2);
-  gfx::Vector2d offset(0, 0);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId id = 0;
-  uint8_t pixels[16] = { 0 };
-  int texture_id = 123;
-
-  // Lazy allocation. Don't allocate when creating the resource.
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
-  resource_provider->CreateForTesting(id);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-
-  Mock::VerifyAndClearExpectations(context);
-
-  // Do allocate when we set the pixels.
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
-  EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1);
-  EXPECT_CALL(*context, texSubImage2D(_, _, _, _, 2, 2, _, _, _)).Times(1);
-  resource_provider->CopyToResource(id, pixels, size);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-
-  Mock::VerifyAndClearExpectations(context);
-
-  // Same for async version.
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  resource_provider->AcquirePixelBuffer(id);
-
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
-      .Times(1);
-  resource_provider->BeginSetPixels(id);
-  ASSERT_TRUE(resource_provider->DidSetPixelsComplete(id));
-
-  resource_provider->ReleasePixelBuffer(id);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, TextureAllocationHint) {
-  // Only for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-  context->set_support_texture_storage(true);
-  context->set_support_texture_usage(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(2, 2);
-
-  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
-  const ResourceProvider::TextureHint hints[4] = {
-      ResourceProvider::TEXTURE_HINT_DEFAULT,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
-  };
-  for (size_t i = 0; i < arraysize(formats); ++i) {
-    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
-      // Lazy allocation. Don't allocate when creating the resource.
-      ResourceProvider::ResourceId id = resource_provider->CreateResource(
-          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
-
-      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-      bool is_immutable_hint =
-          hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE;
-      bool support_immutable_texture =
-          is_immutable_hint && formats[i] == RGBA_8888;
-      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
-          .Times(support_immutable_texture ? 1 : 0);
-      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
-          .Times(support_immutable_texture ? 0 : 1);
-      resource_provider->AllocateForTesting(id);
-
-      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-      resource_provider->DeleteResource(id);
-
-      Mock::VerifyAndClearExpectations(context);
-    }
-  }
-}
-
-TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) {
-  // Only for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-  context->set_support_texture_format_bgra8888(true);
-  context->set_support_texture_storage(true);
-  context->set_support_texture_usage(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  gfx::Size size(2, 2);
-  const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888};
-
-  const ResourceProvider::TextureHint hints[4] = {
-      ResourceProvider::TEXTURE_HINT_DEFAULT,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      ResourceProvider::TEXTURE_HINT_FRAMEBUFFER,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER,
-  };
-  for (size_t i = 0; i < arraysize(formats); ++i) {
-    for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) {
-      // Lazy allocation. Don't allocate when creating the resource.
-      ResourceProvider::ResourceId id = resource_provider->CreateResource(
-          size, GL_CLAMP_TO_EDGE, hints[texture_id - 1], formats[i]);
-
-      EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-      EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-      bool is_immutable_hint =
-          hints[texture_id - 1] & ResourceProvider::TEXTURE_HINT_IMMUTABLE;
-      EXPECT_CALL(*context, texStorage2DEXT(_, _, _, 2, 2))
-          .Times(is_immutable_hint ? 1 : 0);
-      EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _))
-          .Times(is_immutable_hint ? 0 : 1);
-      resource_provider->AllocateForTesting(id);
-
-      EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-      resource_provider->DeleteResource(id);
-
-      Mock::VerifyAndClearExpectations(context);
-    }
-  }
-}
-
-TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  gfx::Size size(2, 2);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId id = 0;
-  int texture_id = 123;
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  resource_provider->AcquirePixelBuffer(id);
-
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
-      .Times(1);
-  resource_provider->BeginSetPixels(id);
-
-  EXPECT_TRUE(resource_provider->DidSetPixelsComplete(id));
-
-  resource_provider->ReleasePixelBuffer(id);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
-  // Only for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  gfx::Size size(2, 2);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId id = 0;
-  int texture_id = 123;
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  resource_provider->AcquirePixelBuffer(id);
-
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-  EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
-      .Times(1);
-  resource_provider->BeginSetPixels(id);
-
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
-  EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
-  resource_provider->ForceSetPixelsToComplete(id);
-
-  resource_provider->ReleasePixelBuffer(id);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, PixelBufferLostContext) {
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new NiceMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  gfx::Size size(2, 2);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId id = 0;
-  int texture_id = 123;
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id));
-
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-  context->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB,
-                               GL_INNOCENT_CONTEXT_RESET_ARB);
-
-  resource_provider->AcquirePixelBuffer(id);
-  int stride;
-  void* buffer = resource_provider->MapPixelBuffer(id, &stride);
-  EXPECT_FALSE(buffer);
-  resource_provider->UnmapPixelBuffer(id);
-  Mock::VerifyAndClearExpectations(context);
-}
-
-TEST_P(ResourceProviderTest, Image_GLTexture) {
-  // Only for GL textures.
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  const int kWidth = 2;
-  const int kHeight = 2;
-  gfx::Size size(kWidth, kHeight);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId id = 0;
-  const unsigned kTextureId = 123u;
-  const unsigned kImageId = 234u;
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
-      .WillOnce(Return(kImageId))
-      .RetiresOnSaturation();
-  {
-    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
-        resource_provider.get(), id);
-    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
-  }
-
-  EXPECT_CALL(*context, NextTextureId())
-      .WillOnce(Return(kTextureId))
-      .RetiresOnSaturation();
-  // Once in CreateTextureId and once in BindForSampling
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(2)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-  {
-    ResourceProvider::ScopedSamplerGL lock_gl(
-        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
-    EXPECT_EQ(kTextureId, lock_gl.texture_id());
-  }
-
-  {
-    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
-        resource_provider.get(), id);
-    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
-  }
-
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kTextureId)).Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, releaseTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, RetireTextureId(kTextureId))
-      .Times(1)
-      .RetiresOnSaturation();
-  {
-    ResourceProvider::ScopedSamplerGL lock_gl(
-        resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
-    EXPECT_EQ(kTextureId, lock_gl.texture_id());
-  }
-
-  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-}
-
-TEST_P(ResourceProviderTest, CopyResource_GLTexture) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new StrictMock<AllocationTrackingContext3D>);
-  AllocationTrackingContext3D* context = context_owned.get();
-  context_owned->set_support_sync_query(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  ASSERT_TRUE(output_surface->BindToClient(&output_surface_client));
-
-  const int kWidth = 2;
-  const int kHeight = 2;
-  gfx::Size size(kWidth, kHeight);
-  ResourceFormat format = RGBA_8888;
-  ResourceProvider::ResourceId source_id = 0;
-  ResourceProvider::ResourceId dest_id = 0;
-  const unsigned kSourceTextureId = 123u;
-  const unsigned kDestTextureId = 321u;
-  const unsigned kImageId = 234u;
-
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  source_id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  EXPECT_CALL(*context, createImageCHROMIUM(_, kWidth, kHeight, GL_RGBA))
-      .WillOnce(Return(kImageId))
-      .RetiresOnSaturation();
-  {
-    ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock(
-        resource_provider.get(), source_id);
-    EXPECT_TRUE(!!lock.GetGpuMemoryBuffer());
-  }
-  Mock::VerifyAndClearExpectations(context);
-
-  dest_id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format);
-
-  EXPECT_CALL(*context, NextTextureId())
-      .WillOnce(Return(kDestTextureId))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kDestTextureId))
-      .Times(2)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA,
-                                   GL_UNSIGNED_BYTE, nullptr))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, NextTextureId())
-      .WillOnce(Return(kSourceTextureId))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, kSourceTextureId))
-      .Times(2)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, bindTexImage2DCHROMIUM(GL_TEXTURE_2D, kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-  resource_provider->CopyResource(source_id, dest_id);
-  Mock::VerifyAndClearExpectations(context);
-
-  EXPECT_CALL(*context, destroyImageCHROMIUM(kImageId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, RetireTextureId(kSourceTextureId))
-      .Times(1)
-      .RetiresOnSaturation();
-  EXPECT_CALL(*context, RetireTextureId(kDestTextureId))
-      .Times(1)
-      .RetiresOnSaturation();
-  resource_provider->DeleteResource(source_id);
-  resource_provider->DeleteResource(dest_id);
-}
-
-void InitializeGLAndCheck(ContextSharedData* shared_data,
-                          ResourceProvider* resource_provider,
-                          FakeOutputSurface* output_surface) {
-  scoped_ptr<ResourceProviderContext> context_owned =
-      ResourceProviderContext::Create(shared_data);
-  ResourceProviderContext* context = context_owned.get();
-
-  scoped_refptr<TestContextProvider> context_provider =
-      TestContextProvider::Create(context_owned.Pass());
-  output_surface->InitializeAndSetContext3d(context_provider, nullptr);
-  resource_provider->InitializeGL();
-
-  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE,
-                      resource_provider, context);
-}
-
-TEST(ResourceProviderTest, BasicInitializeGLSoftware) {
-  scoped_ptr<ContextSharedData> shared_data = ContextSharedData::Create();
-  bool delegated_rendering = false;
-  scoped_ptr<FakeOutputSurface> output_surface(
-      FakeOutputSurface::CreateDeferredGL(
-          scoped_ptr<SoftwareOutputDevice>(new SoftwareOutputDevice),
-          delegated_rendering));
-  FakeOutputSurfaceClient client(output_surface.get());
-  EXPECT_TRUE(output_surface->BindToClient(&client));
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-
-  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_BITMAP,
-                      resource_provider.get(), NULL);
-
-  InitializeGLAndCheck(shared_data.get(),
-                       resource_provider.get(),
-                       output_surface.get());
-
-  resource_provider->InitializeSoftware();
-  output_surface->ReleaseGL();
-  CheckCreateResource(ResourceProvider::RESOURCE_TYPE_BITMAP,
-                      resource_provider.get(), NULL);
-
-  InitializeGLAndCheck(shared_data.get(),
-                       resource_provider.get(),
-                       output_surface.get());
-}
-
-TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new AllocationTrackingContext3D);
-  AllocationTrackingContext3D* context = context_owned.get();
-  context_owned->set_support_compressed_texture_etc1(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  gfx::Size size(4, 4);
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-  int texture_id = 123;
-
-  ResourceProvider::ResourceId id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
-  EXPECT_NE(0u, id);
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
-  resource_provider->AllocateForTesting(id);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-}
-
-TEST_P(ResourceProviderTest, CompressedTextureETC1Upload) {
-  if (GetParam() != ResourceProvider::RESOURCE_TYPE_GL_TEXTURE)
-    return;
-
-  scoped_ptr<AllocationTrackingContext3D> context_owned(
-      new AllocationTrackingContext3D);
-  AllocationTrackingContext3D* context = context_owned.get();
-  context_owned->set_support_compressed_texture_etc1(true);
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  gfx::Size size(4, 4);
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               NULL,
-                               0,
-                               false,
-                               1));
-  int texture_id = 123;
-  uint8_t pixels[8];
-
-  ResourceProvider::ResourceId id = resource_provider->CreateResource(
-      size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1);
-  EXPECT_NE(0u, id);
-  EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id));
-  EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
-  EXPECT_CALL(*context,
-              compressedTexImage2D(
-                  _, 0, _, size.width(), size.height(), _, _, _)).Times(1);
-  resource_provider->CopyToResource(id, pixels, size);
-
-  EXPECT_CALL(*context, RetireTextureId(texture_id)).Times(1);
-  resource_provider->DeleteResource(id);
-}
-
-INSTANTIATE_TEST_CASE_P(
-    ResourceProviderTests,
-    ResourceProviderTest,
-    ::testing::Values(ResourceProvider::RESOURCE_TYPE_GL_TEXTURE,
-                      ResourceProvider::RESOURCE_TYPE_BITMAP));
-
-class TextureIdAllocationTrackingContext : public TestWebGraphicsContext3D {
- public:
-  GLuint NextTextureId() override {
-    base::AutoLock lock(namespace_->lock);
-    return namespace_->next_texture_id++;
-  }
-  void RetireTextureId(GLuint) override {}
-  GLuint PeekTextureId() {
-    base::AutoLock lock(namespace_->lock);
-    return namespace_->next_texture_id;
-  }
-};
-
-TEST(ResourceProviderTest, TextureAllocationChunkSize) {
-  scoped_ptr<TextureIdAllocationTrackingContext> context_owned(
-      new TextureIdAllocationTrackingContext);
-  TextureIdAllocationTrackingContext* context = context_owned.get();
-
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(
-      FakeOutputSurface::Create3d(context_owned.Pass()));
-  CHECK(output_surface->BindToClient(&output_surface_client));
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-
-  gfx::Size size(1, 1);
-  ResourceFormat format = RGBA_8888;
-
-  {
-    size_t kTextureAllocationChunkSize = 1;
-    scoped_ptr<ResourceProvider> resource_provider(
-        ResourceProvider::Create(output_surface.get(),
-                                 shared_bitmap_manager.get(),
-                                 NULL,
-                                 NULL,
-                                 0,
-                                 false,
-                                 kTextureAllocationChunkSize));
-
-    ResourceProvider::ResourceId id = resource_provider->CreateResource(
-        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-        format);
-    resource_provider->AllocateForTesting(id);
-    Mock::VerifyAndClearExpectations(context);
-
-    DCHECK_EQ(2u, context->PeekTextureId());
-    resource_provider->DeleteResource(id);
-  }
-
-  {
-    size_t kTextureAllocationChunkSize = 8;
-    scoped_ptr<ResourceProvider> resource_provider(
-        ResourceProvider::Create(output_surface.get(),
-                                 shared_bitmap_manager.get(),
-                                 NULL,
-                                 NULL,
-                                 0,
-                                 false,
-                                 kTextureAllocationChunkSize));
-
-    ResourceProvider::ResourceId id = resource_provider->CreateResource(
-        size, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-        format);
-    resource_provider->AllocateForTesting(id);
-    Mock::VerifyAndClearExpectations(context);
-
-    DCHECK_EQ(10u, context->PeekTextureId());
-    resource_provider->DeleteResource(id);
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/return_callback.h b/cc/resources/return_callback.h
deleted file mode 100644
index abf5aec..0000000
--- a/cc/resources/return_callback.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_RETURN_CALLBACK_H_
-#define CC_RESOURCES_RETURN_CALLBACK_H_
-
-#include "base/callback.h"
-#include "cc/resources/returned_resource.h"
-
-namespace cc {
-class BlockingTaskRunner;
-
-typedef base::Callback<void(const ReturnedResourceArray&,
-                            BlockingTaskRunner* main_thread_task_runner)>
-    ReturnCallback;
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RETURN_CALLBACK_H_
diff --git a/cc/resources/returned_resource.h b/cc/resources/returned_resource.h
deleted file mode 100644
index c19e1c9..0000000
--- a/cc/resources/returned_resource.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_RETURNED_RESOURCE_H_
-#define CC_RESOURCES_RETURNED_RESOURCE_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-
-namespace cc {
-
-struct ReturnedResource {
-  ReturnedResource() : id(0), sync_point(0), count(0), lost(false) {}
-  unsigned id;
-  unsigned sync_point;
-  int count;
-  bool lost;
-};
-
-typedef std::vector<ReturnedResource> ReturnedResourceArray;
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_RETURNED_RESOURCE_H_
diff --git a/cc/resources/scoped_resource.cc b/cc/resources/scoped_resource.cc
deleted file mode 100644
index e701182..0000000
--- a/cc/resources/scoped_resource.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/scoped_resource.h"
-
-namespace cc {
-
-ScopedResource::ScopedResource(ResourceProvider* resource_provider)
-    : resource_provider_(resource_provider) {
-  DCHECK(resource_provider_);
-}
-
-ScopedResource::~ScopedResource() {
-  Free();
-}
-
-void ScopedResource::Allocate(const gfx::Size& size,
-                              ResourceProvider::TextureHint hint,
-                              ResourceFormat format) {
-  DCHECK(!id());
-  DCHECK(!size.IsEmpty());
-
-  set_dimensions(size, format);
-  set_id(resource_provider_->CreateResource(
-      size, GL_CLAMP_TO_EDGE, hint, format));
-
-#if DCHECK_IS_ON()
-  allocate_thread_id_ = base::PlatformThread::CurrentId();
-#endif
-}
-
-void ScopedResource::AllocateManaged(const gfx::Size& size,
-                                     GLenum target,
-                                     ResourceFormat format) {
-  DCHECK(!id());
-  DCHECK(!size.IsEmpty());
-
-  set_dimensions(size, format);
-  set_id(resource_provider_->CreateManagedResource(
-      size, target, GL_CLAMP_TO_EDGE, ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      format));
-
-#if DCHECK_IS_ON()
-  allocate_thread_id_ = base::PlatformThread::CurrentId();
-#endif
-}
-
-void ScopedResource::Free() {
-  if (id()) {
-#if DCHECK_IS_ON()
-    DCHECK(allocate_thread_id_ == base::PlatformThread::CurrentId());
-#endif
-    resource_provider_->DeleteResource(id());
-  }
-  set_id(0);
-}
-
-}  // namespace cc
diff --git a/cc/resources/scoped_resource.h b/cc/resources/scoped_resource.h
deleted file mode 100644
index 6ea56ed..0000000
--- a/cc/resources/scoped_resource.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_RESOURCES_SCOPED_RESOURCE_H_
-#define CC_RESOURCES_SCOPED_RESOURCE_H_
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/resource.h"
-
-#if DCHECK_IS_ON()
-#include "base/threading/platform_thread.h"
-#endif
-
-namespace cc {
-
-class ScopedResource : public Resource {
- public:
-  static scoped_ptr<ScopedResource> Create(
-      ResourceProvider* resource_provider) {
-    return make_scoped_ptr(new ScopedResource(resource_provider));
-  }
-  virtual ~ScopedResource();
-
-  void Allocate(const gfx::Size& size,
-                ResourceProvider::TextureHint hint,
-                ResourceFormat format);
-  void AllocateManaged(const gfx::Size& size,
-                       GLenum target,
-                       ResourceFormat format);
-  void Free();
-
- protected:
-  explicit ScopedResource(ResourceProvider* provider);
-
- private:
-  ResourceProvider* resource_provider_;
-
-#if DCHECK_IS_ON()
-  base::PlatformThreadId allocate_thread_id_;
-#endif
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedResource);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_SCOPED_RESOURCE_H_
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc
deleted file mode 100644
index b95d814..0000000
--- a/cc/resources/scoped_resource_unittest.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/scoped_resource.h"
-
-#include "cc/output/renderer.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "cc/test/tiled_layer_test_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-TEST(ScopedResourceTest, NewScopedResource) {
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d());
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-  scoped_ptr<ScopedResource> texture =
-      ScopedResource::Create(resource_provider.get());
-
-  // New scoped textures do not hold a texture yet.
-  EXPECT_EQ(0u, texture->id());
-
-  // New scoped textures do not have a size yet.
-  EXPECT_EQ(gfx::Size(), texture->size());
-  EXPECT_EQ(0u, texture->bytes());
-}
-
-TEST(ScopedResourceTest, CreateScopedResource) {
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d());
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-  scoped_ptr<ScopedResource> texture =
-      ScopedResource::Create(resource_provider.get());
-  texture->Allocate(gfx::Size(30, 30), ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-                    RGBA_8888);
-
-  // The texture has an allocated byte-size now.
-  size_t expected_bytes = 30 * 30 * 4;
-  EXPECT_EQ(expected_bytes, texture->bytes());
-
-  EXPECT_LT(0u, texture->id());
-  EXPECT_EQ(static_cast<unsigned>(RGBA_8888), texture->format());
-  EXPECT_EQ(gfx::Size(30, 30), texture->size());
-}
-
-TEST(ScopedResourceTest, ScopedResourceIsDeleted) {
-  FakeOutputSurfaceClient output_surface_client;
-  scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d());
-  CHECK(output_surface->BindToClient(&output_surface_client));
-
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager(
-      new TestSharedBitmapManager());
-  scoped_ptr<ResourceProvider> resource_provider(
-      ResourceProvider::Create(output_surface.get(),
-                               shared_bitmap_manager.get(),
-                               NULL,
-                               NULL,
-                               0,
-                               false,
-                               1));
-  {
-    scoped_ptr<ScopedResource> texture =
-        ScopedResource::Create(resource_provider.get());
-
-    EXPECT_EQ(0u, resource_provider->num_resources());
-    texture->Allocate(gfx::Size(30, 30),
-                      ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-    EXPECT_LT(0u, texture->id());
-    EXPECT_EQ(1u, resource_provider->num_resources());
-  }
-
-  EXPECT_EQ(0u, resource_provider->num_resources());
-  {
-    scoped_ptr<ScopedResource> texture =
-        ScopedResource::Create(resource_provider.get());
-    EXPECT_EQ(0u, resource_provider->num_resources());
-    texture->Allocate(gfx::Size(30, 30),
-                      ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
-    EXPECT_LT(0u, texture->id());
-    EXPECT_EQ(1u, resource_provider->num_resources());
-    texture->Free();
-    EXPECT_EQ(0u, resource_provider->num_resources());
-  }
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/shared_bitmap.cc b/cc/resources/shared_bitmap.cc
deleted file mode 100644
index 1ac0323..0000000
--- a/cc/resources/shared_bitmap.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/shared_bitmap.h"
-
-#include "base/logging.h"
-#include "base/numerics/safe_math.h"
-#include "base/rand_util.h"
-
-namespace cc {
-
-SharedBitmap::SharedBitmap(uint8* pixels, const SharedBitmapId& id)
-    : pixels_(pixels), id_(id) {
-}
-
-SharedBitmap::~SharedBitmap() {
-}
-
-// static
-bool SharedBitmap::SizeInBytes(const gfx::Size& size, size_t* size_in_bytes) {
-  if (size.IsEmpty())
-    return false;
-  base::CheckedNumeric<size_t> s = 4;
-  s *= size.width();
-  s *= size.height();
-  if (!s.IsValid())
-    return false;
-  *size_in_bytes = s.ValueOrDie();
-  return true;
-}
-
-// static
-size_t SharedBitmap::CheckedSizeInBytes(const gfx::Size& size) {
-  CHECK(!size.IsEmpty());
-  base::CheckedNumeric<size_t> s = 4;
-  s *= size.width();
-  s *= size.height();
-  return s.ValueOrDie();
-}
-
-// static
-size_t SharedBitmap::UncheckedSizeInBytes(const gfx::Size& size) {
-  DCHECK(VerifySizeInBytes(size));
-  size_t s = 4;
-  s *= size.width();
-  s *= size.height();
-  return s;
-}
-
-// static
-bool SharedBitmap::VerifySizeInBytes(const gfx::Size& size) {
-  if (size.IsEmpty())
-    return false;
-  base::CheckedNumeric<size_t> s = 4;
-  s *= size.width();
-  s *= size.height();
-  return s.IsValid();
-}
-
-// static
-SharedBitmapId SharedBitmap::GenerateId() {
-  SharedBitmapId id;
-  // Needs cryptographically-secure random numbers.
-  base::RandBytes(id.name, sizeof(id.name));
-  return id;
-}
-
-}  // namespace cc
diff --git a/cc/resources/shared_bitmap.h b/cc/resources/shared_bitmap.h
deleted file mode 100644
index 793ef7a..0000000
--- a/cc/resources/shared_bitmap.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_SHARED_BITMAP_H_
-#define CC_RESOURCES_SHARED_BITMAP_H_
-
-#include "base/basictypes.h"
-#include "gpu/command_buffer/common/mailbox.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-typedef gpu::Mailbox SharedBitmapId;
-
-class SharedBitmap {
- public:
-  SharedBitmap(uint8* pixels, const SharedBitmapId& id);
-
-  virtual ~SharedBitmap();
-
-  uint8* pixels() { return pixels_; }
-
-  const SharedBitmapId& id() { return id_; }
-
-  // Returns true if the size is valid and false otherwise.
-  static bool SizeInBytes(const gfx::Size& size, size_t* size_in_bytes);
-  // Dies with a CRASH() if the size can not be represented as a positive number
-  // of bytes.
-  static size_t CheckedSizeInBytes(const gfx::Size& size);
-  // Returns the size in bytes but may overflow or return 0. Only do this for
-  // sizes that have already been checked.
-  static size_t UncheckedSizeInBytes(const gfx::Size& size);
-  // Returns true if the size is valid and false otherwise.
-  static bool VerifySizeInBytes(const gfx::Size& size);
-
-  static SharedBitmapId GenerateId();
-
- private:
-  uint8* pixels_;
-  SharedBitmapId id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SharedBitmap);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_SHARED_BITMAP_H_
diff --git a/cc/resources/shared_bitmap_manager.h b/cc/resources/shared_bitmap_manager.h
deleted file mode 100644
index 1dd0897..0000000
--- a/cc/resources/shared_bitmap_manager.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
-#define CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/shared_bitmap.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class SharedBitmapManager {
- public:
-  SharedBitmapManager() {}
-  virtual ~SharedBitmapManager() {}
-
-  virtual scoped_ptr<SharedBitmap> AllocateSharedBitmap(const gfx::Size&) = 0;
-  virtual scoped_ptr<SharedBitmap> GetSharedBitmapFromId(
-      const gfx::Size&,
-      const SharedBitmapId&) = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SharedBitmapManager);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_SHARED_BITMAP_MANAGER_H_
diff --git a/cc/resources/single_release_callback.cc b/cc/resources/single_release_callback.cc
deleted file mode 100644
index 4565963..0000000
--- a/cc/resources/single_release_callback.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/single_release_callback.h"
-
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-
-namespace cc {
-
-SingleReleaseCallback::SingleReleaseCallback(const ReleaseCallback& callback)
-    : has_been_run_(false), callback_(callback) {
-  DCHECK(!callback_.is_null())
-      << "Use a NULL SingleReleaseCallback for an empty callback.";
-}
-
-SingleReleaseCallback::~SingleReleaseCallback() {
-  DCHECK(callback_.is_null() || has_been_run_)
-      << "SingleReleaseCallback was never run.";
-}
-
-void SingleReleaseCallback::Run(uint32 sync_point, bool is_lost) {
-  DCHECK(!has_been_run_) << "SingleReleaseCallback was run more than once.";
-  has_been_run_ = true;
-  callback_.Run(sync_point, is_lost);
-}
-
-}  // namespace cc
diff --git a/cc/resources/single_release_callback.h b/cc/resources/single_release_callback.h
deleted file mode 100644
index 1a759ab..0000000
--- a/cc/resources/single_release_callback.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_
-#define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/release_callback.h"
-
-namespace cc {
-
-class SingleReleaseCallback {
- public:
-  static scoped_ptr<SingleReleaseCallback> Create(const ReleaseCallback& cb) {
-    return make_scoped_ptr(new SingleReleaseCallback(cb));
-  }
-
-  ~SingleReleaseCallback();
-
-  void Run(uint32 sync_point, bool is_lost);
-
- private:
-  explicit SingleReleaseCallback(const ReleaseCallback& callback);
-
-  bool has_been_run_;
-  ReleaseCallback callback_;
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_
diff --git a/cc/resources/single_release_callback_impl.cc b/cc/resources/single_release_callback_impl.cc
deleted file mode 100644
index aef112e..0000000
--- a/cc/resources/single_release_callback_impl.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/resources/single_release_callback_impl.h"
-
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "cc/base/blocking_task_runner.h"
-
-namespace cc {
-
-SingleReleaseCallbackImpl::SingleReleaseCallbackImpl(
-    const ReleaseCallbackImpl& callback)
-    : has_been_run_(false), callback_(callback) {
-  DCHECK(!callback_.is_null())
-      << "Use a NULL SingleReleaseCallbackImpl for an empty callback.";
-}
-
-SingleReleaseCallbackImpl::~SingleReleaseCallbackImpl() {
-  DCHECK(callback_.is_null() || has_been_run_)
-      << "SingleReleaseCallbackImpl was never run.";
-}
-
-void SingleReleaseCallbackImpl::Run(
-    uint32 sync_point,
-    bool is_lost,
-    BlockingTaskRunner* main_thread_task_runner) {
-  DCHECK(!has_been_run_) << "SingleReleaseCallbackImpl was run more than once.";
-  has_been_run_ = true;
-  callback_.Run(sync_point, is_lost, main_thread_task_runner);
-}
-
-}  // namespace cc
diff --git a/cc/resources/single_release_callback_impl.h b/cc/resources/single_release_callback_impl.h
deleted file mode 100644
index 58ac154..0000000
--- a/cc/resources/single_release_callback_impl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_
-#define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/release_callback_impl.h"
-
-namespace cc {
-
-class SingleReleaseCallbackImpl {
- public:
-  static scoped_ptr<SingleReleaseCallbackImpl> Create(
-      const ReleaseCallbackImpl& cb) {
-    return make_scoped_ptr(new SingleReleaseCallbackImpl(cb));
-  }
-
-  ~SingleReleaseCallbackImpl();
-
-  void Run(uint32 sync_point,
-           bool is_lost,
-           BlockingTaskRunner* main_thread_task_runner);
-
- private:
-  explicit SingleReleaseCallbackImpl(const ReleaseCallbackImpl& callback);
-
-  bool has_been_run_;
-  ReleaseCallbackImpl callback_;
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_
diff --git a/cc/resources/texture_compressor.cc b/cc/resources/texture_compressor.cc
deleted file mode 100644
index 186a47d..0000000
--- a/cc/resources/texture_compressor.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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.
-
-#include "cc/resources/texture_compressor.h"
-
-#include "base/logging.h"
-#include "cc/resources/texture_compressor_etc1.h"
-
-namespace cc {
-
-scoped_ptr<TextureCompressor> TextureCompressor::Create(Format format) {
-  switch (format) {
-    case kFormatETC1:
-      return make_scoped_ptr(new TextureCompressorETC1());
-  }
-
-  NOTREACHED();
-  return nullptr;
-}
-
-}  // namespace cc
diff --git a/cc/resources/texture_compressor.h b/cc/resources/texture_compressor.h
deleted file mode 100644
index 4d3c409..0000000
--- a/cc/resources/texture_compressor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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.
-
-#ifndef CC_RESOURCES_TEXTURE_COMPRESSOR_H_
-#define CC_RESOURCES_TEXTURE_COMPRESSOR_H_
-
-#include <stdint.h>
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-
-namespace cc {
-
-class TextureCompressor {
- public:
-  enum Format {
-    kFormatETC1,
-  };
-
-  enum Quality {
-    kQualityLow,
-    kQualityMedium,
-    kQualityHigh,
-  };
-
-  static scoped_ptr<TextureCompressor> Create(Format format);
-  virtual ~TextureCompressor() {}
-
-  virtual void Compress(const uint8_t* src,
-                        uint8_t* dst,
-                        int width,
-                        int height,
-                        Quality quality) = 0;
-
- protected:
-  TextureCompressor() {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TextureCompressor);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TEXTURE_COMPRESSOR_H_
diff --git a/cc/resources/texture_compressor_etc1.cc b/cc/resources/texture_compressor_etc1.cc
deleted file mode 100644
index 61c4438..0000000
--- a/cc/resources/texture_compressor_etc1.cc
+++ /dev/null
@@ -1,503 +0,0 @@
-// 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.
-
-// See the following specification for details on the ETC1 format:
-// https://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
-
-#include "cc/resources/texture_compressor_etc1.h"
-
-#include <string.h>
-#include <limits>
-
-#include "base/logging.h"
-
-// Defining the following macro will cause the error metric function to weigh
-// each color channel differently depending on how the human eye can perceive
-// them. This can give a slight improvement in image quality at the cost of a
-// performance hit.
-// #define USE_PERCEIVED_ERROR_METRIC
-
-namespace {
-
-template <typename T>
-inline T clamp(T val, T min, T max) {
-  return val < min ? min : (val > max ? max : val);
-}
-
-inline uint8_t round_to_5_bits(float val) {
-  return clamp<uint8_t>(val * 31.0f / 255.0f + 0.5f, 0, 31);
-}
-
-inline uint8_t round_to_4_bits(float val) {
-  return clamp<uint8_t>(val * 15.0f / 255.0f + 0.5f, 0, 15);
-}
-
-union Color {
-  struct BgraColorType {
-    uint8_t b;
-    uint8_t g;
-    uint8_t r;
-    uint8_t a;
-  } channels;
-  uint8_t components[4];
-  uint32_t bits;
-};
-
-/*
- * Codeword tables.
- * See: Table 3.17.2
- */
-static const int16_t g_codeword_tables[8][4] = {{-8, -2, 2, 8},
-                                                {-17, -5, 5, 17},
-                                                {-29, -9, 9, 29},
-                                                {-42, -13, 13, 42},
-                                                {-60, -18, 18, 60},
-                                                {-80, -24, 24, 80},
-                                                {-106, -33, 33, 106},
-                                                {-183, -47, 47, 183}};
-
-/*
- * Maps modifier indices to pixel index values.
- * See: Table 3.17.3
- */
-static const uint8_t g_mod_to_pix[4] = {3, 2, 0, 1};
-
-/*
- * The ETC1 specification index texels as follows:
- *
- * [a][e][i][m]     [ 0][ 4][ 8][12]
- * [b][f][j][n] <-> [ 1][ 5][ 9][13]
- * [c][g][k][o]     [ 2][ 6][10][14]
- * [d][h][l][p]     [ 3][ 7][11][15]
- *
- * However, when extracting sub blocks from BGRA data the natural array
- * indexing order ends up different:
- *
- * vertical0: [a][e][b][f]  horizontal0: [a][e][i][m]
- *            [c][g][d][h]               [b][f][j][n]
- * vertical1: [i][m][j][n]  horizontal1: [c][g][k][o]
- *            [k][o][l][p]               [d][h][l][p]
- *
- * In order to translate from the natural array indices in a sub block to the
- * indices (number) used by specification and hardware we use this table.
- */
-static const uint8_t g_idx_to_num[4][8] = {
-    {0, 4, 1, 5, 2, 6, 3, 7},        // Vertical block 0.
-    {8, 12, 9, 13, 10, 14, 11, 15},  // Vertical block 1.
-    {0, 4, 8, 12, 1, 5, 9, 13},      // Horizontal block 0.
-    {2, 6, 10, 14, 3, 7, 11, 15}     // Horizontal block 1.
-};
-
-inline void WriteColors444(uint8_t* block,
-                           const Color& color0,
-                           const Color& color1) {
-  block[0] = (color0.channels.r & 0xf0) | (color1.channels.r >> 4);
-  block[1] = (color0.channels.g & 0xf0) | (color1.channels.g >> 4);
-  block[2] = (color0.channels.b & 0xf0) | (color1.channels.b >> 4);
-}
-
-inline void WriteColors555(uint8_t* block,
-                           const Color& color0,
-                           const Color& color1) {
-  // Table for conversion to 3-bit two complement format.
-  static const uint8_t two_compl_trans_table[8] = {
-      4,  // -4 (100b)
-      5,  // -3 (101b)
-      6,  // -2 (110b)
-      7,  // -1 (111b)
-      0,  //  0 (000b)
-      1,  //  1 (001b)
-      2,  //  2 (010b)
-      3,  //  3 (011b)
-  };
-
-  int16_t delta_r =
-      static_cast<int16_t>(color1.channels.r >> 3) - (color0.channels.r >> 3);
-  int16_t delta_g =
-      static_cast<int16_t>(color1.channels.g >> 3) - (color0.channels.g >> 3);
-  int16_t delta_b =
-      static_cast<int16_t>(color1.channels.b >> 3) - (color0.channels.b >> 3);
-  DCHECK(delta_r >= -4 && delta_r <= 3);
-  DCHECK(delta_g >= -4 && delta_g <= 3);
-  DCHECK(delta_b >= -4 && delta_b <= 3);
-
-  block[0] = (color0.channels.r & 0xf8) | two_compl_trans_table[delta_r + 4];
-  block[1] = (color0.channels.g & 0xf8) | two_compl_trans_table[delta_g + 4];
-  block[2] = (color0.channels.b & 0xf8) | two_compl_trans_table[delta_b + 4];
-}
-
-inline void WriteCodewordTable(uint8_t* block,
-                               uint8_t sub_block_id,
-                               uint8_t table) {
-  DCHECK_LT(sub_block_id, 2);
-  DCHECK_LT(table, 8);
-
-  uint8_t shift = (2 + (3 - sub_block_id * 3));
-  block[3] &= ~(0x07 << shift);
-  block[3] |= table << shift;
-}
-
-inline void WritePixelData(uint8_t* block, uint32_t pixel_data) {
-  block[4] |= pixel_data >> 24;
-  block[5] |= (pixel_data >> 16) & 0xff;
-  block[6] |= (pixel_data >> 8) & 0xff;
-  block[7] |= pixel_data & 0xff;
-}
-
-inline void WriteFlip(uint8_t* block, bool flip) {
-  block[3] &= ~0x01;
-  block[3] |= static_cast<uint8_t>(flip);
-}
-
-inline void WriteDiff(uint8_t* block, bool diff) {
-  block[3] &= ~0x02;
-  block[3] |= static_cast<uint8_t>(diff) << 1;
-}
-
-/**
- * Compress and rounds BGR888 into BGR444. The resulting BGR444 color is
- * expanded to BGR888 as it would be in hardware after decompression. The
- * actual 444-bit data is available in the four most significant bits of each
- * channel.
- */
-inline Color MakeColor444(const float* bgr) {
-  uint8_t b4 = round_to_4_bits(bgr[0]);
-  uint8_t g4 = round_to_4_bits(bgr[1]);
-  uint8_t r4 = round_to_4_bits(bgr[2]);
-  Color bgr444;
-  bgr444.channels.b = (b4 << 4) | b4;
-  bgr444.channels.g = (g4 << 4) | g4;
-  bgr444.channels.r = (r4 << 4) | r4;
-  return bgr444;
-}
-
-/**
- * Compress and rounds BGR888 into BGR555. The resulting BGR555 color is
- * expanded to BGR888 as it would be in hardware after decompression. The
- * actual 555-bit data is available in the five most significant bits of each
- * channel.
- */
-inline Color MakeColor555(const float* bgr) {
-  uint8_t b5 = round_to_5_bits(bgr[0]);
-  uint8_t g5 = round_to_5_bits(bgr[1]);
-  uint8_t r5 = round_to_5_bits(bgr[2]);
-  Color bgr555;
-  bgr555.channels.b = (b5 << 3) | (b5 >> 2);
-  bgr555.channels.g = (g5 << 3) | (g5 >> 2);
-  bgr555.channels.r = (r5 << 3) | (r5 >> 2);
-  return bgr555;
-}
-
-/**
- * Constructs a color from a given base color and luminance value.
- */
-inline Color MakeColor(const Color& base, int16_t lum) {
-  int b = static_cast<int>(base.channels.b) + lum;
-  int g = static_cast<int>(base.channels.g) + lum;
-  int r = static_cast<int>(base.channels.r) + lum;
-  Color color;
-  color.channels.b = static_cast<uint8_t>(clamp(b, 0, 255));
-  color.channels.g = static_cast<uint8_t>(clamp(g, 0, 255));
-  color.channels.r = static_cast<uint8_t>(clamp(r, 0, 255));
-  return color;
-}
-
-/**
- * Calculates the error metric for two colors. A small error signals that the
- * colors are similar to each other, a large error the signals the opposite.
- */
-inline uint32_t GetColorError(const Color& u, const Color& v) {
-#ifdef USE_PERCEIVED_ERROR_METRIC
-  float delta_b = static_cast<float>(u.channels.b) - v.channels.b;
-  float delta_g = static_cast<float>(u.channels.g) - v.channels.g;
-  float delta_r = static_cast<float>(u.channels.r) - v.channels.r;
-  return static_cast<uint32_t>(0.299f * delta_b * delta_b +
-                               0.587f * delta_g * delta_g +
-                               0.114f * delta_r * delta_r);
-#else
-  int delta_b = static_cast<int>(u.channels.b) - v.channels.b;
-  int delta_g = static_cast<int>(u.channels.g) - v.channels.g;
-  int delta_r = static_cast<int>(u.channels.r) - v.channels.r;
-  return delta_b * delta_b + delta_g * delta_g + delta_r * delta_r;
-#endif
-}
-
-void GetAverageColor(const Color* src, float* avg_color) {
-  uint32_t sum_b = 0, sum_g = 0, sum_r = 0;
-
-  for (unsigned int i = 0; i < 8; ++i) {
-    sum_b += src[i].channels.b;
-    sum_g += src[i].channels.g;
-    sum_r += src[i].channels.r;
-  }
-
-  const float kInv8 = 1.0f / 8.0f;
-  avg_color[0] = static_cast<float>(sum_b) * kInv8;
-  avg_color[1] = static_cast<float>(sum_g) * kInv8;
-  avg_color[2] = static_cast<float>(sum_r) * kInv8;
-}
-
-void ComputeLuminance(uint8_t* block,
-                      const Color* src,
-                      const Color& base,
-                      int sub_block_id,
-                      const uint8_t* idx_to_num_tab) {
-  uint32_t best_tbl_err = std::numeric_limits<uint32_t>::max();
-  uint8_t best_tbl_idx = 0;
-  uint8_t best_mod_idx[8][8];  // [table][texel]
-
-  // Try all codeword tables to find the one giving the best results for this
-  // block.
-  for (unsigned int tbl_idx = 0; tbl_idx < 8; ++tbl_idx) {
-    // Pre-compute all the candidate colors; combinations of the base color and
-    // all available luminance values.
-    Color candidate_color[4];  // [modifier]
-    for (unsigned int mod_idx = 0; mod_idx < 4; ++mod_idx) {
-      int16_t lum = g_codeword_tables[tbl_idx][mod_idx];
-      candidate_color[mod_idx] = MakeColor(base, lum);
-    }
-
-    uint32_t tbl_err = 0;
-
-    for (unsigned int i = 0; i < 8; ++i) {
-      // Try all modifiers in the current table to find which one gives the
-      // smallest error.
-      uint32_t best_mod_err = std::numeric_limits<uint32_t>::max();
-      for (unsigned int mod_idx = 0; mod_idx < 4; ++mod_idx) {
-        const Color& color = candidate_color[mod_idx];
-
-        uint32_t mod_err = GetColorError(src[i], color);
-        if (mod_err < best_mod_err) {
-          best_mod_idx[tbl_idx][i] = mod_idx;
-          best_mod_err = mod_err;
-
-          if (mod_err == 0)
-            break;  // We cannot do any better than this.
-        }
-      }
-
-      tbl_err += best_mod_err;
-      if (tbl_err > best_tbl_err)
-        break;  // We're already doing worse than the best table so skip.
-    }
-
-    if (tbl_err < best_tbl_err) {
-      best_tbl_err = tbl_err;
-      best_tbl_idx = tbl_idx;
-
-      if (tbl_err == 0)
-        break;  // We cannot do any better than this.
-    }
-  }
-
-  WriteCodewordTable(block, sub_block_id, best_tbl_idx);
-
-  uint32_t pix_data = 0;
-
-  for (unsigned int i = 0; i < 8; ++i) {
-    uint8_t mod_idx = best_mod_idx[best_tbl_idx][i];
-    uint8_t pix_idx = g_mod_to_pix[mod_idx];
-
-    uint32_t lsb = pix_idx & 0x1;
-    uint32_t msb = pix_idx >> 1;
-
-    // Obtain the texel number as specified in the standard.
-    int texel_num = idx_to_num_tab[i];
-    pix_data |= msb << (texel_num + 16);
-    pix_data |= lsb << (texel_num);
-  }
-
-  WritePixelData(block, pix_data);
-}
-
-/**
- * Tries to compress the block under the assumption that it's a single color
- * block. If it's not the function will bail out without writing anything to
- * the destination buffer.
- */
-bool TryCompressSolidBlock(uint8_t* dst, const Color* src) {
-  for (unsigned int i = 1; i < 16; ++i) {
-    if (src[i].bits != src[0].bits)
-      return false;
-  }
-
-  // Clear destination buffer so that we can "or" in the results.
-  memset(dst, 0, 8);
-
-  float src_color_float[3] = {static_cast<float>(src->channels.b),
-                              static_cast<float>(src->channels.g),
-                              static_cast<float>(src->channels.r)};
-  Color base = MakeColor555(src_color_float);
-
-  WriteDiff(dst, true);
-  WriteFlip(dst, false);
-  WriteColors555(dst, base, base);
-
-  uint8_t best_tbl_idx = 0;
-  uint8_t best_mod_idx = 0;
-  uint32_t best_mod_err = std::numeric_limits<uint32_t>::max();
-
-  // Try all codeword tables to find the one giving the best results for this
-  // block.
-  for (unsigned int tbl_idx = 0; tbl_idx < 8; ++tbl_idx) {
-    // Try all modifiers in the current table to find which one gives the
-    // smallest error.
-    for (unsigned int mod_idx = 0; mod_idx < 4; ++mod_idx) {
-      int16_t lum = g_codeword_tables[tbl_idx][mod_idx];
-      const Color& color = MakeColor(base, lum);
-
-      uint32_t mod_err = GetColorError(*src, color);
-      if (mod_err < best_mod_err) {
-        best_tbl_idx = tbl_idx;
-        best_mod_idx = mod_idx;
-        best_mod_err = mod_err;
-
-        if (mod_err == 0)
-          break;  // We cannot do any better than this.
-      }
-    }
-
-    if (best_mod_err == 0)
-      break;
-  }
-
-  WriteCodewordTable(dst, 0, best_tbl_idx);
-  WriteCodewordTable(dst, 1, best_tbl_idx);
-
-  uint8_t pix_idx = g_mod_to_pix[best_mod_idx];
-  uint32_t lsb = pix_idx & 0x1;
-  uint32_t msb = pix_idx >> 1;
-
-  uint32_t pix_data = 0;
-  for (unsigned int i = 0; i < 2; ++i) {
-    for (unsigned int j = 0; j < 8; ++j) {
-      // Obtain the texel number as specified in the standard.
-      int texel_num = g_idx_to_num[i][j];
-      pix_data |= msb << (texel_num + 16);
-      pix_data |= lsb << (texel_num);
-    }
-  }
-
-  WritePixelData(dst, pix_data);
-  return true;
-}
-
-void CompressBlock(uint8_t* dst, const Color* ver_src, const Color* hor_src) {
-  if (TryCompressSolidBlock(dst, ver_src))
-    return;
-
-  const Color* sub_block_src[4] = {ver_src, ver_src + 8, hor_src, hor_src + 8};
-
-  Color sub_block_avg[4];
-  bool use_differential[2] = {true, true};
-
-  // Compute the average color for each sub block and determine if differential
-  // coding can be used.
-  for (unsigned int i = 0, j = 1; i < 4; i += 2, j += 2) {
-    float avg_color_0[3];
-    GetAverageColor(sub_block_src[i], avg_color_0);
-    Color avg_color_555_0 = MakeColor555(avg_color_0);
-
-    float avg_color_1[3];
-    GetAverageColor(sub_block_src[j], avg_color_1);
-    Color avg_color_555_1 = MakeColor555(avg_color_1);
-
-    for (unsigned int light_idx = 0; light_idx < 3; ++light_idx) {
-      int u = avg_color_555_0.components[light_idx] >> 3;
-      int v = avg_color_555_1.components[light_idx] >> 3;
-
-      int component_diff = v - u;
-      if (component_diff < -4 || component_diff > 3) {
-        use_differential[i / 2] = false;
-        sub_block_avg[i] = MakeColor444(avg_color_0);
-        sub_block_avg[j] = MakeColor444(avg_color_1);
-      } else {
-        sub_block_avg[i] = avg_color_555_0;
-        sub_block_avg[j] = avg_color_555_1;
-      }
-    }
-  }
-
-  // Compute the error of each sub block before adjusting for luminance. These
-  // error values are later used for determining if we should flip the sub
-  // block or not.
-  uint32_t sub_block_err[4] = {0};
-  for (unsigned int i = 0; i < 4; ++i) {
-    for (unsigned int j = 0; j < 8; ++j) {
-      sub_block_err[i] += GetColorError(sub_block_avg[i], sub_block_src[i][j]);
-    }
-  }
-
-  bool flip =
-      sub_block_err[2] + sub_block_err[3] < sub_block_err[0] + sub_block_err[1];
-
-  // Clear destination buffer so that we can "or" in the results.
-  memset(dst, 0, 8);
-
-  WriteDiff(dst, use_differential[!!flip]);
-  WriteFlip(dst, flip);
-
-  uint8_t sub_block_off_0 = flip ? 2 : 0;
-  uint8_t sub_block_off_1 = sub_block_off_0 + 1;
-
-  if (use_differential[!!flip]) {
-    WriteColors555(dst, sub_block_avg[sub_block_off_0],
-                   sub_block_avg[sub_block_off_1]);
-  } else {
-    WriteColors444(dst, sub_block_avg[sub_block_off_0],
-                   sub_block_avg[sub_block_off_1]);
-  }
-
-  // Compute luminance for the first sub block.
-  ComputeLuminance(dst, sub_block_src[sub_block_off_0],
-                   sub_block_avg[sub_block_off_0], 0,
-                   g_idx_to_num[sub_block_off_0]);
-  // Compute luminance for the second sub block.
-  ComputeLuminance(dst, sub_block_src[sub_block_off_1],
-                   sub_block_avg[sub_block_off_1], 1,
-                   g_idx_to_num[sub_block_off_1]);
-}
-
-}  // namespace
-
-namespace cc {
-
-void TextureCompressorETC1::Compress(const uint8_t* src,
-                                     uint8_t* dst,
-                                     int width,
-                                     int height,
-                                     Quality quality) {
-  DCHECK(width >= 4 && (width & 3) == 0);
-  DCHECK(height >= 4 && (height & 3) == 0);
-
-  Color ver_blocks[16];
-  Color hor_blocks[16];
-
-  for (int y = 0; y < height; y += 4, src += width * 4 * 4) {
-    for (int x = 0; x < width; x += 4, dst += 8) {
-      const Color* row0 = reinterpret_cast<const Color*>(src + x * 4);
-      const Color* row1 = row0 + width;
-      const Color* row2 = row1 + width;
-      const Color* row3 = row2 + width;
-
-      memcpy(ver_blocks, row0, 8);
-      memcpy(ver_blocks + 2, row1, 8);
-      memcpy(ver_blocks + 4, row2, 8);
-      memcpy(ver_blocks + 6, row3, 8);
-      memcpy(ver_blocks + 8, row0 + 2, 8);
-      memcpy(ver_blocks + 10, row1 + 2, 8);
-      memcpy(ver_blocks + 12, row2 + 2, 8);
-      memcpy(ver_blocks + 14, row3 + 2, 8);
-
-      memcpy(hor_blocks, row0, 16);
-      memcpy(hor_blocks + 4, row1, 16);
-      memcpy(hor_blocks + 8, row2, 16);
-      memcpy(hor_blocks + 12, row3, 16);
-
-      CompressBlock(dst, ver_blocks, hor_blocks);
-    }
-  }
-}
-
-}  // namespace cc
diff --git a/cc/resources/texture_compressor_etc1.h b/cc/resources/texture_compressor_etc1.h
deleted file mode 100644
index 7b18cf3..0000000
--- a/cc/resources/texture_compressor_etc1.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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.
-
-#ifndef CC_RESOURCES_TEXTURE_COMPRESSOR_ETC1_H_
-#define CC_RESOURCES_TEXTURE_COMPRESSOR_ETC1_H_
-
-#include "cc/resources/texture_compressor.h"
-
-namespace cc {
-
-class TextureCompressorETC1 : public TextureCompressor {
- public:
-  TextureCompressorETC1() {}
-
-  // Compress a texture using ETC1. Note that the |quality| parameter is
-  // ignored. The current implementation does not support different quality
-  // settings.
-  void Compress(const uint8_t* src,
-                uint8_t* dst,
-                int width,
-                int height,
-                Quality quality) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TextureCompressorETC1);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TEXTURE_COMPRESSOR_ETC1_H_
diff --git a/cc/resources/texture_compressor_perftest.cc b/cc/resources/texture_compressor_perftest.cc
deleted file mode 100644
index 7d68bd6..0000000
--- a/cc/resources/texture_compressor_perftest.cc
+++ /dev/null
@@ -1,103 +0,0 @@
-// 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.
-
-#include "base/logging.h"
-#include "cc/debug/lap_timer.h"
-#include "cc/resources/texture_compressor.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-
-namespace cc {
-namespace {
-
-const int kTimeLimitMillis = 2000;
-const int kWarmupRuns = 5;
-const int kTimeCheckInterval = 10;
-
-const int kImageWidth = 256;
-const int kImageHeight = 256;
-const int kImageSizeInBytes = kImageWidth * kImageHeight * 4;
-
-const TextureCompressor::Quality kQualities[] = {
-    TextureCompressor::kQualityLow,
-    TextureCompressor::kQualityMedium,
-    TextureCompressor::kQualityHigh};
-
-std::string FormatName(TextureCompressor::Format format) {
-  switch (format) {
-    case TextureCompressor::kFormatETC1:
-      return "ETC1";
-  }
-
-  NOTREACHED();
-  return "";
-}
-
-std::string QualityName(TextureCompressor::Quality quality) {
-  switch (quality) {
-    case TextureCompressor::kQualityLow:
-      return "Low";
-    case TextureCompressor::kQualityMedium:
-      return "Medium";
-    case TextureCompressor::kQualityHigh:
-      return "High";
-  }
-
-  NOTREACHED();
-  return "";
-}
-
-class TextureCompressorPerfTest
-    : public testing::TestWithParam<TextureCompressor::Format> {
- public:
-  TextureCompressorPerfTest()
-      : timer_(kWarmupRuns,
-               base::TimeDelta::FromMilliseconds(kTimeLimitMillis),
-               kTimeCheckInterval) {}
-
-  void SetUp() override {
-    TextureCompressor::Format format = GetParam();
-    compressor_ = TextureCompressor::Create(format);
-  }
-
-  void RunTest(const std::string& name, TextureCompressor::Quality quality) {
-    timer_.Reset();
-    do {
-      compressor_->Compress(src_, dst_, kImageWidth, kImageHeight, quality);
-      timer_.NextLap();
-    } while (!timer_.HasTimeLimitExpired());
-
-    std::string str = FormatName(GetParam()) + " " + QualityName(quality);
-    perf_test::PrintResult("Compress256x256", name, str, timer_.MsPerLap(),
-                           "us", true);
-  }
-
- protected:
-  LapTimer timer_;
-  scoped_ptr<TextureCompressor> compressor_;
-  uint8_t src_[kImageSizeInBytes];
-  uint8_t dst_[kImageSizeInBytes];
-};
-
-TEST_P(TextureCompressorPerfTest, Compress256x256Image) {
-  for (int i = 0; i < kImageSizeInBytes; ++i)
-    src_[i] = i % 256;
-
-  for (auto& quality : kQualities)
-    RunTest("Image", quality);
-}
-
-TEST_P(TextureCompressorPerfTest, Compress256x256SolidImage) {
-  memset(src_, 0, kImageSizeInBytes);
-
-  for (auto& quality : kQualities)
-    RunTest("SolidImage", quality);
-}
-
-INSTANTIATE_TEST_CASE_P(TextureCompressorPerfTests,
-                        TextureCompressorPerfTest,
-                        ::testing::Values(TextureCompressor::kFormatETC1));
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/texture_mailbox.cc b/cc/resources/texture_mailbox.cc
deleted file mode 100644
index 9bf242e..0000000
--- a/cc/resources/texture_mailbox.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/texture_mailbox.h"
-
-#include "base/logging.h"
-#include "cc/resources/shared_bitmap.h"
-
-namespace cc {
-
-TextureMailbox::TextureMailbox() : shared_bitmap_(NULL) {
-}
-
-TextureMailbox::TextureMailbox(const gpu::MailboxHolder& mailbox_holder)
-    : mailbox_holder_(mailbox_holder),
-      shared_bitmap_(NULL),
-      allow_overlay_(false),
-      nearest_neighbor_(false) {
-}
-
-TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox,
-                               uint32 target,
-                               uint32 sync_point)
-    : mailbox_holder_(mailbox, target, sync_point),
-      shared_bitmap_(NULL),
-      allow_overlay_(false),
-      nearest_neighbor_(false) {
-}
-
-TextureMailbox::TextureMailbox(SharedBitmap* shared_bitmap,
-                               const gfx::Size& size)
-    : shared_bitmap_(shared_bitmap),
-      shared_memory_size_(size),
-      allow_overlay_(false),
-      nearest_neighbor_(false) {
-  // If an embedder of cc gives an invalid TextureMailbox, we should crash
-  // here to identify the offender.
-  CHECK(SharedBitmap::VerifySizeInBytes(shared_memory_size_));
-}
-
-TextureMailbox::~TextureMailbox() {}
-
-bool TextureMailbox::Equals(const TextureMailbox& other) const {
-  if (other.IsTexture()) {
-    return IsTexture() && !memcmp(mailbox_holder_.mailbox.name,
-                                  other.mailbox_holder_.mailbox.name,
-                                  sizeof(mailbox_holder_.mailbox.name));
-  } else if (other.IsSharedMemory()) {
-    return IsSharedMemory() && (shared_bitmap_ == other.shared_bitmap_);
-  }
-
-  DCHECK(!other.IsValid());
-  return !IsValid();
-}
-
-size_t TextureMailbox::SharedMemorySizeInBytes() const {
-  // UncheckedSizeInBytes is okay because we VerifySizeInBytes in the
-  // constructor and the field is immutable.
-  return SharedBitmap::UncheckedSizeInBytes(shared_memory_size_);
-}
-
-}  // namespace cc
diff --git a/cc/resources/texture_mailbox.h b/cc/resources/texture_mailbox.h
deleted file mode 100644
index 1540b93..0000000
--- a/cc/resources/texture_mailbox.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_TEXTURE_MAILBOX_H_
-#define CC_RESOURCES_TEXTURE_MAILBOX_H_
-
-#include <string>
-
-#include "base/memory/shared_memory.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-class SharedBitmap;
-
-// TODO(skaslev, danakj) Rename this class more apropriately since now it
-// can hold a shared memory resource as well as a texture mailbox.
-class TextureMailbox {
- public:
-  TextureMailbox();
-  explicit TextureMailbox(const gpu::MailboxHolder& mailbox_holder);
-  TextureMailbox(const gpu::Mailbox& mailbox, uint32 target, uint32 sync_point);
-  TextureMailbox(SharedBitmap* shared_bitmap, const gfx::Size& size);
-
-  ~TextureMailbox();
-
-  bool IsValid() const { return IsTexture() || IsSharedMemory(); }
-  bool IsTexture() const { return !mailbox_holder_.mailbox.IsZero(); }
-  bool IsSharedMemory() const { return shared_bitmap_ != NULL; }
-
-  bool Equals(const TextureMailbox&) const;
-
-  const gpu::Mailbox& mailbox() const { return mailbox_holder_.mailbox; }
-  const int8* name() const { return mailbox().name; }
-  uint32 target() const { return mailbox_holder_.texture_target; }
-  uint32 sync_point() const { return mailbox_holder_.sync_point; }
-  void set_sync_point(int32 sync_point) {
-    mailbox_holder_.sync_point = sync_point;
-  }
-
-  bool allow_overlay() const { return allow_overlay_; }
-  void set_allow_overlay(bool allow_overlay) { allow_overlay_ = allow_overlay; }
-  bool nearest_neighbor() const { return nearest_neighbor_; }
-  void set_nearest_neighbor(bool nearest_neighbor) {
-    nearest_neighbor_ = nearest_neighbor;
-  }
-
-  SharedBitmap* shared_bitmap() const { return shared_bitmap_; }
-  gfx::Size shared_memory_size() const { return shared_memory_size_; }
-  size_t SharedMemorySizeInBytes() const;
-
- private:
-  gpu::MailboxHolder mailbox_holder_;
-  SharedBitmap* shared_bitmap_;
-  gfx::Size shared_memory_size_;
-  bool allow_overlay_;
-  bool nearest_neighbor_;
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TEXTURE_MAILBOX_H_
diff --git a/cc/resources/texture_mailbox_deleter.cc b/cc/resources/texture_mailbox_deleter.cc
deleted file mode 100644
index ab86368..0000000
--- a/cc/resources/texture_mailbox_deleter.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/texture_mailbox_deleter.h"
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/weak_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/output/context_provider.h"
-#include "cc/resources/single_release_callback.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-
-namespace cc {
-
-static void DeleteTextureOnImplThread(
-    const scoped_refptr<ContextProvider>& context_provider,
-    unsigned texture_id,
-    uint32 sync_point,
-    bool is_lost) {
-  if (sync_point)
-    context_provider->ContextGL()->WaitSyncPointCHROMIUM(sync_point);
-  context_provider->ContextGL()->DeleteTextures(1, &texture_id);
-}
-
-static void PostTaskFromMainToImplThread(
-    scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner,
-    ReleaseCallback run_impl_callback,
-    unsigned sync_point,
-    bool is_lost) {
-  // This posts the task to RunDeleteTextureOnImplThread().
-  impl_task_runner->PostTask(
-      FROM_HERE, base::Bind(run_impl_callback, sync_point, is_lost));
-}
-
-TextureMailboxDeleter::TextureMailboxDeleter(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
-    : impl_task_runner_(task_runner), weak_ptr_factory_(this) {}
-
-TextureMailboxDeleter::~TextureMailboxDeleter() {
-  for (size_t i = 0; i < impl_callbacks_.size(); ++i)
-    impl_callbacks_.at(i)->Run(0, true);
-}
-
-scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback(
-    const scoped_refptr<ContextProvider>& context_provider,
-    unsigned texture_id) {
-  // This callback owns a reference on the |context_provider|. It must be
-  // destroyed on the impl thread. Upon destruction of this class, the
-  // callback must immediately be destroyed.
-  scoped_ptr<SingleReleaseCallback> impl_callback =
-      SingleReleaseCallback::Create(base::Bind(&DeleteTextureOnImplThread,
-                                               context_provider,
-                                               texture_id));
-
-  impl_callbacks_.push_back(impl_callback.Pass());
-
-  // The raw pointer to the impl-side callback is valid as long as this
-  // class is alive. So we guard it with a WeakPtr.
-  ReleaseCallback run_impl_callback(
-      base::Bind(&TextureMailboxDeleter::RunDeleteTextureOnImplThread,
-                 weak_ptr_factory_.GetWeakPtr(),
-                 impl_callbacks_.back()));
-
-  // Provide a callback for the main thread that posts back to the impl
-  // thread.
-  scoped_ptr<SingleReleaseCallback> main_callback =
-      SingleReleaseCallback::Create(base::Bind(
-          &PostTaskFromMainToImplThread, impl_task_runner_, run_impl_callback));
-
-  return main_callback.Pass();
-}
-
-void TextureMailboxDeleter::RunDeleteTextureOnImplThread(
-    SingleReleaseCallback* impl_callback,
-    unsigned sync_point,
-    bool is_lost) {
-  for (size_t i = 0; i < impl_callbacks_.size(); ++i) {
-    if (impl_callbacks_.at(i) == impl_callback) {
-      // Run the callback, then destroy it here on the impl thread.
-      impl_callbacks_.at(i)->Run(sync_point, is_lost);
-      impl_callbacks_.erase(impl_callbacks_.begin() + i);
-      return;
-    }
-  }
-
-  NOTREACHED() << "The Callback returned by GetDeleteCallback() was called "
-               << "more than once.";
-}
-
-}  // namespace cc
diff --git a/cc/resources/texture_mailbox_deleter.h b/cc/resources/texture_mailbox_deleter.h
deleted file mode 100644
index e82810a..0000000
--- a/cc/resources/texture_mailbox_deleter.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_RESOURCES_TEXTURE_MAILBOX_DELETER_H_
-#define CC_RESOURCES_TEXTURE_MAILBOX_DELETER_H_
-
-#include "base/memory/weak_ptr.h"
-#include "cc/base/scoped_ptr_vector.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace cc {
-class ContextProvider;
-class SingleReleaseCallback;
-
-class TextureMailboxDeleter {
- public:
-  explicit TextureMailboxDeleter(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
-  ~TextureMailboxDeleter();
-
-  // Returns a Callback that can be used as the ReleaseCallback for a
-  // TextureMailbox attached to the |texture_id|. The ReleaseCallback can
-  // be passed to other threads and will destroy the texture, once it is
-  // run, on the impl thread. If the TextureMailboxDeleter is destroyed
-  // due to the compositor shutting down, then the ReleaseCallback will
-  // become a no-op and the texture will be deleted immediately on the
-  // impl thread, along with dropping the reference to the ContextProvider.
-  scoped_ptr<SingleReleaseCallback> GetReleaseCallback(
-      const scoped_refptr<ContextProvider>& context_provider,
-      unsigned texture_id);
-
- private:
-  // Runs the |impl_callback| to delete the texture and removes the callback
-  // from the |impl_callbacks_| list.
-  void RunDeleteTextureOnImplThread(SingleReleaseCallback* impl_callback,
-                                    uint32 sync_point,
-                                    bool is_lost);
-
-  scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_;
-  ScopedPtrVector<SingleReleaseCallback> impl_callbacks_;
-  base::WeakPtrFactory<TextureMailboxDeleter> weak_ptr_factory_;
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TEXTURE_MAILBOX_DELETER_H_
diff --git a/cc/resources/texture_mailbox_deleter_unittest.cc b/cc/resources/texture_mailbox_deleter_unittest.cc
deleted file mode 100644
index 05e33a3..0000000
--- a/cc/resources/texture_mailbox_deleter_unittest.cc
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/resources/texture_mailbox_deleter.h"
-
-#include "base/message_loop/message_loop_proxy.h"
-#include "cc/resources/single_release_callback.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-TEST(TextureMailboxDeleterTest, Destroy) {
-  scoped_ptr<TextureMailboxDeleter> deleter(
-      new TextureMailboxDeleter(base::MessageLoopProxy::current()));
-
-  scoped_refptr<TestContextProvider> context_provider =
-      TestContextProvider::Create();
-  context_provider->BindToCurrentThread();
-
-  GLuint texture_id = 0u;
-  context_provider->ContextGL()->GenTextures(1, &texture_id);
-
-  EXPECT_TRUE(context_provider->HasOneRef());
-  EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
-
-  scoped_ptr<SingleReleaseCallback> cb =
-      deleter->GetReleaseCallback(context_provider, texture_id).Pass();
-  EXPECT_FALSE(context_provider->HasOneRef());
-  EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures());
-
-  // When the deleter is destroyed, it immediately drops its ref on the
-  // ContextProvider, and deletes the texture.
-  deleter = nullptr;
-  EXPECT_TRUE(context_provider->HasOneRef());
-  EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures());
-
-  // Run the scoped release callback before destroying it, but it won't do
-  // anything.
-  cb->Run(0, false);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/texture_uploader.cc b/cc/resources/texture_uploader.cc
deleted file mode 100644
index 601fa8f..0000000
--- a/cc/resources/texture_uploader.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/resources/texture_uploader.h"
-
-#include <algorithm>
-#include <vector>
-
-#include "base/metrics/histogram.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/util.h"
-#include "cc/resources/resource.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/vector2d.h"
-
-using gpu::gles2::GLES2Interface;
-
-namespace {
-
-// How many previous uploads to use when predicting future throughput.
-static const size_t kUploadHistorySizeMax = 1000;
-static const size_t kUploadHistorySizeInitial = 100;
-
-// Global estimated number of textures per second to maintain estimates across
-// subsequent instances of TextureUploader.
-// More than one thread will not access this variable, so we do not need to
-// synchronize access.
-static const double kDefaultEstimatedTexturesPerSecond = 48.0 * 60.0;
-
-// Flush interval when performing texture uploads.
-static const size_t kTextureUploadFlushPeriod = 4;
-
-}  // anonymous namespace
-
-namespace cc {
-
-TextureUploader::Query::Query(GLES2Interface* gl)
-    : gl_(gl),
-      query_id_(0),
-      value_(0),
-      has_value_(false),
-      is_non_blocking_(false) {
-  gl_->GenQueriesEXT(1, &query_id_);
-}
-
-TextureUploader::Query::~Query() { gl_->DeleteQueriesEXT(1, &query_id_); }
-
-void TextureUploader::Query::Begin() {
-  has_value_ = false;
-  is_non_blocking_ = false;
-  gl_->BeginQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM, query_id_);
-}
-
-void TextureUploader::Query::End() {
-  gl_->EndQueryEXT(GL_COMMANDS_ISSUED_CHROMIUM);
-}
-
-bool TextureUploader::Query::IsPending() {
-  unsigned available = 1;
-  gl_->GetQueryObjectuivEXT(
-      query_id_, GL_QUERY_RESULT_AVAILABLE_EXT, &available);
-  return !available;
-}
-
-unsigned TextureUploader::Query::Value() {
-  if (!has_value_) {
-    gl_->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &value_);
-    has_value_ = true;
-  }
-  return value_;
-}
-
-TextureUploader::TextureUploader(GLES2Interface* gl)
-    : gl_(gl),
-      num_blocking_texture_uploads_(0),
-      sub_image_size_(0),
-      num_texture_uploads_since_last_flush_(0) {
-  for (size_t i = kUploadHistorySizeInitial; i > 0; i--)
-    textures_per_second_history_.insert(kDefaultEstimatedTexturesPerSecond);
-}
-
-TextureUploader::~TextureUploader() {}
-
-size_t TextureUploader::NumBlockingUploads() {
-  ProcessQueries();
-  return num_blocking_texture_uploads_;
-}
-
-void TextureUploader::MarkPendingUploadsAsNonBlocking() {
-  for (ScopedPtrDeque<Query>::iterator it = pending_queries_.begin();
-       it != pending_queries_.end();
-       ++it) {
-    if ((*it)->is_non_blocking())
-      continue;
-
-    num_blocking_texture_uploads_--;
-    (*it)->mark_as_non_blocking();
-  }
-
-  DCHECK(!num_blocking_texture_uploads_);
-}
-
-double TextureUploader::EstimatedTexturesPerSecond() {
-  ProcessQueries();
-
-  // Use the median as our estimate.
-  std::multiset<double>::iterator median = textures_per_second_history_.begin();
-  std::advance(median, textures_per_second_history_.size() / 2);
-  return *median;
-}
-
-void TextureUploader::BeginQuery() {
-  // Check to see if any of the pending queries are free before allocating a
-  // new one. If this is not done, queries may be allocated without bound.
-  // http://crbug.com/398072
-  if (available_queries_.empty())
-    ProcessQueries();
-
-  if (available_queries_.empty())
-    available_queries_.push_back(Query::Create(gl_));
-
-  available_queries_.front()->Begin();
-}
-
-void TextureUploader::EndQuery() {
-  available_queries_.front()->End();
-  pending_queries_.push_back(available_queries_.take_front());
-  num_blocking_texture_uploads_++;
-}
-
-void TextureUploader::Upload(const uint8* image,
-                             const gfx::Rect& image_rect,
-                             const gfx::Rect& source_rect,
-                             gfx::Vector2d dest_offset,
-                             ResourceFormat format,
-                             const gfx::Size& size) {
-  CHECK(image_rect.Contains(source_rect));
-
-  bool is_full_upload = dest_offset.IsZero() && source_rect.size() == size;
-
-  if (is_full_upload)
-    BeginQuery();
-
-  UploadWithMapTexSubImage(image, image_rect, source_rect, dest_offset, format);
-
-  if (is_full_upload)
-    EndQuery();
-
-  num_texture_uploads_since_last_flush_++;
-  if (num_texture_uploads_since_last_flush_ >= kTextureUploadFlushPeriod)
-    Flush();
-}
-
-void TextureUploader::Flush() {
-  if (!num_texture_uploads_since_last_flush_)
-    return;
-
-  gl_->ShallowFlushCHROMIUM();
-
-  num_texture_uploads_since_last_flush_ = 0;
-}
-
-void TextureUploader::ReleaseCachedQueries() {
-  ProcessQueries();
-  available_queries_.clear();
-}
-
-void TextureUploader::UploadWithTexSubImage(const uint8* image,
-                                            const gfx::Rect& image_rect,
-                                            const gfx::Rect& source_rect,
-                                            gfx::Vector2d dest_offset,
-                                            ResourceFormat format) {
-  TRACE_EVENT0("cc", "TextureUploader::UploadWithTexSubImage");
-
-  // Early-out if this is a no-op, and assert that |image| be valid if this is
-  // not a no-op.
-  if (source_rect.IsEmpty())
-    return;
-  DCHECK(image);
-
-  // Offset from image-rect to source-rect.
-  gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
-
-  const uint8* pixel_source;
-  unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
-  // Use 4-byte row alignment (OpenGL default) for upload performance.
-  // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
-  unsigned upload_image_stride =
-      RoundUp(bytes_per_pixel * source_rect.width(), 4u);
-
-  if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
-      !offset.x()) {
-    pixel_source = &image[image_rect.width() * bytes_per_pixel * offset.y()];
-  } else {
-    size_t needed_size = upload_image_stride * source_rect.height();
-    if (sub_image_size_ < needed_size) {
-      sub_image_.reset(new uint8[needed_size]);
-      sub_image_size_ = needed_size;
-    }
-    // Strides not equal, so do a row-by-row memcpy from the
-    // paint results into a temp buffer for uploading.
-    for (int row = 0; row < source_rect.height(); ++row)
-      memcpy(&sub_image_[upload_image_stride * row],
-             &image[bytes_per_pixel *
-                    (offset.x() + (offset.y() + row) * image_rect.width())],
-             source_rect.width() * bytes_per_pixel);
-
-    pixel_source = &sub_image_[0];
-  }
-
-  gl_->TexSubImage2D(GL_TEXTURE_2D,
-                     0,
-                     dest_offset.x(),
-                     dest_offset.y(),
-                     source_rect.width(),
-                     source_rect.height(),
-                     GLDataFormat(format),
-                     GLDataType(format),
-                     pixel_source);
-}
-
-void TextureUploader::UploadWithMapTexSubImage(const uint8* image,
-                                               const gfx::Rect& image_rect,
-                                               const gfx::Rect& source_rect,
-                                               gfx::Vector2d dest_offset,
-                                               ResourceFormat format) {
-  TRACE_EVENT0("cc", "TextureUploader::UploadWithMapTexSubImage");
-
-  // Early-out if this is a no-op, and assert that |image| be valid if this is
-  // not a no-op.
-  if (source_rect.IsEmpty())
-    return;
-  DCHECK(image);
-  // Compressed textures have no implementation of mapTexSubImage.
-  DCHECK_NE(ETC1, format);
-
-  // Offset from image-rect to source-rect.
-  gfx::Vector2d offset(source_rect.origin() - image_rect.origin());
-
-  unsigned bytes_per_pixel = BitsPerPixel(format) / 8;
-  // Use 4-byte row alignment (OpenGL default) for upload performance.
-  // Assuming that GL_UNPACK_ALIGNMENT has not changed from default.
-  unsigned upload_image_stride =
-      RoundUp(bytes_per_pixel * source_rect.width(), 4u);
-
-  // Upload tile data via a mapped transfer buffer
-  uint8* pixel_dest =
-      static_cast<uint8*>(gl_->MapTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
-                                                        0,
-                                                        dest_offset.x(),
-                                                        dest_offset.y(),
-                                                        source_rect.width(),
-                                                        source_rect.height(),
-                                                        GLDataFormat(format),
-                                                        GLDataType(format),
-                                                        GL_WRITE_ONLY));
-
-  if (!pixel_dest) {
-    UploadWithTexSubImage(image, image_rect, source_rect, dest_offset, format);
-    return;
-  }
-
-  if (upload_image_stride == image_rect.width() * bytes_per_pixel &&
-      !offset.x()) {
-    memcpy(pixel_dest,
-           &image[image_rect.width() * bytes_per_pixel * offset.y()],
-           source_rect.height() * image_rect.width() * bytes_per_pixel);
-  } else {
-    // Strides not equal, so do a row-by-row memcpy from the
-    // paint results into the pixel_dest.
-    for (int row = 0; row < source_rect.height(); ++row) {
-      memcpy(&pixel_dest[upload_image_stride * row],
-             &image[bytes_per_pixel *
-                    (offset.x() + (offset.y() + row) * image_rect.width())],
-             source_rect.width() * bytes_per_pixel);
-    }
-  }
-
-  gl_->UnmapTexSubImage2DCHROMIUM(pixel_dest);
-}
-
-void TextureUploader::ProcessQueries() {
-  while (!pending_queries_.empty()) {
-    if (pending_queries_.front()->IsPending())
-      break;
-
-    unsigned us_elapsed = pending_queries_.front()->Value();
-    UMA_HISTOGRAM_CUSTOM_COUNTS(
-        "Renderer4.TextureGpuUploadTimeUS", us_elapsed, 0, 100000, 50);
-
-    // Clamp the queries to saner values in case the queries fail.
-    us_elapsed = std::max(1u, us_elapsed);
-    us_elapsed = std::min(15000u, us_elapsed);
-
-    if (!pending_queries_.front()->is_non_blocking())
-      num_blocking_texture_uploads_--;
-
-    // Remove the min and max value from our history and insert the new one.
-    double textures_per_second = 1.0 / (us_elapsed * 1e-6);
-    if (textures_per_second_history_.size() >= kUploadHistorySizeMax) {
-      textures_per_second_history_.erase(textures_per_second_history_.begin());
-      textures_per_second_history_.erase(--textures_per_second_history_.end());
-    }
-    textures_per_second_history_.insert(textures_per_second);
-
-    available_queries_.push_back(pending_queries_.take_front());
-  }
-}
-
-}  // namespace cc
diff --git a/cc/resources/texture_uploader.h b/cc/resources/texture_uploader.h
deleted file mode 100644
index f7e03be..0000000
--- a/cc/resources/texture_uploader.h
+++ /dev/null
@@ -1,117 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_RESOURCES_TEXTURE_UPLOADER_H_
-#define CC_RESOURCES_TEXTURE_UPLOADER_H_
-
-#include <set>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/base/scoped_ptr_deque.h"
-#include "cc/resources/resource_provider.h"
-
-namespace gfx {
-class Rect;
-class Size;
-class Vector2d;
-}
-
-namespace gpu {
-namespace gles2 {
-class GLES2Interface;
-}
-}
-
-namespace cc {
-
-class TextureUploader {
- public:
-  static scoped_ptr<TextureUploader> Create(gpu::gles2::GLES2Interface* gl) {
-    return make_scoped_ptr(new TextureUploader(gl));
-  }
-  ~TextureUploader();
-
-  size_t NumBlockingUploads();
-  void MarkPendingUploadsAsNonBlocking();
-  double EstimatedTexturesPerSecond();
-
-  // Let content_rect be a rectangle, and let content_rect be a sub-rectangle of
-  // content_rect, expressed in the same coordinate system as content_rect. Let
-  // image be a buffer for content_rect. This function will copy the region
-  // corresponding to source_rect to dest_offset in this sub-image.
-  void Upload(const uint8* image,
-              const gfx::Rect& content_rect,
-              const gfx::Rect& source_rect,
-              gfx::Vector2d dest_offset,
-              ResourceFormat format,
-              const gfx::Size& size);
-
-  void Flush();
-  void ReleaseCachedQueries();
-
- private:
-  class Query {
-   public:
-    static scoped_ptr<Query> Create(gpu::gles2::GLES2Interface* gl) {
-      return make_scoped_ptr(new Query(gl));
-    }
-
-    virtual ~Query();
-
-    void Begin();
-    void End();
-    bool IsPending();
-    unsigned Value();
-    size_t TexturesUploaded();
-    void mark_as_non_blocking() { is_non_blocking_ = true; }
-    bool is_non_blocking() const { return is_non_blocking_; }
-
-   private:
-    explicit Query(gpu::gles2::GLES2Interface* gl);
-
-    gpu::gles2::GLES2Interface* gl_;
-    unsigned query_id_;
-    unsigned value_;
-    bool has_value_;
-    bool is_non_blocking_;
-
-    DISALLOW_COPY_AND_ASSIGN(Query);
-  };
-
-  explicit TextureUploader(gpu::gles2::GLES2Interface* gl);
-
-  void BeginQuery();
-  void EndQuery();
-  void ProcessQueries();
-
-  void UploadWithTexSubImage(const uint8* image,
-                             const gfx::Rect& image_rect,
-                             const gfx::Rect& source_rect,
-                             gfx::Vector2d dest_offset,
-                             ResourceFormat format);
-  void UploadWithMapTexSubImage(const uint8* image,
-                                const gfx::Rect& image_rect,
-                                const gfx::Rect& source_rect,
-                                gfx::Vector2d dest_offset,
-                                ResourceFormat format);
-  void UploadWithTexImageETC1(const uint8* image, const gfx::Size& size);
-
-  gpu::gles2::GLES2Interface* gl_;
-  ScopedPtrDeque<Query> pending_queries_;
-  ScopedPtrDeque<Query> available_queries_;
-  std::multiset<double> textures_per_second_history_;
-  size_t num_blocking_texture_uploads_;
-
-  size_t sub_image_size_;
-  scoped_ptr<uint8[]> sub_image_;
-
-  size_t num_texture_uploads_since_last_flush_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextureUploader);
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TEXTURE_UPLOADER_H_
diff --git a/cc/resources/texture_uploader_unittest.cc b/cc/resources/texture_uploader_unittest.cc
deleted file mode 100644
index b168962..0000000
--- a/cc/resources/texture_uploader_unittest.cc
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/resources/texture_uploader.h"
-
-#include "cc/base/util.h"
-#include "cc/resources/prioritized_resource.h"
-#include "gpu/command_buffer/client/gles2_interface_stub.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-
-namespace cc {
-namespace {
-
-class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub {
- public:
-  TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {}
-
-  void PixelStorei(GLenum pname, GLint param) override {
-    switch (pname) {
-      case GL_UNPACK_ALIGNMENT:
-        // Param should be a power of two <= 8.
-        EXPECT_EQ(0, param & (param - 1));
-        EXPECT_GE(8, param);
-        switch (param) {
-          case 1:
-          case 2:
-          case 4:
-          case 8:
-            unpack_alignment_ = param;
-            break;
-          default:
-            break;
-        }
-        break;
-      default:
-        break;
-    }
-  }
-
-  void GetQueryObjectuivEXT(GLuint, GLenum type, GLuint* value) override {
-    switch (type) {
-      case GL_QUERY_RESULT_AVAILABLE_EXT:
-        *value = result_available_;
-        break;
-      default:
-        *value = 0;
-        break;
-    }
-  }
-
-  void TexSubImage2D(GLenum target,
-                     GLint level,
-                     GLint xoffset,
-                     GLint yoffset,
-                     GLsizei width,
-                     GLsizei height,
-                     GLenum format,
-                     GLenum type,
-                     const void* pixels) override {
-    EXPECT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
-    EXPECT_EQ(0, level);
-    EXPECT_LE(0, width);
-    EXPECT_LE(0, height);
-    EXPECT_LE(0, xoffset);
-    EXPECT_LE(0, yoffset);
-    EXPECT_LE(0, width);
-    EXPECT_LE(0, height);
-
-    // Check for allowed format/type combination.
-    unsigned int bytes_per_pixel = 0;
-    switch (format) {
-      case GL_ALPHA:
-        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-        bytes_per_pixel = 1;
-        break;
-      case GL_RGB:
-        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4), type);
-        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1), type);
-        switch (type) {
-          case GL_UNSIGNED_BYTE:
-            bytes_per_pixel = 3;
-            break;
-          case GL_UNSIGNED_SHORT_5_6_5:
-            bytes_per_pixel = 2;
-            break;
-        }
-        break;
-      case GL_RGBA:
-        EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type);
-        switch (type) {
-          case GL_UNSIGNED_BYTE:
-            bytes_per_pixel = 4;
-            break;
-          case GL_UNSIGNED_SHORT_4_4_4_4:
-            bytes_per_pixel = 2;
-            break;
-          case GL_UNSIGNED_SHORT_5_5_5_1:
-            bytes_per_pixel = 2;
-            break;
-        }
-        break;
-      case GL_LUMINANCE:
-        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-        bytes_per_pixel = 1;
-        break;
-      case GL_LUMINANCE_ALPHA:
-        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-        bytes_per_pixel = 2;
-        break;
-      case GL_RED_EXT:
-        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-        bytes_per_pixel = 1;
-        break;
-      case GL_RG_EXT:
-        EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
-        bytes_per_pixel = 2;
-        break;
-    }
-
-    // If NULL, we aren't checking texture contents.
-    if (pixels == NULL)
-      return;
-
-    const uint8* bytes = static_cast<const uint8*>(pixels);
-    // We'll expect the first byte of every row to be 0x1, and the last byte to
-    // be 0x2.
-    const unsigned int stride =
-        RoundUp(bytes_per_pixel * width, unpack_alignment_);
-    for (GLsizei row = 0; row < height; ++row) {
-      const uint8* row_bytes =
-          bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride);
-      EXPECT_EQ(0x1, row_bytes[0]);
-      EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]);
-    }
-  }
-
-  void SetResultAvailable(unsigned result_available) {
-    result_available_ = result_available;
-  }
-
- private:
-  unsigned result_available_;
-  unsigned unpack_alignment_;
-
-  DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext);
-};
-
-void UploadTexture(TextureUploader* uploader,
-                   ResourceFormat format,
-                   const gfx::Size& size,
-                   const uint8* data) {
-  uploader->Upload(
-      data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size);
-}
-
-TEST(TextureUploaderTest, NumBlockingUploads) {
-  TextureUploadTestContext context;
-  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
-  context.SetResultAvailable(0);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(1u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(2u, uploader->NumBlockingUploads());
-
-  context.SetResultAvailable(1);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-}
-
-TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) {
-  TextureUploadTestContext context;
-  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
-  context.SetResultAvailable(0);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(2u, uploader->NumBlockingUploads());
-
-  uploader->MarkPendingUploadsAsNonBlocking();
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  EXPECT_EQ(1u, uploader->NumBlockingUploads());
-
-  context.SetResultAvailable(1);
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
-  uploader->MarkPendingUploadsAsNonBlocking();
-  EXPECT_EQ(0u, uploader->NumBlockingUploads());
-}
-
-TEST(TextureUploaderTest, UploadContentsTest) {
-  TextureUploadTestContext context;
-  scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
-
-  uint8 buffer[256 * 256 * 4];
-
-  // Upload a tightly packed 256x256 RGBA texture.
-  memset(buffer, 0, sizeof(buffer));
-  for (int i = 0; i < 256; ++i) {
-    // Mark the beginning and end of each row, for the test.
-    buffer[i * 4 * 256] = 0x1;
-    buffer[(i + 1) * 4 * 256 - 1] = 0x2;
-  }
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer);
-
-  // Upload a tightly packed 41x43 RGBA texture.
-  memset(buffer, 0, sizeof(buffer));
-  for (int i = 0; i < 43; ++i) {
-    // Mark the beginning and end of each row, for the test.
-    buffer[i * 4 * 41] = 0x1;
-    buffer[(i + 1) * 4 * 41 - 1] = 0x2;
-  }
-  UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer);
-
-  // Upload a tightly packed 41x86 ALPHA texture.
-  memset(buffer, 0, sizeof(buffer));
-  for (int i = 0; i < 86; ++i) {
-    // Mark the beginning and end of each row, for the test.
-    buffer[i * 1 * 41] = 0x1;
-    buffer[(i + 1) * 41 - 1] = 0x2;
-  }
-  UploadTexture(uploader.get(), ALPHA_8, gfx::Size(41, 86), buffer);
-
-  // Upload a tightly packed 82x86 LUMINANCE texture.
-  memset(buffer, 0, sizeof(buffer));
-  for (int i = 0; i < 86; ++i) {
-    // Mark the beginning and end of each row, for the test.
-    buffer[i * 1 * 82] = 0x1;
-    buffer[(i + 1) * 82 - 1] = 0x2;
-  }
-  UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer);
-
-  // Upload a tightly packed 82x86 RED texture.
-  memset(buffer, 0, sizeof(buffer));
-  for (int i = 0; i < 86; ++i) {
-    // Mark the beginning and end of each row, for the test.
-    buffer[i * 1 * 82] = 0x1;
-    buffer[(i + 1) * 82 - 1] = 0x2;
-  }
-  UploadTexture(uploader.get(), RED_8, gfx::Size(82, 86), buffer);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/resources/transferable_resource.cc b/cc/resources/transferable_resource.cc
deleted file mode 100644
index 558d6e8..0000000
--- a/cc/resources/transferable_resource.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/resources/returned_resource.h"
-#include "cc/resources/transferable_resource.h"
-
-namespace cc {
-
-TransferableResource::TransferableResource()
-    : id(0),
-      format(RGBA_8888),
-      filter(0),
-      is_repeated(false),
-      is_software(false),
-      allow_overlay(false) {
-}
-
-TransferableResource::~TransferableResource() {
-}
-
-ReturnedResource TransferableResource::ToReturnedResource() const {
-  ReturnedResource returned;
-  returned.id = id;
-  returned.sync_point = mailbox_holder.sync_point;
-  returned.count = 1;
-  return returned;
-}
-
-// static
-void TransferableResource::ReturnResources(
-    const TransferableResourceArray& input,
-    ReturnedResourceArray* output) {
-  for (TransferableResourceArray::const_iterator it = input.begin();
-       it != input.end(); ++it)
-    output->push_back(it->ToReturnedResource());
-}
-
-}  // namespace cc
diff --git a/cc/resources/transferable_resource.h b/cc/resources/transferable_resource.h
deleted file mode 100644
index 1e5aaf3..0000000
--- a/cc/resources/transferable_resource.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_RESOURCES_TRANSFERABLE_RESOURCE_H_
-#define CC_RESOURCES_TRANSFERABLE_RESOURCE_H_
-
-#include <vector>
-
-#include "base/basictypes.h"
-#include "cc/resources/resource_format.h"
-#include "gpu/command_buffer/common/mailbox_holder.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-struct ReturnedResource;
-typedef std::vector<ReturnedResource> ReturnedResourceArray;
-struct TransferableResource;
-typedef std::vector<TransferableResource> TransferableResourceArray;
-
-struct TransferableResource {
-  TransferableResource();
-  ~TransferableResource();
-
-  ReturnedResource ToReturnedResource() const;
-  static void ReturnResources(const TransferableResourceArray& input,
-                              ReturnedResourceArray* output);
-
-  unsigned id;
-  ResourceFormat format;
-  uint32 filter;
-  gfx::Size size;
-  gpu::MailboxHolder mailbox_holder;
-  bool is_repeated;
-  bool is_software;
-  bool allow_overlay;
-};
-
-}  // namespace cc
-
-#endif  // CC_RESOURCES_TRANSFERABLE_RESOURCE_H_
diff --git a/cc/scheduler/begin_frame_source.cc b/cc/scheduler/begin_frame_source.cc
deleted file mode 100644
index 42b8f6f..0000000
--- a/cc/scheduler/begin_frame_source.cc
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/scheduler/begin_frame_source.h"
-
-#include "base/auto_reset.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/scheduler/delay_based_time_source.h"
-#include "cc/scheduler/scheduler.h"
-#include "ui/gfx/frame_time.h"
-
-#ifdef NDEBUG
-#define DEBUG_FRAMES(...)
-#else
-#define DEBUG_FRAMES(name, arg1_name, arg1_val, arg2_name, arg2_val)   \
-  TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), \
-               name,                                                   \
-               arg1_name,                                              \
-               arg1_val,                                               \
-               arg2_name,                                              \
-               arg2_val);
-#endif
-
-namespace cc {
-
-// BeginFrameObserverMixIn -----------------------------------------------
-BeginFrameObserverMixIn::BeginFrameObserverMixIn()
-    : last_begin_frame_args_(), dropped_begin_frame_args_(0) {
-}
-
-const BeginFrameArgs BeginFrameObserverMixIn::LastUsedBeginFrameArgs() const {
-  return last_begin_frame_args_;
-}
-void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) {
-  DEBUG_FRAMES("BeginFrameObserverMixIn::OnBeginFrame",
-               "last args",
-               last_begin_frame_args_.AsValue(),
-               "new args",
-               args.AsValue());
-  DCHECK(args.IsValid());
-  DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
-  bool used = OnBeginFrameMixInDelegate(args);
-  if (used) {
-    last_begin_frame_args_ = args;
-  } else {
-    ++dropped_begin_frame_args_;
-  }
-}
-
-void BeginFrameObserverMixIn::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->BeginDictionary("last_begin_frame_args_");
-  last_begin_frame_args_.AsValueInto(dict);
-  dict->EndDictionary();
-  dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_);
-}
-
-// BeginFrameSourceMixIn ------------------------------------------------------
-BeginFrameSourceMixIn::BeginFrameSourceMixIn()
-    : observer_(NULL),
-      needs_begin_frames_(false),
-      inside_as_value_into_(false) {
-  DCHECK(!observer_);
-  DCHECK_EQ(inside_as_value_into_, false);
-}
-
-bool BeginFrameSourceMixIn::NeedsBeginFrames() const {
-  return needs_begin_frames_;
-}
-
-void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) {
-  DEBUG_FRAMES("BeginFrameSourceMixIn::SetNeedsBeginFrames",
-               "current state",
-               needs_begin_frames_,
-               "new state",
-               needs_begin_frames);
-  if (needs_begin_frames_ != needs_begin_frames) {
-    needs_begin_frames_ = needs_begin_frames;
-    OnNeedsBeginFramesChange(needs_begin_frames);
-  }
-}
-
-void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) {
-  DEBUG_FRAMES("BeginFrameSourceMixIn::AddObserver",
-               "current observer",
-               observer_,
-               "to add observer",
-               obs);
-  DCHECK(!observer_);
-  observer_ = obs;
-}
-
-void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) {
-  DEBUG_FRAMES("BeginFrameSourceMixIn::RemoveObserver",
-               "current observer",
-               observer_,
-               "to remove observer",
-               obs);
-  DCHECK_EQ(observer_, obs);
-  observer_ = NULL;
-}
-
-void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) {
-  DEBUG_FRAMES("BeginFrameSourceMixIn::CallOnBeginFrame",
-               "current observer",
-               observer_,
-               "args",
-               args.AsValue());
-  if (observer_) {
-    return observer_->OnBeginFrame(args);
-  }
-}
-
-// Tracing support
-void BeginFrameSourceMixIn::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  // As the observer might try to trace the source, prevent an infinte loop
-  // from occuring.
-  if (inside_as_value_into_) {
-    dict->SetString("observer", "<loop detected>");
-    return;
-  }
-
-  if (observer_) {
-    base::AutoReset<bool> prevent_loops(
-        const_cast<bool*>(&inside_as_value_into_), true);
-    dict->BeginDictionary("observer");
-    observer_->AsValueInto(dict);
-    dict->EndDictionary();
-  } else {
-    dict->SetString("observer", "NULL");
-  }
-  dict->SetBoolean("needs_begin_frames", NeedsBeginFrames());
-}
-
-// BackToBackBeginFrameSourceMixIn --------------------------------------------
-scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create(
-    base::SingleThreadTaskRunner* task_runner) {
-  return make_scoped_ptr(new BackToBackBeginFrameSource(task_runner));
-}
-
-BackToBackBeginFrameSource::BackToBackBeginFrameSource(
-    base::SingleThreadTaskRunner* task_runner)
-    : BeginFrameSourceMixIn(),
-      task_runner_(task_runner),
-      send_begin_frame_posted_(false),
-      weak_factory_(this) {
-  DCHECK(task_runner);
-  DCHECK_EQ(needs_begin_frames_, false);
-  DCHECK_EQ(send_begin_frame_posted_, false);
-}
-
-BackToBackBeginFrameSource::~BackToBackBeginFrameSource() {
-}
-
-base::TimeTicks BackToBackBeginFrameSource::Now() {
-  return gfx::FrameTime::Now();
-}
-
-void BackToBackBeginFrameSource::OnNeedsBeginFramesChange(
-    bool needs_begin_frames) {
-  if (!needs_begin_frames)
-    return;
-
-  if (send_begin_frame_posted_)
-    return;
-
-  send_begin_frame_posted_ = true;
-  task_runner_->PostTask(FROM_HERE,
-                         base::Bind(&BackToBackBeginFrameSource::BeginFrame,
-                                    weak_factory_.GetWeakPtr()));
-}
-
-void BackToBackBeginFrameSource::BeginFrame() {
-  send_begin_frame_posted_ = false;
-
-  if (!needs_begin_frames_)
-    return;
-
-  base::TimeTicks now = Now();
-  BeginFrameArgs args = BeginFrameArgs::Create(
-      BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(),
-      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
-  CallOnBeginFrame(args);
-}
-
-// BeginFrameSource support
-
-void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) {
-  if (remaining_frames == 0) {
-    OnNeedsBeginFramesChange(NeedsBeginFrames());
-  }
-}
-
-// Tracing support
-void BackToBackBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "BackToBackBeginFrameSource");
-  BeginFrameSourceMixIn::AsValueInto(dict);
-  dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_);
-}
-
-// SyntheticBeginFrameSource ---------------------------------------------
-scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create(
-    base::SingleThreadTaskRunner* task_runner,
-    base::TimeTicks initial_vsync_timebase,
-    base::TimeDelta initial_vsync_interval) {
-  scoped_refptr<DelayBasedTimeSource> time_source;
-  if (gfx::FrameTime::TimestampsAreHighRes()) {
-    time_source = DelayBasedTimeSourceHighRes::Create(initial_vsync_interval,
-                                                      task_runner);
-  } else {
-    time_source =
-        DelayBasedTimeSource::Create(initial_vsync_interval, task_runner);
-  }
-
-  return make_scoped_ptr(new SyntheticBeginFrameSource(time_source));
-}
-
-SyntheticBeginFrameSource::SyntheticBeginFrameSource(
-    scoped_refptr<DelayBasedTimeSource> time_source)
-    : BeginFrameSourceMixIn(), time_source_(time_source) {
-  time_source_->SetActive(false);
-  time_source_->SetClient(this);
-}
-
-SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
-  if (NeedsBeginFrames())
-    time_source_->SetActive(false);
-}
-
-void SyntheticBeginFrameSource::OnUpdateVSyncParameters(
-    base::TimeTicks new_vsync_timebase,
-    base::TimeDelta new_vsync_interval) {
-  time_source_->SetTimebaseAndInterval(new_vsync_timebase, new_vsync_interval);
-}
-
-BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs(
-    base::TimeTicks frame_time,
-    BeginFrameArgs::BeginFrameArgsType type) {
-  base::TimeTicks deadline = time_source_->NextTickTime();
-  return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, deadline,
-                                time_source_->Interval(), type);
-}
-
-// TimeSourceClient support
-void SyntheticBeginFrameSource::OnTimerTick() {
-  CallOnBeginFrame(CreateBeginFrameArgs(time_source_->LastTickTime(),
-                                        BeginFrameArgs::NORMAL));
-}
-
-// BeginFrameSourceMixIn support
-void SyntheticBeginFrameSource::OnNeedsBeginFramesChange(
-    bool needs_begin_frames) {
-  base::TimeTicks missed_tick_time =
-      time_source_->SetActive(needs_begin_frames);
-  if (!missed_tick_time.is_null()) {
-    CallOnBeginFrame(
-        CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED));
-  }
-}
-
-// Tracing support
-void SyntheticBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "SyntheticBeginFrameSource");
-  BeginFrameSourceMixIn::AsValueInto(dict);
-
-  dict->BeginDictionary("time_source");
-  time_source_->AsValueInto(dict);
-  dict->EndDictionary();
-}
-
-// BeginFrameSourceMultiplexer -------------------------------------------
-scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() {
-  return make_scoped_ptr(new BeginFrameSourceMultiplexer());
-}
-
-BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer()
-    : BeginFrameSourceMixIn(),
-      minimum_interval_(base::TimeDelta()),
-      active_source_(NULL),
-      source_list_() {
-}
-
-BeginFrameSourceMultiplexer::BeginFrameSourceMultiplexer(
-    base::TimeDelta minimum_interval)
-    : BeginFrameSourceMixIn(),
-      minimum_interval_(minimum_interval),
-      active_source_(NULL),
-      source_list_() {
-}
-
-BeginFrameSourceMultiplexer::~BeginFrameSourceMultiplexer() {
-}
-
-void BeginFrameSourceMultiplexer::SetMinimumInterval(
-    base::TimeDelta new_minimum_interval) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetMinimumInterval",
-               "current minimum (us)",
-               minimum_interval_.InMicroseconds(),
-               "new minimum (us)",
-               new_minimum_interval.InMicroseconds());
-  DCHECK_GE(new_minimum_interval.ToInternalValue(), 0);
-  minimum_interval_ = new_minimum_interval;
-}
-
-void BeginFrameSourceMultiplexer::AddSource(BeginFrameSource* new_source) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::AddSource",
-               "current active",
-               active_source_,
-               "source to remove",
-               new_source);
-  DCHECK(new_source);
-  DCHECK(!HasSource(new_source));
-
-  source_list_.insert(new_source);
-
-  // If there is no active source, set the new one as the active one.
-  if (!active_source_)
-    SetActiveSource(new_source);
-}
-
-void BeginFrameSourceMultiplexer::RemoveSource(
-    BeginFrameSource* existing_source) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::RemoveSource",
-               "current active",
-               active_source_,
-               "source to remove",
-               existing_source);
-  DCHECK(existing_source);
-  DCHECK(HasSource(existing_source));
-  DCHECK_NE(existing_source, active_source_);
-  source_list_.erase(existing_source);
-}
-
-void BeginFrameSourceMultiplexer::SetActiveSource(
-    BeginFrameSource* new_source) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::SetActiveSource",
-               "current active",
-               active_source_,
-               "to become active",
-               new_source);
-
-  DCHECK(HasSource(new_source) || new_source == NULL);
-
-  bool needs_begin_frames = NeedsBeginFrames();
-  if (active_source_) {
-    if (needs_begin_frames)
-      SetNeedsBeginFrames(false);
-
-    // Technically we shouldn't need to remove observation, but this prevents
-    // the case where SetNeedsBeginFrames message gets to the source after a
-    // message has already been sent.
-    active_source_->RemoveObserver(this);
-    active_source_ = NULL;
-  }
-  DCHECK(!active_source_);
-  active_source_ = new_source;
-
-  if (active_source_) {
-    active_source_->AddObserver(this);
-
-    if (needs_begin_frames) {
-      SetNeedsBeginFrames(true);
-    }
-  }
-}
-
-const BeginFrameSource* BeginFrameSourceMultiplexer::ActiveSource() {
-  return active_source_;
-}
-
-// BeginFrameObserver support
-void BeginFrameSourceMultiplexer::OnBeginFrame(const BeginFrameArgs& args) {
-  if (!IsIncreasing(args)) {
-    DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
-                 "action",
-                 "discarding",
-                 "new args",
-                 args.AsValue());
-    return;
-  }
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame",
-               "action",
-               "using",
-               "new args",
-               args.AsValue());
-  CallOnBeginFrame(args);
-}
-
-const BeginFrameArgs BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs()
-    const {
-  if (observer_)
-    return observer_->LastUsedBeginFrameArgs();
-  else
-    return BeginFrameArgs();
-}
-
-// BeginFrameSource support
-void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange(
-    bool needs_begin_frames) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange",
-               "active_source", active_source_, "needs_begin_frames",
-               needs_begin_frames);
-  if (active_source_) {
-    active_source_->SetNeedsBeginFrames(needs_begin_frames);
-  } else {
-    DCHECK(!needs_begin_frames);
-  }
-}
-
-void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) {
-  DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame",
-               "active_source",
-               active_source_,
-               "remaining_frames",
-               remaining_frames);
-  if (active_source_) {
-    active_source_->DidFinishFrame(remaining_frames);
-  }
-}
-
-// Tracing support
-void BeginFrameSourceMultiplexer::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "BeginFrameSourceMultiplexer");
-
-  dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds());
-  if (observer_) {
-    dict->BeginDictionary("last_begin_frame_args");
-    observer_->LastUsedBeginFrameArgs().AsValueInto(dict);
-    dict->EndDictionary();
-  }
-
-  if (active_source_) {
-    dict->BeginDictionary("active_source");
-    active_source_->AsValueInto(dict);
-    dict->EndDictionary();
-  } else {
-    dict->SetString("active_source", "NULL");
-  }
-
-  dict->BeginArray("sources");
-  for (std::set<BeginFrameSource*>::const_iterator it = source_list_.begin();
-       it != source_list_.end();
-       ++it) {
-    dict->BeginDictionary();
-    (*it)->AsValueInto(dict);
-    dict->EndDictionary();
-  }
-  dict->EndArray();
-}
-
-// protected methods
-bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) {
-  return (source_list_.find(source) != source_list_.end());
-}
-
-bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) {
-  DCHECK(args.IsValid());
-  if (!observer_)
-    return false;
-
-  // If the last begin frame is invalid, then any new begin frame is valid.
-  if (!observer_->LastUsedBeginFrameArgs().IsValid())
-    return true;
-
-  // Only allow new args have a *strictly bigger* frame_time value and statisfy
-  // minimum interval requirement.
-  return (args.frame_time >=
-          observer_->LastUsedBeginFrameArgs().frame_time + minimum_interval_);
-}
-
-}  // namespace cc
diff --git a/cc/scheduler/begin_frame_source.h b/cc/scheduler/begin_frame_source.h
deleted file mode 100644
index d15139d..0000000
--- a/cc/scheduler/begin_frame_source.h
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
-#define CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
-
-#include <set>
-#include <string>
-
-#include "base/logging.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/output/vsync_parameter_observer.h"
-#include "cc/scheduler/delay_based_time_source.h"
-
-namespace cc {
-
-// (Pure) Interface for observing BeginFrame messages from BeginFrameSource
-// objects.
-class BeginFrameObserver {
- public:
-  virtual ~BeginFrameObserver() {}
-
-  // The |args| given to OnBeginFrame is guaranteed to have
-  // |args|.IsValid()==true and have |args|.frame_time
-  // field be strictly greater than the previous call.
-  //
-  // Side effects: This function can (and most of the time *will*) change the
-  // return value of the LastUsedBeginFrameArgs method. See the documentation
-  // on that method for more information.
-  virtual void OnBeginFrame(const BeginFrameArgs& args) = 0;
-
-  // Returns the last BeginFrameArgs used by the observer. This method's return
-  // value is affected by the OnBeginFrame method!
-  //
-  //  - Before the first call of OnBeginFrame, this method should return a
-  //    BeginFrameArgs on which IsValid() returns false.
-  //
-  //  - If the |args| passed to OnBeginFrame is (or *will be*) used, then
-  //    LastUsedBeginFrameArgs return value should become the |args| given to
-  //    OnBeginFrame.
-  //
-  //  - If the |args| passed to OnBeginFrame is dropped, then
-  //    LastUsedBeginFrameArgs return value should *not* change.
-  //
-  // These requirements are designed to allow chaining and nesting of
-  // BeginFrameObservers which filter the incoming BeginFrame messages while
-  // preventing "double dropping" and other bad side effects.
-  virtual const BeginFrameArgs LastUsedBeginFrameArgs() const = 0;
-
-  // Tracing support
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
-};
-
-// Simple mix in which implements a BeginFrameObserver which checks the
-// incoming values meet the BeginFrameObserver requirements and implements the
-// required LastUsedBeginFrameArgs behaviour.
-//
-// Users of this mix in should;
-//  - Implement the OnBeginFrameMixInDelegate function.
-//  - Recommended (but not required) to call
-//    BeginFrameObserverMixIn::OnValueInto in their overridden OnValueInto
-//    function.
-class BeginFrameObserverMixIn : public BeginFrameObserver {
- public:
-  BeginFrameObserverMixIn();
-
-  // BeginFrameObserver
-
-  // Traces |args| and DCHECK |args| satisfies pre-conditions then calls
-  // OnBeginFrameMixInDelegate and updates the last_begin_frame_args_ value on
-  // true.
-  void OnBeginFrame(const BeginFrameArgs& args) override;
-  const BeginFrameArgs LastUsedBeginFrameArgs() const override;
-
-  // Outputs last_begin_frame_args_
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- protected:
-  // Subclasses should override this method!
-  // Return true if the given argument is (or will be) used.
-  virtual bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) = 0;
-
-  BeginFrameArgs last_begin_frame_args_;
-  int64_t dropped_begin_frame_args_;
-};
-
-// Interface for a class which produces BeginFrame calls to a
-// BeginFrameObserver.
-//
-// BeginFrame calls *normally* occur just after a vsync interrupt when input
-// processing has been finished and provide information about the time values
-// of the vsync times. *However*, these values can be heavily modified or even
-// plain made up (when no vsync signal is available or vsync throttling is
-// turned off). See the BeginFrameObserver for information about the guarantees
-// all BeginFrameSources *must* provide.
-class BeginFrameSource {
- public:
-  virtual ~BeginFrameSource() {}
-
-  // SetNeedsBeginFrames is the on/off "switch" for the BeginFrameSource. When
-  // set to false no more BeginFrame messages should be sent to observer.
-  virtual bool NeedsBeginFrames() const = 0;
-  virtual void SetNeedsBeginFrames(bool needs_begin_frames) = 0;
-
-  // DidFinishFrame provides back pressure to a frame source about frame
-  // processing (rather than toggling SetNeedsBeginFrames every frame). It is
-  // used by systems like the BackToBackFrameSource to make sure only one frame
-  // is pending at a time.
-  virtual void DidFinishFrame(size_t remaining_frames) = 0;
-
-  // Add/Remove an observer from the source.
-  // *At the moment* only a single observer can be added to the source, however
-  // in the future this may be extended to allow multiple observers.
-  // If making this change, please use base::ObserverList to do so.
-  virtual void AddObserver(BeginFrameObserver* obs) = 0;
-  virtual void RemoveObserver(BeginFrameObserver* obs) = 0;
-
-  // Tells the Source that client is ready to handle BeginFrames messages.
-  virtual void SetClientReady() = 0;
-
-  // Tracing support - Recommend (but not required) to call this implementation
-  // in any override.
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const = 0;
-};
-
-// Simple mix in which implements a BeginFrameSource.
-// Implementation classes should:
-//  - Implement the pure virtual (Set)NeedsBeginFrames methods from
-//    BeginFrameSource.
-//  - Use the CallOnBeginFrame method to call to the observer(s).
-//  - Recommended (but not required) to call BeginFrameSourceMixIn::AsValueInto
-//    in their own AsValueInto implementation.
-class BeginFrameSourceMixIn : public BeginFrameSource {
- public:
-  ~BeginFrameSourceMixIn() override {}
-
-  // BeginFrameSource
-  bool NeedsBeginFrames() const final;
-  void SetNeedsBeginFrames(bool needs_begin_frames) final;
-  void DidFinishFrame(size_t remaining_frames) override {}
-  void AddObserver(BeginFrameObserver* obs) final;
-  void RemoveObserver(BeginFrameObserver* obs) final;
-  void SetClientReady() override {}
-
-  // Tracing support - Recommend (but not required) to call this implementation
-  // in any override.
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- protected:
-  BeginFrameSourceMixIn();
-
-  // These methods should be used by subclasses to make the call to the
-  // observers.
-  void CallOnBeginFrame(const BeginFrameArgs& args);
-
-  // This method should be overridden if you want to change some behaviour on
-  // needs_begin_frames change.
-  virtual void OnNeedsBeginFramesChange(bool needs_begin_frames) {}
-
-  BeginFrameObserver* observer_;
-  bool needs_begin_frames_;
-
- private:
-  bool inside_as_value_into_;
-};
-
-// A frame source which calls BeginFrame (at the next possible time) as soon as
-// remaining frames reaches zero.
-class BackToBackBeginFrameSource : public BeginFrameSourceMixIn {
- public:
-  static scoped_ptr<BackToBackBeginFrameSource> Create(
-      base::SingleThreadTaskRunner* task_runner);
-  ~BackToBackBeginFrameSource() override;
-
-  // BeginFrameSource
-  void DidFinishFrame(size_t remaining_frames) override;
-
-  // Tracing
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- protected:
-  explicit BackToBackBeginFrameSource(
-      base::SingleThreadTaskRunner* task_runner);
-  virtual base::TimeTicks Now();  // Now overridable for testing
-
-  base::SingleThreadTaskRunner* task_runner_;
-
-  bool send_begin_frame_posted_;
-
-  // BeginFrameSourceMixIn
-  void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
-  void BeginFrame();
-
- private:
-  base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_;
-};
-
-// A frame source which is locked to an external parameters provides from a
-// vsync source and generates BeginFrameArgs for it.
-class SyntheticBeginFrameSource : public BeginFrameSourceMixIn,
-                                  public VSyncParameterObserver,
-                                  public TimeSourceClient {
- public:
-  static scoped_ptr<SyntheticBeginFrameSource> Create(
-      base::SingleThreadTaskRunner* task_runner,
-      base::TimeTicks initial_vsync_timebase,
-      base::TimeDelta initial_vsync_interval);
-  ~SyntheticBeginFrameSource() override;
-
-  // Tracing
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
-  // VSyncParameterObserver
-  void OnUpdateVSyncParameters(base::TimeTicks new_vsync_timebase,
-                               base::TimeDelta new_vsync_interval) override;
-
-  // TimeSourceClient
-  void OnTimerTick() override;
-
- protected:
-  explicit SyntheticBeginFrameSource(
-      scoped_refptr<DelayBasedTimeSource> time_source);
-
-  BeginFrameArgs CreateBeginFrameArgs(base::TimeTicks frame_time,
-                                      BeginFrameArgs::BeginFrameArgsType type);
-
-  // BeginFrameSourceMixIn
-  void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
-  scoped_refptr<DelayBasedTimeSource> time_source_;
-};
-
-// A "virtual" frame source which lets you switch between multiple other frame
-// sources while making sure the BeginFrameArgs stays increasing (possibly
-// enforcing minimum boundry between BeginFrameArgs messages).
-class BeginFrameSourceMultiplexer : public BeginFrameSourceMixIn,
-                                    public BeginFrameObserver {
- public:
-  static scoped_ptr<BeginFrameSourceMultiplexer> Create();
-  ~BeginFrameSourceMultiplexer() override;
-
-  void SetMinimumInterval(base::TimeDelta new_minimum_interval);
-
-  void AddSource(BeginFrameSource* new_source);
-  void RemoveSource(BeginFrameSource* existing_source);
-  void SetActiveSource(BeginFrameSource* new_source);
-  const BeginFrameSource* ActiveSource();
-
-  // BeginFrameObserver
-  // The mux is an BeginFrameObserver as it needs to proxy the OnBeginFrame
-  // calls to preserve the monotonicity of the BeginFrameArgs when switching
-  // sources.
-  void OnBeginFrame(const BeginFrameArgs& args) override;
-  const BeginFrameArgs LastUsedBeginFrameArgs() const override;
-
-  // BeginFrameSource
-  void DidFinishFrame(size_t remaining_frames) override;
-
-  // BeginFrameSourceMixIn
-  void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
-  // Tracing
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
- protected:
-  BeginFrameSourceMultiplexer();
-  explicit BeginFrameSourceMultiplexer(base::TimeDelta minimum_interval);
-
-  bool HasSource(BeginFrameSource* source);
-  bool IsIncreasing(const BeginFrameArgs& args);
-
-  base::TimeDelta minimum_interval_;
-
-  BeginFrameSource* active_source_;
-  std::set<BeginFrameSource*> source_list_;
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_BEGIN_FRAME_SOURCE_H_
diff --git a/cc/scheduler/begin_frame_source_unittest.cc b/cc/scheduler/begin_frame_source_unittest.cc
deleted file mode 100644
index 22126be..0000000
--- a/cc/scheduler/begin_frame_source_unittest.cc
+++ /dev/null
@@ -1,775 +0,0 @@
-// Copyright 2011 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.
-
-#include <deque>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/gtest_prod_util.h"
-#include "base/test/test_simple_task_runner.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "cc/test/scheduler_test_common.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Macros to help set up expected calls on the MockBeginFrameObserver.
-#define EXPECT_BEGIN_FRAME_DROP(obs, frame_time, deadline, interval)       \
-  {                                                                        \
-    ::testing::Expectation exp =                                           \
-        EXPECT_CALL((obs), OnBeginFrame(CreateBeginFrameArgsForTesting(    \
-                               BEGINFRAME_FROM_HERE, frame_time, deadline, \
-                               interval))).InSequence((obs).sequence);     \
-  }
-
-#define EXPECT_BEGIN_FRAME_USED(obs, frame_time, deadline, interval)       \
-  {                                                                        \
-    BeginFrameArgs args = CreateBeginFrameArgsForTesting(                  \
-        BEGINFRAME_FROM_HERE, frame_time, deadline, interval);             \
-    ::testing::Expectation exp =                                           \
-        EXPECT_CALL((obs), OnBeginFrame(args)).InSequence((obs).sequence); \
-    EXPECT_CALL((obs), LastUsedBeginFrameArgs())                           \
-        .Times(::testing::AnyNumber())                                     \
-        .After(exp)                                                        \
-        .WillRepeatedly(::testing::Return(args));                          \
-  }
-
-// Macros to send BeginFrameArgs on a FakeBeginFrameSink (and verify resulting
-// observer behaviour).
-#define SEND_BEGIN_FRAME(args_equal_to, source, frame_time, deadline, \
-                         interval)                                    \
-  {                                                                   \
-    BeginFrameArgs old_args = (source).TestLastUsedBeginFrameArgs();  \
-    BeginFrameArgs new_args = CreateBeginFrameArgsForTesting(         \
-        BEGINFRAME_FROM_HERE, frame_time, deadline, interval);        \
-    ASSERT_FALSE(old_args == new_args);                               \
-    (source).TestOnBeginFrame(new_args);                              \
-    EXPECT_EQ(args_equal_to, (source).TestLastUsedBeginFrameArgs());  \
-  }
-
-// When dropping LastUsedBeginFrameArgs **shouldn't** change.
-#define SEND_BEGIN_FRAME_DROP(source, frame_time, deadline, interval) \
-  SEND_BEGIN_FRAME(old_args, source, frame_time, deadline, interval);
-
-// When used LastUsedBeginFrameArgs **should** be updated.
-#define SEND_BEGIN_FRAME_USED(source, frame_time, deadline, interval) \
-  SEND_BEGIN_FRAME(new_args, source, frame_time, deadline, interval);
-
-namespace cc {
-namespace {
-
-class MockBeginFrameObserver : public BeginFrameObserver {
- public:
-  MOCK_METHOD1(OnBeginFrame, void(const BeginFrameArgs&));
-  MOCK_CONST_METHOD0(LastUsedBeginFrameArgs, const BeginFrameArgs());
-
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const {
-    dict->SetString("type", "MockBeginFrameObserver");
-    dict->BeginDictionary("last_begin_frame_args");
-    LastUsedBeginFrameArgs().AsValueInto(dict);
-    dict->EndDictionary();
-  }
-
-  // A value different from the normal default returned by a BeginFrameObserver
-  // so it is easiable traced back here.
-  static const BeginFrameArgs kDefaultBeginFrameArgs;
-
-  MockBeginFrameObserver() {
-    // Set a "default" value returned by LastUsedBeginFrameArgs so that gMock
-    // doesn't fail an assert and instead returns useful information.
-    EXPECT_CALL(*this, LastUsedBeginFrameArgs())
-        .Times(::testing::AnyNumber())
-        .InSequence(sequence)
-        .WillRepeatedly(::testing::Return(kDefaultBeginFrameArgs));
-  }
-  virtual ~MockBeginFrameObserver() {}
-
-  ::testing::Sequence sequence;
-};
-
-TEST(MockBeginFrameObserverTest, ExpectOnBeginFrame) {
-  ::testing::NiceMock<MockBeginFrameObserver> obs;
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
-  EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
-            MockBeginFrameObserver::kDefaultBeginFrameArgs);
-
-  obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
-      BEGINFRAME_FROM_HERE, 100, 200,
-      300));  // One call to LastUsedBeginFrameArgs
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300));
-
-  obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
-      BEGINFRAME_FROM_HERE, 400, 600,
-      300));  // Multiple calls to LastUsedBeginFrameArgs
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300));
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300));
-
-  obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
-      BEGINFRAME_FROM_HERE, 700, 900,
-      300));  // No calls to LastUsedBeginFrameArgs
-}
-
-TEST(MockBeginFrameObserverTest, ExpectOnBeginFrameStatus) {
-  ::testing::NiceMock<MockBeginFrameObserver> obs;
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
-  EXPECT_EQ(obs.LastUsedBeginFrameArgs(),
-            MockBeginFrameObserver::kDefaultBeginFrameArgs);
-
-  // Used
-  obs.OnBeginFrame(
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300));
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300));
-
-  // Dropped
-  obs.OnBeginFrame(
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 400, 600, 300));
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300));
-
-  // Dropped
-  obs.OnBeginFrame(
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 450, 650, 300));
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300));
-
-  // Used
-  obs.OnBeginFrame(
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300));
-  EXPECT_EQ(
-      obs.LastUsedBeginFrameArgs(),
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 700, 900, 300));
-}
-
-const BeginFrameArgs MockBeginFrameObserver::kDefaultBeginFrameArgs =
-    CreateBeginFrameArgsForTesting(
-#ifdef NDEBUG
-        nullptr,
-#else
-        FROM_HERE_WITH_EXPLICIT_FUNCTION(
-            "MockBeginFrameObserver::kDefaultBeginFrameArgs"),
-#endif
-        -1,
-        -1,
-        -1);
-
-// BeginFrameObserverMixIn testing ---------------------------------------
-class MockMinimalBeginFrameObserverMixIn : public BeginFrameObserverMixIn {
- public:
-  MOCK_METHOD1(OnBeginFrameMixInDelegate, bool(const BeginFrameArgs&));
-  int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
-};
-
-TEST(BeginFrameObserverMixInTest, OnBeginFrameImplementation) {
-  using ::testing::Return;
-  MockMinimalBeginFrameObserverMixIn obs;
-  ::testing::InSequence ordered;  // These calls should be ordered
-
-  // Initial conditions
-  EXPECT_EQ(BeginFrameArgs(), obs.LastUsedBeginFrameArgs());
-  EXPECT_EQ(0, obs.dropped_begin_frame_args());
-
-#ifndef NDEBUG
-  EXPECT_DEATH({ obs.OnBeginFrame(BeginFrameArgs()); }, "");
-#endif
-
-  BeginFrameArgs args1 =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 100, 200, 300);
-  EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args1)).WillOnce(Return(true));
-  obs.OnBeginFrame(args1);
-  EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
-  EXPECT_EQ(0, obs.dropped_begin_frame_args());
-
-#ifndef NDEBUG
-  EXPECT_DEATH({
-                 obs.OnBeginFrame(CreateBeginFrameArgsForTesting(
-                     BEGINFRAME_FROM_HERE, 50, 200, 300));
-               },
-               "");
-#endif
-
-  // Returning false shouldn't update the LastUsedBeginFrameArgs value.
-  BeginFrameArgs args2 =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 200, 300, 400);
-  EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args2)).WillOnce(Return(false));
-  obs.OnBeginFrame(args2);
-  EXPECT_EQ(args1, obs.LastUsedBeginFrameArgs());
-  EXPECT_EQ(1, obs.dropped_begin_frame_args());
-
-  BeginFrameArgs args3 =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 150, 300, 400);
-  EXPECT_CALL(obs, OnBeginFrameMixInDelegate(args3)).WillOnce(Return(true));
-  obs.OnBeginFrame(args3);
-  EXPECT_EQ(args3, obs.LastUsedBeginFrameArgs());
-  EXPECT_EQ(1, obs.dropped_begin_frame_args());
-}
-
-// BeginFrameSource testing ----------------------------------------------
-TEST(BeginFrameSourceMixInTest, ObserverManipulation) {
-  MockBeginFrameObserver obs;
-  MockBeginFrameObserver otherObs;
-  FakeBeginFrameSource source;
-
-  source.AddObserver(&obs);
-  EXPECT_EQ(&obs, source.GetObserver());
-
-#ifndef NDEBUG
-  // Adding an observer when an observer already exists should DCHECK fail.
-  EXPECT_DEATH({ source.AddObserver(&otherObs); }, "");
-
-  // Removing wrong observer should DCHECK fail.
-  EXPECT_DEATH({ source.RemoveObserver(&otherObs); }, "");
-
-  // Removing an observer when there is no observer should DCHECK fail.
-  EXPECT_DEATH({
-                 source.RemoveObserver(&obs);
-                 source.RemoveObserver(&obs);
-               },
-               "");
-#endif
-  source.RemoveObserver(&obs);
-
-  source.AddObserver(&otherObs);
-  EXPECT_EQ(&otherObs, source.GetObserver());
-  source.RemoveObserver(&otherObs);
-}
-
-TEST(BeginFrameSourceMixInTest, Observer) {
-  FakeBeginFrameSource source;
-  MockBeginFrameObserver obs;
-  source.AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_DROP(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_DROP(obs, 450, 650, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
-  SEND_BEGIN_FRAME_USED(source, 100, 200, 300);
-  SEND_BEGIN_FRAME_DROP(source, 400, 600, 300);
-  SEND_BEGIN_FRAME_DROP(source, 450, 650, 300);
-  SEND_BEGIN_FRAME_USED(source, 700, 900, 300);
-}
-
-TEST(BeginFrameSourceMixInTest, NoObserver) {
-  FakeBeginFrameSource source;
-  SEND_BEGIN_FRAME_DROP(source, 100, 200, 300);
-}
-
-TEST(BeginFrameSourceMixInTest, NeedsBeginFrames) {
-  FakeBeginFrameSource source;
-  EXPECT_FALSE(source.NeedsBeginFrames());
-  source.SetNeedsBeginFrames(true);
-  EXPECT_TRUE(source.NeedsBeginFrames());
-  source.SetNeedsBeginFrames(false);
-  EXPECT_FALSE(source.NeedsBeginFrames());
-}
-
-class LoopingBeginFrameObserver : public BeginFrameObserverMixIn {
- public:
-  BeginFrameSource* source_;
-
-  void AsValueInto(base::trace_event::TracedValue* dict) const override {
-    dict->SetString("type", "LoopingBeginFrameObserver");
-    dict->BeginDictionary("source");
-    source_->AsValueInto(dict);
-    dict->EndDictionary();
-  }
-
- protected:
-  // BeginFrameObserverMixIn
-  bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) override {
-    return true;
-  }
-};
-
-TEST(BeginFrameSourceMixInTest, DetectAsValueIntoLoop) {
-  LoopingBeginFrameObserver obs;
-  FakeBeginFrameSource source;
-
-  obs.source_ = &source;
-  source.AddObserver(&obs);
-
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  source.AsValueInto(state.get());
-}
-
-// BackToBackBeginFrameSource testing -----------------------------------------
-class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
- public:
-  static scoped_ptr<TestBackToBackBeginFrameSource> Create(
-      scoped_refptr<TestNowSource> now_src,
-      base::SingleThreadTaskRunner* task_runner) {
-    return make_scoped_ptr(
-        new TestBackToBackBeginFrameSource(now_src, task_runner));
-  }
-
- protected:
-  TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
-                                 base::SingleThreadTaskRunner* task_runner)
-      : BackToBackBeginFrameSource(task_runner), now_src_(now_src) {}
-
-  base::TimeTicks Now() override { return now_src_->Now(); }
-
-  scoped_refptr<TestNowSource> now_src_;
-};
-
-class BackToBackBeginFrameSourceTest : public ::testing::Test {
- public:
-  static const int64_t kDeadline;
-  static const int64_t kInterval;
-
-  scoped_refptr<TestNowSource> now_src_;
-  scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
-  scoped_ptr<TestBackToBackBeginFrameSource> source_;
-  scoped_ptr<MockBeginFrameObserver> obs_;
-
-  void SetUp() override {
-    now_src_ = TestNowSource::Create(1000);
-    task_runner_ =
-        make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
-    task_runner_->SetRunTaskLimit(1);
-    source_ =
-        TestBackToBackBeginFrameSource::Create(now_src_, task_runner_.get());
-    obs_ = make_scoped_ptr(new ::testing::StrictMock<MockBeginFrameObserver>());
-    source_->AddObserver(obs_.get());
-  }
-
-  void TearDown() override { obs_.reset(); }
-};
-
-const int64_t BackToBackBeginFrameSourceTest::kDeadline =
-    BeginFrameArgs::DefaultInterval().ToInternalValue();
-
-const int64_t BackToBackBeginFrameSourceTest::kInterval =
-    BeginFrameArgs::DefaultInterval().ToInternalValue();
-
-TEST_F(BackToBackBeginFrameSourceTest, SetNeedsBeginFramesSendsBeginFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  EXPECT_TRUE(task_runner_->HasPendingTasks());
-  task_runner_->RunUntilIdle();
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest,
-       DidFinishFrameThenSetNeedsBeginFramesProducesNoFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  source_->SetNeedsBeginFrames(false);
-  source_->DidFinishFrame(0);
-
-  EXPECT_FALSE(task_runner_->HasPendingTasks());
-}
-
-TEST_F(BackToBackBeginFrameSourceTest,
-       SetNeedsBeginFramesThenDidFinishFrameProducesNoFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  source_->SetNeedsBeginFrames(false);
-
-  EXPECT_TRUE(task_runner_->HasPendingTasks());
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest,
-       DidFinishFrameThenTogglingSetNeedsBeginFramesProducesCorrectFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-
-  source_->SetNeedsBeginFrames(false);
-  now_src_->AdvanceNowMicroseconds(10);
-  source_->DidFinishFrame(0);
-  now_src_->AdvanceNowMicroseconds(10);
-  source_->SetNeedsBeginFrames(false);
-  now_src_->AdvanceNowMicroseconds(10);
-  source_->SetNeedsBeginFrames(true);
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
-  EXPECT_TRUE(task_runner_->HasPendingTasks());
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest,
-       TogglingSetNeedsBeginFramesThenDidFinishFrameProducesCorrectFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  now_src_->AdvanceNowMicroseconds(10);
-  source_->SetNeedsBeginFrames(false);
-  now_src_->AdvanceNowMicroseconds(10);
-  source_->SetNeedsBeginFrames(true);
-  now_src_->AdvanceNowMicroseconds(10);
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1130, 1130 + kDeadline, kInterval);
-  EXPECT_TRUE(task_runner_->HasPendingTasks());
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameNeedsBeginFrameFalse) {
-  source_->SetNeedsBeginFrames(false);
-  source_->DidFinishFrame(0);
-  EXPECT_FALSE(task_runner_->RunPendingTasks());
-}
-
-TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameRemainingFrames) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-
-  source_->DidFinishFrame(3);
-  EXPECT_FALSE(task_runner_->HasPendingTasks());
-  source_->DidFinishFrame(2);
-  EXPECT_FALSE(task_runner_->HasPendingTasks());
-  source_->DidFinishFrame(1);
-  EXPECT_FALSE(task_runner_->HasPendingTasks());
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
-  source_->DidFinishFrame(0);
-  EXPECT_EQ(base::TimeDelta(), task_runner_->DelayToNextTaskTime());
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest, DidFinishFrameMultipleCallsIdempotent) {
-  source_->SetNeedsBeginFrames(true);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  source_->DidFinishFrame(0);
-  source_->DidFinishFrame(0);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1100, 1100 + kDeadline, kInterval);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  source_->DidFinishFrame(0);
-  source_->DidFinishFrame(0);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1200, 1200 + kDeadline, kInterval);
-  task_runner_->RunUntilIdle();
-}
-
-TEST_F(BackToBackBeginFrameSourceTest, DelayInPostedTaskProducesCorrectFrame) {
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1000, 1000 + kDeadline, kInterval);
-  source_->SetNeedsBeginFrames(true);
-  task_runner_->RunUntilIdle();
-
-  now_src_->AdvanceNowMicroseconds(100);
-  source_->DidFinishFrame(0);
-  now_src_->AdvanceNowMicroseconds(50);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 1150, 1150 + kDeadline, kInterval);
-
-  EXPECT_TRUE(task_runner_->HasPendingTasks());
-  task_runner_->RunUntilIdle();
-}
-
-// SyntheticBeginFrameSource testing ------------------------------------------
-class SyntheticBeginFrameSourceTest : public ::testing::Test {
- public:
-  scoped_refptr<TestNowSource> now_src_;
-  scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
-  scoped_ptr<TestSyntheticBeginFrameSource> source_;
-  scoped_ptr<MockBeginFrameObserver> obs_;
-
-  void SetUp() override {
-    now_src_ = TestNowSource::Create(1000);
-    task_runner_ =
-        make_scoped_refptr(new OrderedSimpleTaskRunner(now_src_, false));
-    source_ = TestSyntheticBeginFrameSource::Create(
-        now_src_, task_runner_.get(), base::TimeDelta::FromMicroseconds(10000));
-    obs_ = make_scoped_ptr(new MockBeginFrameObserver());
-    source_->AddObserver(obs_.get());
-  }
-
-  void TearDown() override { obs_.reset(); }
-};
-
-TEST_F(SyntheticBeginFrameSourceTest,
-       SetNeedsBeginFramesCallsOnBeginFrameWithMissedTick) {
-  now_src_->SetNowMicroseconds(10010);
-  EXPECT_CALL((*obs_), OnBeginFrame(CreateBeginFrameArgsForTesting(
-                           BEGINFRAME_FROM_HERE, 10000, 20000, 10000,
-                           BeginFrameArgs::MISSED)));
-  source_->SetNeedsBeginFrames(true);  // Should cause the last tick to be sent
-  // No tasks should need to be run for this to occur.
-}
-
-TEST_F(SyntheticBeginFrameSourceTest,
-       SetNeedsBeginFramesCallsCausesOnBeginFrame) {
-  source_->SetNeedsBeginFrames(true);
-  EXPECT_EQ(10000, task_runner_->NextTaskTime().ToInternalValue());
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
-  now_src_->SetNowMicroseconds(10010);
-  task_runner_->RunPendingTasks();
-}
-
-TEST_F(SyntheticBeginFrameSourceTest, BasicOperation) {
-  task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
-  source_->SetNeedsBeginFrames(true);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 30000, 40000, 10000);
-  task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
-
-  source_->SetNeedsBeginFrames(false);
-  // No new frames....
-  task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
-}
-
-TEST_F(SyntheticBeginFrameSourceTest, VSyncChanges) {
-  task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-  source_->SetNeedsBeginFrames(true);
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 10000, 20000, 10000);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 20000, 30000, 10000);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 30000, 40000, 10000);
-  task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(30001));
-
-  // Update the vsync information
-  source_->OnUpdateVSyncParameters(base::TimeTicks::FromInternalValue(27500),
-                                   base::TimeDelta::FromMicroseconds(10001));
-
-  EXPECT_BEGIN_FRAME_USED(*obs_, 40000, 47502, 10001);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 47502, 57503, 10001);
-  EXPECT_BEGIN_FRAME_USED(*obs_, 57503, 67504, 10001);
-  task_runner_->RunUntilTime(base::TimeTicks::FromInternalValue(60000));
-}
-
-// BeginFrameSourceMultiplexer testing -----------------------------------
-class BeginFrameSourceMultiplexerTest : public ::testing::Test {
- protected:
-  void SetUp() override {
-    mux_ = BeginFrameSourceMultiplexer::Create();
-
-    source1_store_ = make_scoped_ptr(new FakeBeginFrameSource());
-    source2_store_ = make_scoped_ptr(new FakeBeginFrameSource());
-    source3_store_ = make_scoped_ptr(new FakeBeginFrameSource());
-
-    source1_ = source1_store_.get();
-    source2_ = source2_store_.get();
-    source3_ = source3_store_.get();
-  }
-
-  void TearDown() override {
-    // Make sure the mux is torn down before the sources.
-    mux_.reset();
-  }
-
-  scoped_ptr<BeginFrameSourceMultiplexer> mux_;
-  FakeBeginFrameSource* source1_;
-  FakeBeginFrameSource* source2_;
-  FakeBeginFrameSource* source3_;
-
- private:
-  scoped_ptr<FakeBeginFrameSource> source1_store_;
-  scoped_ptr<FakeBeginFrameSource> source2_store_;
-  scoped_ptr<FakeBeginFrameSource> source3_store_;
-};
-
-TEST_F(BeginFrameSourceMultiplexerTest, SourcesManipulation) {
-  EXPECT_EQ(NULL, mux_->ActiveSource());
-
-  mux_->AddSource(source1_);
-  EXPECT_EQ(source1_, mux_->ActiveSource());
-
-  mux_->SetActiveSource(NULL);
-  EXPECT_EQ(NULL, mux_->ActiveSource());
-
-  mux_->SetActiveSource(source1_);
-
-#ifndef NDEBUG
-  // Setting a source which isn't in the mux as active should DCHECK fail.
-  EXPECT_DEATH({ mux_->SetActiveSource(source2_); }, "");
-
-  // Adding a source which is already added should DCHECK fail.
-  EXPECT_DEATH({ mux_->AddSource(source1_); }, "");
-
-  // Removing a source which isn't in the mux should DCHECK fail.
-  EXPECT_DEATH({ mux_->RemoveSource(source2_); }, "");
-
-  // Removing the active source fails
-  EXPECT_DEATH({ mux_->RemoveSource(source1_); }, "");
-#endif
-
-  // Test manipulation doesn't segfault.
-  mux_->AddSource(source2_);
-  mux_->RemoveSource(source2_);
-
-  mux_->AddSource(source2_);
-  mux_->SetActiveSource(source2_);
-  EXPECT_EQ(source2_, mux_->ActiveSource());
-
-  mux_->RemoveSource(source1_);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, NeedsBeginFrames) {
-  mux_->AddSource(source1_);
-  mux_->AddSource(source2_);
-  mux_->SetActiveSource(source1_);
-  EXPECT_EQ(source1_->NeedsBeginFrames(), false);
-  EXPECT_EQ(source2_->NeedsBeginFrames(), false);
-
-  // Check SetNeedsFrames works
-  mux_->SetNeedsBeginFrames(true);
-  EXPECT_EQ(source1_->NeedsBeginFrames(), true);
-  EXPECT_EQ(source2_->NeedsBeginFrames(), false);
-
-  mux_->SetNeedsBeginFrames(false);
-  EXPECT_EQ(source1_->NeedsBeginFrames(), false);
-  EXPECT_EQ(source2_->NeedsBeginFrames(), false);
-
-  // Checking that switching the source makes SetNeedsFrames on the
-  // subsources correctly.
-  mux_->SetNeedsBeginFrames(true);
-
-  mux_->SetActiveSource(source1_);
-  EXPECT_EQ(source1_->NeedsBeginFrames(), true);
-  EXPECT_EQ(source2_->NeedsBeginFrames(), false);
-
-  mux_->SetActiveSource(source2_);
-  EXPECT_EQ(source1_->NeedsBeginFrames(), false);
-  EXPECT_EQ(source2_->NeedsBeginFrames(), true);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesSimple) {
-  mux_->AddSource(source1_);
-  mux_->AddSource(source2_);
-  mux_->SetActiveSource(source1_);
-
-  MockBeginFrameObserver obs;
-  mux_->AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-
-  mux_->SetActiveSource(source1_);
-
-  SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
-  SEND_BEGIN_FRAME_DROP(*source2_, 200, 500, 300);
-
-  mux_->SetActiveSource(source2_);
-  SEND_BEGIN_FRAME_USED(*source2_, 400, 600, 300);
-  SEND_BEGIN_FRAME_DROP(*source1_, 500, 700, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, BeginFramesBackwardsProtection) {
-  mux_->AddSource(source1_);
-  mux_->AddSource(source2_);
-
-  MockBeginFrameObserver obs;
-  mux_->AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 1000, 1200, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 1001, 1201, 301);
-
-  mux_->SetActiveSource(source1_);
-  SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
-  SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-
-  mux_->SetActiveSource(source2_);
-  SEND_BEGIN_FRAME_DROP(*source2_, 699, 899, 300);
-  SEND_BEGIN_FRAME_USED(*source2_, 1000, 1200, 300);
-
-  mux_->SetActiveSource(source1_);
-  SEND_BEGIN_FRAME_USED(*source1_, 1001, 1201, 301);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalNegativeFails) {
-#ifndef NDEBUG
-  EXPECT_DEATH(
-      { mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(-100)); },
-      "");
-#endif
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalZero) {
-  mux_->SetMinimumInterval(base::TimeDelta());
-  mux_->AddSource(source1_);
-
-  MockBeginFrameObserver obs;
-  mux_->AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
-  SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
-  SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
-  SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalBasic) {
-  mux_->SetMinimumInterval(base::TimeDelta::FromInternalValue(600));
-  mux_->AddSource(source1_);
-
-  MockBeginFrameObserver obs;
-  mux_->AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 100, 200, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-
-  SEND_BEGIN_FRAME_USED(*source1_, 100, 200, 300);
-  SEND_BEGIN_FRAME_DROP(*source1_, 400, 600, 300);
-  SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-}
-
-TEST_F(BeginFrameSourceMultiplexerTest, MinimumIntervalWithMultipleSources) {
-  mux_->SetMinimumInterval(base::TimeDelta::FromMicroseconds(150));
-  mux_->AddSource(source1_);
-  mux_->AddSource(source2_);
-
-  MockBeginFrameObserver obs;
-  mux_->AddObserver(&obs);
-  EXPECT_BEGIN_FRAME_USED(obs, 400, 600, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 700, 900, 300);
-  EXPECT_BEGIN_FRAME_USED(obs, 1050, 1250, 300);
-
-  mux_->SetActiveSource(source1_);
-  SEND_BEGIN_FRAME_USED(*source1_, 400, 600, 300);
-  SEND_BEGIN_FRAME_USED(*source1_, 700, 900, 300);
-
-  mux_->SetActiveSource(source2_);
-  SEND_BEGIN_FRAME_DROP(*source2_, 750, 1050, 300);
-  SEND_BEGIN_FRAME_USED(*source2_, 1050, 1250, 300);
-
-  mux_->SetActiveSource(source1_);
-  SEND_BEGIN_FRAME_DROP(*source2_, 1100, 1400, 300);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/scheduler/commit_earlyout_reason.h b/cc/scheduler/commit_earlyout_reason.h
deleted file mode 100644
index 14aaeb3..0000000
--- a/cc/scheduler/commit_earlyout_reason.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SCHEDULER_COMMIT_EARLYOUT_REASON_H_
-#define CC_SCHEDULER_COMMIT_EARLYOUT_REASON_H_
-
-#include "base/logging.h"
-
-namespace cc {
-
-enum class CommitEarlyOutReason {
-  ABORTED_OUTPUT_SURFACE_LOST,
-  ABORTED_NOT_VISIBLE,
-  ABORTED_DEFERRED_COMMIT,
-  FINISHED_NO_UPDATES,
-};
-
-inline const char* CommitEarlyOutReasonToString(CommitEarlyOutReason reason) {
-  switch (reason) {
-    case CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST:
-      return "CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST";
-    case CommitEarlyOutReason::ABORTED_NOT_VISIBLE:
-      return "CommitEarlyOutReason::ABORTED_NOT_VISIBLE";
-    case CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT:
-      return "CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT";
-    case CommitEarlyOutReason::FINISHED_NO_UPDATES:
-      return "CommitEarlyOutReason::FINISHED_NO_UPDATES";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-inline bool CommitEarlyOutHandledCommit(CommitEarlyOutReason reason) {
-  return reason == CommitEarlyOutReason::FINISHED_NO_UPDATES;
-}
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_COMMIT_EARLYOUT_REASON_H_
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc
deleted file mode 100644
index ef43524..0000000
--- a/cc/scheduler/delay_based_time_source.cc
+++ /dev/null
@@ -1,301 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/delay_based_time_source.h"
-
-#include <algorithm>
-#include <cmath>
-#include <string>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-
-namespace cc {
-
-namespace {
-
-// kDoubleTickDivisor prevents ticks from running within the specified
-// fraction of an interval.  This helps account for jitter in the timebase as
-// well as quick timer reactivation.
-static const int kDoubleTickDivisor = 2;
-
-// kIntervalChangeThreshold is the fraction of the interval that will trigger an
-// immediate interval change.  kPhaseChangeThreshold is the fraction of the
-// interval that will trigger an immediate phase change.  If the changes are
-// within the thresholds, the change will take place on the next tick.  If
-// either change is outside the thresholds, the next tick will be canceled and
-// reissued immediately.
-static const double kIntervalChangeThreshold = 0.25;
-static const double kPhaseChangeThreshold = 0.25;
-
-}  // namespace
-
-// The following methods correspond to the DelayBasedTimeSource that uses
-// the base::TimeTicks::Now as the timebase.
-scoped_refptr<DelayBasedTimeSourceHighRes> DelayBasedTimeSourceHighRes::Create(
-    base::TimeDelta interval,
-    base::SingleThreadTaskRunner* task_runner) {
-  return make_scoped_refptr(
-      new DelayBasedTimeSourceHighRes(interval, task_runner));
-}
-
-DelayBasedTimeSourceHighRes::DelayBasedTimeSourceHighRes(
-    base::TimeDelta interval,
-    base::SingleThreadTaskRunner* task_runner)
-    : DelayBasedTimeSource(interval, task_runner) {
-}
-
-DelayBasedTimeSourceHighRes::~DelayBasedTimeSourceHighRes() {}
-
-base::TimeTicks DelayBasedTimeSourceHighRes::Now() const {
-  return base::TimeTicks::Now();
-}
-
-// The following methods correspond to the DelayBasedTimeSource that uses
-// the base::TimeTicks::Now as the timebase.
-scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create(
-    base::TimeDelta interval,
-    base::SingleThreadTaskRunner* task_runner) {
-  return make_scoped_refptr(new DelayBasedTimeSource(interval, task_runner));
-}
-
-DelayBasedTimeSource::DelayBasedTimeSource(
-    base::TimeDelta interval,
-    base::SingleThreadTaskRunner* task_runner)
-    : client_(NULL),
-      last_tick_time_(base::TimeTicks() - interval),
-      current_parameters_(interval, base::TimeTicks()),
-      next_parameters_(interval, base::TimeTicks()),
-      active_(false),
-      task_runner_(task_runner),
-      weak_factory_(this) {
-  DCHECK_GT(interval.ToInternalValue(), 0);
-}
-
-DelayBasedTimeSource::~DelayBasedTimeSource() {}
-
-base::TimeTicks DelayBasedTimeSource::SetActive(bool active) {
-  TRACE_EVENT1("cc", "DelayBasedTimeSource::SetActive", "active", active);
-  if (active == active_)
-    return base::TimeTicks();
-  active_ = active;
-
-  if (!active_) {
-    weak_factory_.InvalidateWeakPtrs();
-    return base::TimeTicks();
-  }
-
-  PostNextTickTask(Now());
-
-  // Determine if there was a tick that was missed while not active.
-  base::TimeTicks last_tick_time_if_always_active =
-    current_parameters_.tick_target - current_parameters_.interval;
-  base::TimeTicks new_tick_time_threshold =
-    last_tick_time_ + current_parameters_.interval / kDoubleTickDivisor;
-  if (last_tick_time_if_always_active >  new_tick_time_threshold) {
-    last_tick_time_ = last_tick_time_if_always_active;
-    return last_tick_time_;
-  }
-
-  return base::TimeTicks();
-}
-
-bool DelayBasedTimeSource::Active() const { return active_; }
-
-base::TimeTicks DelayBasedTimeSource::LastTickTime() const {
-  return last_tick_time_;
-}
-
-base::TimeTicks DelayBasedTimeSource::NextTickTime() const {
-  return Active() ? current_parameters_.tick_target : base::TimeTicks();
-}
-
-void DelayBasedTimeSource::OnTimerFired() {
-  DCHECK(active_);
-
-  last_tick_time_ = current_parameters_.tick_target;
-
-  PostNextTickTask(Now());
-
-  // Fire the tick.
-  if (client_)
-    client_->OnTimerTick();
-}
-
-void DelayBasedTimeSource::SetClient(TimeSourceClient* client) {
-  client_ = client;
-}
-
-void DelayBasedTimeSource::SetTimebaseAndInterval(base::TimeTicks timebase,
-                                                  base::TimeDelta interval) {
-  DCHECK_GT(interval.ToInternalValue(), 0);
-  next_parameters_.interval = interval;
-  next_parameters_.tick_target = timebase;
-
-  if (!active_) {
-    // If we aren't active, there's no need to reset the timer.
-    return;
-  }
-
-  // If the change in interval is larger than the change threshold,
-  // request an immediate reset.
-  double interval_delta =
-      std::abs((interval - current_parameters_.interval).InSecondsF());
-  double interval_change = interval_delta / interval.InSecondsF();
-  if (interval_change > kIntervalChangeThreshold) {
-    TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::IntervalChanged",
-                         TRACE_EVENT_SCOPE_THREAD);
-    SetActive(false);
-    SetActive(true);
-    return;
-  }
-
-  // If the change in phase is greater than the change threshold in either
-  // direction, request an immediate reset. This logic might result in a false
-  // negative if there is a simultaneous small change in the interval and the
-  // fmod just happens to return something near zero. Assuming the timebase
-  // is very recent though, which it should be, we'll still be ok because the
-  // old clock and new clock just happen to line up.
-  double target_delta =
-      std::abs((timebase - current_parameters_.tick_target).InSecondsF());
-  double phase_change =
-      fmod(target_delta, interval.InSecondsF()) / interval.InSecondsF();
-  if (phase_change > kPhaseChangeThreshold &&
-      phase_change < (1.0 - kPhaseChangeThreshold)) {
-    TRACE_EVENT_INSTANT0("cc", "DelayBasedTimeSource::PhaseChanged",
-                         TRACE_EVENT_SCOPE_THREAD);
-    SetActive(false);
-    SetActive(true);
-    return;
-  }
-}
-
-base::TimeTicks DelayBasedTimeSource::Now() const {
-  return base::TimeTicks::Now();
-}
-
-// This code tries to achieve an average tick rate as close to interval_ as
-// possible.  To do this, it has to deal with a few basic issues:
-//   1. PostDelayedTask can delay only at a millisecond granularity. So, 16.666
-//   has to posted as 16 or 17.
-//   2. A delayed task may come back a bit late (a few ms), or really late
-//   (frames later)
-//
-// The basic idea with this scheduler here is to keep track of where we *want*
-// to run in tick_target_. We update this with the exact interval.
-//
-// Then, when we post our task, we take the floor of (tick_target_ and Now()).
-// If we started at now=0, and 60FPs (all times in milliseconds):
-//      now=0    target=16.667   PostDelayedTask(16)
-//
-// When our callback runs, we figure out how far off we were from that goal.
-// Because of the flooring operation, and assuming our timer runs exactly when
-// it should, this yields:
-//      now=16   target=16.667
-//
-// Since we can't post a 0.667 ms task to get to now=16, we just treat this as a
-// tick. Then, we update target to be 33.333. We now post another task based on
-// the difference between our target and now:
-//      now=16   tick_target=16.667  new_target=33.333   -->
-//          PostDelayedTask(floor(33.333 - 16)) --> PostDelayedTask(17)
-//
-// Over time, with no late tasks, this leads to us posting tasks like this:
-//      now=0    tick_target=0       new_target=16.667   -->
-//          tick(), PostDelayedTask(16)
-//      now=16   tick_target=16.667  new_target=33.333   -->
-//          tick(), PostDelayedTask(17)
-//      now=33   tick_target=33.333  new_target=50.000   -->
-//          tick(), PostDelayedTask(17)
-//      now=50   tick_target=50.000  new_target=66.667   -->
-//          tick(), PostDelayedTask(16)
-//
-// We treat delays in tasks differently depending on the amount of delay we
-// encounter. Suppose we posted a task with a target=16.667:
-//   Case 1: late but not unrecoverably-so
-//      now=18 tick_target=16.667
-//
-//   Case 2: so late we obviously missed the tick
-//      now=25.0 tick_target=16.667
-//
-// We treat the first case as a tick anyway, and assume the delay was unusual.
-// Thus, we compute the new_target based on the old timebase:
-//      now=18   tick_target=16.667  new_target=33.333   -->
-//          tick(), PostDelayedTask(floor(33.333-18)) --> PostDelayedTask(15)
-// This brings us back to 18+15 = 33, which was where we would have been if the
-// task hadn't been late.
-//
-// For the really late delay, we we move to the next logical tick. The timebase
-// is not reset.
-//      now=37   tick_target=16.667  new_target=50.000  -->
-//          tick(), PostDelayedTask(floor(50.000-37)) --> PostDelayedTask(13)
-base::TimeTicks DelayBasedTimeSource::NextTickTarget(base::TimeTicks now) {
-  base::TimeTicks new_tick_target = now.SnappedToNextTick(
-      next_parameters_.tick_target, next_parameters_.interval);
-  DCHECK(now <= new_tick_target)
-      << "now = " << now.ToInternalValue()
-      << "; new_tick_target = " << new_tick_target.ToInternalValue()
-      << "; new_interval = " << next_parameters_.interval.InMicroseconds()
-      << "; tick_target = " << next_parameters_.tick_target.ToInternalValue();
-
-  // Avoid double ticks when:
-  // 1) Turning off the timer and turning it right back on.
-  // 2) Jittery data is passed to SetTimebaseAndInterval().
-  if (new_tick_target - last_tick_time_ <=
-      next_parameters_.interval / kDoubleTickDivisor)
-    new_tick_target += next_parameters_.interval;
-
-  return new_tick_target;
-}
-
-void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) {
-  base::TimeTicks new_tick_target = NextTickTarget(now);
-
-  // Post another task *before* the tick and update state
-  base::TimeDelta delay;
-  if (now <= new_tick_target)
-    delay = new_tick_target - now;
-  task_runner_->PostDelayedTask(FROM_HERE,
-                                base::Bind(&DelayBasedTimeSource::OnTimerFired,
-                                           weak_factory_.GetWeakPtr()),
-                                delay);
-
-  next_parameters_.tick_target = new_tick_target;
-  current_parameters_ = next_parameters_;
-}
-
-std::string DelayBasedTimeSource::TypeString() const {
-  return "DelayBasedTimeSource";
-}
-
-std::string DelayBasedTimeSourceHighRes::TypeString() const {
-  return "DelayBasedTimeSourceHighRes";
-}
-
-void DelayBasedTimeSource::AsValueInto(
-    base::trace_event::TracedValue* state) const {
-  state->SetString("type", TypeString());
-  state->SetDouble("last_tick_time_us", LastTickTime().ToInternalValue());
-  state->SetDouble("next_tick_time_us", NextTickTime().ToInternalValue());
-
-  state->BeginDictionary("current_parameters");
-  state->SetDouble("interval_us",
-                   current_parameters_.interval.InMicroseconds());
-  state->SetDouble("tick_target_us",
-                   current_parameters_.tick_target.ToInternalValue());
-  state->EndDictionary();
-
-  state->BeginDictionary("next_parameters");
-  state->SetDouble("interval_us", next_parameters_.interval.InMicroseconds());
-  state->SetDouble("tick_target_us",
-                   next_parameters_.tick_target.ToInternalValue());
-  state->EndDictionary();
-
-  state->SetBoolean("active", active_);
-}
-
-}  // namespace cc
diff --git a/cc/scheduler/delay_based_time_source.h b/cc/scheduler/delay_based_time_source.h
deleted file mode 100644
index 5fcf69d..0000000
--- a/cc/scheduler/delay_based_time_source.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_
-#define CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_
-
-#include <string>
-
-#include "base/memory/weak_ptr.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-class SingleThreadTaskRunner;
-}
-
-namespace cc {
-
-class TimeSourceClient {
- public:
-  virtual void OnTimerTick() = 0;
-
- protected:
-  virtual ~TimeSourceClient() {}
-};
-
-// This timer implements a time source that achieves the specified interval
-// in face of millisecond-precision delayed callbacks and random queueing
-// delays. DelayBasedTimeSource uses base::TimeTicks::Now as its timebase.
-class DelayBasedTimeSource : public base::RefCounted<DelayBasedTimeSource> {
- public:
-  static scoped_refptr<DelayBasedTimeSource> Create(
-      base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner);
-
-  virtual void SetClient(TimeSourceClient* client);
-
-  // TimeSource implementation
-  virtual void SetTimebaseAndInterval(base::TimeTicks timebase,
-                                      base::TimeDelta interval);
-  base::TimeDelta Interval() const { return next_parameters_.interval; }
-
-  virtual base::TimeTicks SetActive(bool active);
-  virtual bool Active() const;
-
-  // Get the last and next tick times. NextTickTime() returns null when
-  // inactive.
-  virtual base::TimeTicks LastTickTime() const;
-  virtual base::TimeTicks NextTickTime() const;
-
-  // Virtual for testing.
-  virtual base::TimeTicks Now() const;
-
-  virtual void AsValueInto(base::trace_event::TracedValue* dict) const;
-
- protected:
-  DelayBasedTimeSource(base::TimeDelta interval,
-                       base::SingleThreadTaskRunner* task_runner);
-  virtual ~DelayBasedTimeSource();
-
-  virtual std::string TypeString() const;
-
-  base::TimeTicks NextTickTarget(base::TimeTicks now);
-  void PostNextTickTask(base::TimeTicks now);
-  void OnTimerFired();
-
-  struct Parameters {
-    Parameters(base::TimeDelta interval, base::TimeTicks tick_target)
-        : interval(interval), tick_target(tick_target) {}
-    base::TimeDelta interval;
-    base::TimeTicks tick_target;
-  };
-
-  TimeSourceClient* client_;
-  base::TimeTicks last_tick_time_;
-
-  // current_parameters_ should only be written by PostNextTickTask.
-  // next_parameters_ will take effect on the next call to PostNextTickTask.
-  // Maintaining a pending set of parameters allows NextTickTime() to always
-  // reflect the actual time we expect OnTimerFired to be called.
-  Parameters current_parameters_;
-  Parameters next_parameters_;
-
-  bool active_;
-
-  base::SingleThreadTaskRunner* task_runner_;
-  base::WeakPtrFactory<DelayBasedTimeSource> weak_factory_;
-
- private:
-  friend class base::RefCounted<DelayBasedTimeSource>;
-  DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSource);
-};
-
-// DelayBasedTimeSource that once used base::TimeTicks::HighResNow as its time
-// source, but is now a no-op.
-// TODO(brianderson): Remove along with gfx::/FrameTime.http://crbug.com/447329
-class DelayBasedTimeSourceHighRes : public DelayBasedTimeSource {
- public:
-  static scoped_refptr<DelayBasedTimeSourceHighRes> Create(
-        base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner);
-
-  base::TimeTicks Now() const override;
-
- protected:
-  DelayBasedTimeSourceHighRes(base::TimeDelta interval,
-                              base::SingleThreadTaskRunner* task_runner);
-  ~DelayBasedTimeSourceHighRes() override;
-
-  std::string TypeString() const override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSourceHighRes);
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_DELAY_BASED_TIME_SOURCE_H_
diff --git a/cc/scheduler/delay_based_time_source_unittest.cc b/cc/scheduler/delay_based_time_source_unittest.cc
deleted file mode 100644
index f721b11..0000000
--- a/cc/scheduler/delay_based_time_source_unittest.cc
+++ /dev/null
@@ -1,528 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/delay_based_time_source.h"
-
-#include "base/basictypes.h"
-#include "base/test/test_simple_task_runner.h"
-#include "cc/test/scheduler_test_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-base::TimeDelta Interval() {
-  return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond /
-                                           60);
-}
-
-TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-
-  timer->SetActive(true);
-  EXPECT_TRUE(timer->Active());
-  EXPECT_TRUE(task_runner->HasPendingTask());
-
-  timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(16));
-  task_runner->RunPendingTasks();
-  EXPECT_TRUE(timer->Active());
-  EXPECT_TRUE(client.TickCalled());
-}
-
-TEST(DelayBasedTimeSourceTest, TickNotCalledWithTaskPosted) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  EXPECT_TRUE(task_runner->HasPendingTask());
-  timer->SetActive(false);
-  task_runner->RunPendingTasks();
-  EXPECT_FALSE(client.TickCalled());
-}
-
-TEST(DelayBasedTimeSourceTest, StartTwiceEnqueuesOneTask) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  EXPECT_TRUE(task_runner->HasPendingTask());
-  task_runner->ClearPendingTasks();
-  timer->SetActive(true);
-  EXPECT_FALSE(task_runner->HasPendingTask());
-}
-
-TEST(DelayBasedTimeSourceTest, StartWhenRunningDoesntTick) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  EXPECT_TRUE(task_runner->HasPendingTask());
-  task_runner->RunPendingTasks();
-  task_runner->ClearPendingTasks();
-  timer->SetActive(true);
-  EXPECT_FALSE(task_runner->HasPendingTask());
-}
-
-// At 60Hz, when the tick returns at exactly the requested next time, make sure
-// a 16ms next delay is posted.
-TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenExactlyOnRequestedTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  timer->SetNow(timer->Now() + Interval());
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-// At 60Hz, when the tick returns at slightly after the requested next time,
-// make sure a 16ms next delay is posted.
-TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenSlightlyAfterRequestedTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  timer->SetNow(timer->Now() + Interval() +
-                base::TimeDelta::FromMicroseconds(1));
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-// At 60Hz, when the tick returns at exactly 2*interval after the requested next
-// time, make sure a 0ms next delay is posted.
-TEST(DelayBasedTimeSourceTest,
-     NextDelaySaneWhenExactlyTwiceAfterRequestedTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  timer->SetNow(timer->Now() + 2 * Interval());
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(0, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-// At 60Hz, when the tick returns at 2*interval and a bit after the requested
-// next time, make sure a 16ms next delay is posted.
-TEST(DelayBasedTimeSourceTest,
-     NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  timer->SetNow(timer->Now() + 2 * Interval() +
-                base::TimeDelta::FromMicroseconds(1));
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-// At 60Hz, when the tick returns halfway to the next frame time, make sure
-// a correct next delay value is posted.
-TEST(DelayBasedTimeSourceTest, NextDelaySaneWhenHalfAfterRequestedTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  timer->SetNow(timer->Now() + Interval() +
-                base::TimeDelta::FromMilliseconds(8));
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-// If the timebase and interval are updated with a jittery source, we want to
-// make sure we do not double tick.
-TEST(DelayBasedTimeSourceTest, SaneHandlingOfJitteryTimebase) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Jitter timebase ~1ms late
-  timer->SetNow(timer->Now() + Interval());
-  timer->SetTimebaseAndInterval(
-      timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval());
-  task_runner->RunPendingTasks();
-
-  // Without double tick prevention, NextPendingTaskDelay would be 1.
-  EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Jitter timebase ~1ms early
-  timer->SetNow(timer->Now() + Interval());
-  timer->SetTimebaseAndInterval(
-      timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval());
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, HandlesSignificantTimebaseChangesImmediately) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick, then shift timebase by +7ms.
-  timer->SetNow(timer->Now() + Interval());
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  client.Reset();
-  task_runner->ClearPendingTasks();
-  task_runner->RunPendingTasks();
-  base::TimeDelta jitter = base::TimeDelta::FromMilliseconds(7) +
-                           base::TimeDelta::FromMicroseconds(1);
-  timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval());
-
-  EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
-  EXPECT_EQ(16 + 7, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick, then shift timebase by -7ms.
-  timer->SetNow(timer->Now() + Interval() + jitter);
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  client.Reset();
-  task_runner->ClearPendingTasks();
-  task_runner->RunPendingTasks();
-  timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval());
-
-  EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
-  EXPECT_EQ(16 - 7, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, HanldlesSignificantIntervalChangesImmediately) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick, then double the interval.
-  timer->SetNow(timer->Now() + Interval());
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  client.Reset();
-  task_runner->ClearPendingTasks();
-  task_runner->RunPendingTasks();
-  timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval() * 2);
-
-  EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
-  EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick, then halve the interval.
-  timer->SetNow(timer->Now() + Interval() * 2);
-  task_runner->RunPendingTasks();
-
-  EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  client.Reset();
-  task_runner->ClearPendingTasks();
-  task_runner->RunPendingTasks();
-  timer->SetTimebaseAndInterval(base::TimeTicks() + Interval() * 3, Interval());
-
-  EXPECT_FALSE(client.TickCalled());  // Make sure pending tasks were canceled.
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, JitteryRuntimeWithFutureTimebases) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-
-  // Run the first tick.
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  base::TimeTicks future_timebase = timer->Now() + Interval() * 10;
-
-  // 1ms jitter
-  base::TimeDelta jitter1 = base::TimeDelta::FromMilliseconds(1);
-
-  // Tick with +1ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter1);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter1);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with -1ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter1);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter1);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // 8 ms jitter
-  base::TimeDelta jitter8 = base::TimeDelta::FromMilliseconds(8);
-
-  // Tick with +8ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter8);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter8);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with -8ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter8);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(24, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter8);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // 15 ms jitter
-  base::TimeDelta jitter15  = base::TimeDelta::FromMilliseconds(15);
-
-  // Tick with +15ms jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter15);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(1, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter15);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with -15ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() - jitter15);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(31, task_runner->NextPendingTaskDelay().InMilliseconds());
-
-  // Tick with 0ms of jitter
-  future_timebase += Interval();
-  timer->SetTimebaseAndInterval(future_timebase, Interval());
-  timer->SetNow(timer->Now() + Interval() + jitter15);
-  task_runner->RunPendingTasks();
-  EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) {
-  int num_iterations = 10;
-
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);
-
-  double total_frame_time = 0.0;
-  for (int i = 0; i < num_iterations; ++i) {
-    int64 delay_ms = task_runner->NextPendingTaskDelay().InMilliseconds();
-
-    // accumulate the "delay"
-    total_frame_time += delay_ms / 1000.0;
-
-    // Run the callback exactly when asked
-    timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(delay_ms));
-    task_runner->RunPendingTasks();
-  }
-  double average_interval =
-      total_frame_time / static_cast<double>(num_iterations);
-  EXPECT_NEAR(1.0 / 60.0, average_interval, 0.1);
-}
-
-TEST(DelayBasedTimeSourceTest, TestDeactivateWhilePending) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-  timer->SetActive(true);  // Should post a task.
-  timer->SetActive(false);
-  timer = NULL;
-  // Should run the posted task without crashing.
-  EXPECT_TRUE(task_runner->HasPendingTask());
-  task_runner->RunPendingTasks();
-}
-
-TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateBeforeNextTickTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-
-  // Should run the activate task, and pick up a new timebase.
-  timer->SetActive(true);
-  task_runner->RunPendingTasks();
-
-  // Stop the timer
-  timer->SetActive(false);
-
-  // Task will be pending anyway, run it
-  task_runner->RunPendingTasks();
-
-  // Start the timer again, but before the next tick time the timer previously
-  // planned on using. That same tick time should still be targeted.
-  timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(4));
-  timer->SetActive(true);
-  EXPECT_EQ(12, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, TestDeactivateAndReactivateAfterNextTickTime) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-
-  // Should run the activate task, and pick up a new timebase.
-  timer->SetActive(true);
-  task_runner->RunPendingTasks();
-
-  // Stop the timer.
-  timer->SetActive(false);
-
-  // Task will be pending anyway, run it.
-  task_runner->RunPendingTasks();
-
-  // Start the timer again, but before the next tick time the timer previously
-  // planned on using. That same tick time should still be targeted.
-  timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(20));
-  timer->SetActive(true);
-  EXPECT_EQ(13, task_runner->NextPendingTaskDelay().InMilliseconds());
-}
-
-TEST(DelayBasedTimeSourceTest, TestReturnValueWhenTimerIsDeActivated) {
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner =
-      new base::TestSimpleTaskRunner;
-  FakeTimeSourceClient client;
-  scoped_refptr<FakeDelayBasedTimeSource> timer =
-      FakeDelayBasedTimeSource::Create(Interval(), task_runner.get());
-  timer->SetClient(&client);
-
-  timer->SetActive(true);
-  task_runner->RunPendingTasks();
-
-  // SetActive should return empty TimeTicks when the timer is deactivated.
-  base::TimeTicks missed_tick_time = timer->SetActive(false);
-  EXPECT_TRUE(missed_tick_time.is_null());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/scheduler/draw_result.h b/cc/scheduler/draw_result.h
deleted file mode 100644
index 0809a41..0000000
--- a/cc/scheduler/draw_result.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SCHEDULER_DRAW_RESULT_H_
-#define CC_SCHEDULER_DRAW_RESULT_H_
-
-namespace cc {
-
-enum DrawResult {
-  INVALID_RESULT,
-  DRAW_SUCCESS,
-  DRAW_ABORTED_CHECKERBOARD_ANIMATIONS,
-  DRAW_ABORTED_MISSING_HIGH_RES_CONTENT,
-  DRAW_ABORTED_CONTEXT_LOST,
-  DRAW_ABORTED_CANT_DRAW,
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_DRAW_RESULT_H_
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
deleted file mode 100644
index 0efaab9..0000000
--- a/cc/scheduler/scheduler.cc
+++ /dev/null
@@ -1,836 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/scheduler.h"
-
-#include <algorithm>
-
-#include "base/auto_reset.h"
-#include "base/logging.h"
-#include "base/profiler/scoped_tracker.h"
-#include "base/single_thread_task_runner.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "cc/debug/traced_value.h"
-#include "cc/scheduler/delay_based_time_source.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-
-BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
-    Scheduler* scheduler) {
-  if (scheduler->settings_.use_external_begin_frame_source) {
-    TRACE_EVENT1("cc",
-                 "Scheduler::Scheduler()",
-                 "PrimaryFrameSource",
-                 "ExternalBeginFrameSource");
-    DCHECK(scheduler->primary_frame_source_internal_)
-        << "Need external BeginFrameSource";
-    return scheduler->primary_frame_source_internal_.get();
-  } else {
-    TRACE_EVENT1("cc",
-                 "Scheduler::Scheduler()",
-                 "PrimaryFrameSource",
-                 "SyntheticBeginFrameSource");
-    scoped_ptr<SyntheticBeginFrameSource> synthetic_source =
-        SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
-                                          scheduler->Now(),
-                                          BeginFrameArgs::DefaultInterval());
-
-    DCHECK(!scheduler->vsync_observer_);
-    scheduler->vsync_observer_ = synthetic_source.get();
-
-    DCHECK(!scheduler->primary_frame_source_internal_);
-    scheduler->primary_frame_source_internal_ = synthetic_source.Pass();
-    return scheduler->primary_frame_source_internal_.get();
-  }
-}
-
-BeginFrameSource*
-SchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource(
-    Scheduler* scheduler) {
-  TRACE_EVENT1("cc",
-               "Scheduler::Scheduler()",
-               "BackgroundFrameSource",
-               "SyntheticBeginFrameSource");
-  DCHECK(!(scheduler->background_frame_source_internal_));
-  scheduler->background_frame_source_internal_ =
-      SyntheticBeginFrameSource::Create(
-          scheduler->task_runner_.get(), scheduler->Now(),
-          scheduler->settings_.background_frame_interval);
-  return scheduler->background_frame_source_internal_.get();
-}
-
-BeginFrameSource*
-SchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource(
-    Scheduler* scheduler) {
-  TRACE_EVENT1("cc", "Scheduler::Scheduler()", "UnthrottledFrameSource",
-               "BackToBackBeginFrameSource");
-  DCHECK(!scheduler->unthrottled_frame_source_internal_);
-  scheduler->unthrottled_frame_source_internal_ =
-      BackToBackBeginFrameSource::Create(scheduler->task_runner_.get());
-  return scheduler->unthrottled_frame_source_internal_.get();
-}
-
-Scheduler::Scheduler(
-    SchedulerClient* client,
-    const SchedulerSettings& scheduler_settings,
-    int layer_tree_host_id,
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
-    scoped_ptr<BeginFrameSource> external_begin_frame_source,
-    SchedulerFrameSourcesConstructor* frame_sources_constructor)
-    : frame_source_(),
-      primary_frame_source_(NULL),
-      background_frame_source_(NULL),
-      primary_frame_source_internal_(external_begin_frame_source.Pass()),
-      background_frame_source_internal_(),
-      vsync_observer_(NULL),
-      throttle_frame_production_(scheduler_settings.throttle_frame_production),
-      settings_(scheduler_settings),
-      client_(client),
-      layer_tree_host_id_(layer_tree_host_id),
-      task_runner_(task_runner),
-      state_machine_(scheduler_settings),
-      inside_process_scheduled_actions_(false),
-      inside_action_(SchedulerStateMachine::ACTION_NONE),
-      weak_factory_(this) {
-  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
-               "Scheduler::Scheduler",
-               "settings",
-               settings_.AsValue());
-  DCHECK(client_);
-  DCHECK(!state_machine_.BeginFrameNeeded());
-
-  begin_retro_frame_closure_ =
-      base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
-  begin_impl_frame_deadline_closure_ = base::Bind(
-      &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
-  poll_for_draw_triggers_closure_ = base::Bind(
-      &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
-  advance_commit_state_closure_ = base::Bind(
-      &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
-
-  frame_source_ = BeginFrameSourceMultiplexer::Create();
-  frame_source_->AddObserver(this);
-
-  // Primary frame source
-  primary_frame_source_ =
-      frame_sources_constructor->ConstructPrimaryFrameSource(this);
-  frame_source_->AddSource(primary_frame_source_);
-  primary_frame_source_->SetClientReady();
-
-  // Background ticking frame source
-  background_frame_source_ =
-      frame_sources_constructor->ConstructBackgroundFrameSource(this);
-  frame_source_->AddSource(background_frame_source_);
-
-  // Unthrottled frame source
-  unthrottled_frame_source_ =
-      frame_sources_constructor->ConstructUnthrottledFrameSource(this);
-  frame_source_->AddSource(unthrottled_frame_source_);
-}
-
-Scheduler::~Scheduler() {
-  if (frame_source_->NeedsBeginFrames())
-    frame_source_->SetNeedsBeginFrames(false);
-}
-
-base::TimeTicks Scheduler::Now() const {
-  base::TimeTicks now = gfx::FrameTime::Now();
-  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"),
-               "Scheduler::Now",
-               "now",
-               now);
-  return now;
-}
-
-void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
-                                      base::TimeDelta interval) {
-  // TODO(brianderson): We should not be receiving 0 intervals.
-  if (interval == base::TimeDelta())
-    interval = BeginFrameArgs::DefaultInterval();
-
-  if (vsync_observer_)
-    vsync_observer_->OnUpdateVSyncParameters(timebase, interval);
-}
-
-void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
-  DCHECK_GE(draw_time.ToInternalValue(), 0);
-  estimated_parent_draw_time_ = draw_time;
-}
-
-void Scheduler::SetCanStart() {
-  state_machine_.SetCanStart();
-  ProcessScheduledActions();
-}
-
-void Scheduler::UpdateActiveFrameSource() {
-  if (state_machine_.visible()) {
-    if (throttle_frame_production_) {
-      frame_source_->SetActiveSource(primary_frame_source_);
-    } else {
-      frame_source_->SetActiveSource(unthrottled_frame_source_);
-    }
-  } else {
-    frame_source_->SetActiveSource(background_frame_source_);
-  }
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetVisible(bool visible) {
-  state_machine_.SetVisible(visible);
-  UpdateActiveFrameSource();
-}
-
-void Scheduler::SetCanDraw(bool can_draw) {
-  state_machine_.SetCanDraw(can_draw);
-  ProcessScheduledActions();
-}
-
-void Scheduler::NotifyReadyToActivate() {
-  state_machine_.NotifyReadyToActivate();
-  ProcessScheduledActions();
-}
-
-void Scheduler::NotifyReadyToDraw() {
-  // Empty for now, until we take action based on the notification as part of
-  // crbugs 352894, 383157, 421923.
-}
-
-void Scheduler::SetThrottleFrameProduction(bool throttle) {
-  throttle_frame_production_ = throttle;
-  UpdateActiveFrameSource();
-}
-
-void Scheduler::SetNeedsCommit() {
-  state_machine_.SetNeedsCommit();
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetNeedsRedraw() {
-  state_machine_.SetNeedsRedraw();
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetNeedsAnimate() {
-  state_machine_.SetNeedsAnimate();
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetNeedsPrepareTiles() {
-  DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_PREPARE_TILES));
-  state_machine_.SetNeedsPrepareTiles();
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetMaxSwapsPending(int max) {
-  state_machine_.SetMaxSwapsPending(max);
-}
-
-void Scheduler::DidSwapBuffers() {
-  state_machine_.DidSwapBuffers();
-
-  // There is no need to call ProcessScheduledActions here because
-  // swapping should not trigger any new actions.
-  if (!inside_process_scheduled_actions_) {
-    DCHECK_EQ(state_machine_.NextAction(), SchedulerStateMachine::ACTION_NONE);
-  }
-}
-
-void Scheduler::DidSwapBuffersComplete() {
-  state_machine_.DidSwapBuffersComplete();
-  ProcessScheduledActions();
-}
-
-void Scheduler::SetImplLatencyTakesPriority(bool impl_latency_takes_priority) {
-  state_machine_.SetImplLatencyTakesPriority(impl_latency_takes_priority);
-  ProcessScheduledActions();
-}
-
-void Scheduler::NotifyReadyToCommit() {
-  TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
-  state_machine_.NotifyReadyToCommit();
-  ProcessScheduledActions();
-}
-
-void Scheduler::BeginMainFrameAborted(CommitEarlyOutReason reason) {
-  TRACE_EVENT1("cc", "Scheduler::BeginMainFrameAborted", "reason",
-               CommitEarlyOutReasonToString(reason));
-  state_machine_.BeginMainFrameAborted(reason);
-  ProcessScheduledActions();
-}
-
-void Scheduler::DidPrepareTiles() {
-  state_machine_.DidPrepareTiles();
-}
-
-void Scheduler::DidLoseOutputSurface() {
-  TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
-  begin_retro_frame_args_.clear();
-  begin_retro_frame_task_.Cancel();
-  state_machine_.DidLoseOutputSurface();
-  ProcessScheduledActions();
-}
-
-void Scheduler::DidCreateAndInitializeOutputSurface() {
-  TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
-  DCHECK(!frame_source_->NeedsBeginFrames());
-  DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
-  state_machine_.DidCreateAndInitializeOutputSurface();
-  ProcessScheduledActions();
-}
-
-void Scheduler::NotifyBeginMainFrameStarted() {
-  TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
-  state_machine_.NotifyBeginMainFrameStarted();
-}
-
-base::TimeTicks Scheduler::AnticipatedDrawTime() const {
-  if (!frame_source_->NeedsBeginFrames() ||
-      begin_impl_frame_args_.interval <= base::TimeDelta())
-    return base::TimeTicks();
-
-  base::TimeTicks now = Now();
-  base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
-                                      begin_impl_frame_args_.deadline);
-  int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
-  return timebase + (begin_impl_frame_args_.interval * intervals);
-}
-
-base::TimeTicks Scheduler::LastBeginImplFrameTime() {
-  return begin_impl_frame_args_.frame_time;
-}
-
-void Scheduler::SetupNextBeginFrameIfNeeded() {
-  // Never call SetNeedsBeginFrames if the frame source already has the right
-  // value.
-  if (frame_source_->NeedsBeginFrames() != state_machine_.BeginFrameNeeded()) {
-    if (state_machine_.BeginFrameNeeded()) {
-      // Call SetNeedsBeginFrames(true) as soon as possible.
-      frame_source_->SetNeedsBeginFrames(true);
-    } else if (state_machine_.begin_impl_frame_state() ==
-               SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
-      // Call SetNeedsBeginFrames(false) in between frames only.
-      frame_source_->SetNeedsBeginFrames(false);
-      client_->SendBeginMainFrameNotExpectedSoon();
-    }
-  }
-
-  PostBeginRetroFrameIfNeeded();
-}
-
-// We may need to poll when we can't rely on BeginFrame to advance certain
-// state or to avoid deadlock.
-void Scheduler::SetupPollingMechanisms() {
-  bool needs_advance_commit_state_timer = false;
-  // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
-  // aren't expecting any more BeginFrames. This should only be needed by
-  // the synchronous compositor when BeginFrameNeeded is false.
-  if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
-    DCHECK(!state_machine_.SupportsProactiveBeginFrame());
-    if (poll_for_draw_triggers_task_.IsCancelled()) {
-      poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
-      base::TimeDelta delay = begin_impl_frame_args_.IsValid()
-                                  ? begin_impl_frame_args_.interval
-                                  : BeginFrameArgs::DefaultInterval();
-      task_runner_->PostDelayedTask(
-          FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
-    }
-  } else {
-    poll_for_draw_triggers_task_.Cancel();
-
-    // At this point we'd prefer to advance through the commit flow by
-    // drawing a frame, however it's possible that the frame rate controller
-    // will not give us a BeginFrame until the commit completes.  See
-    // crbug.com/317430 for an example of a swap ack being held on commit. Thus
-    // we set a repeating timer to poll on ProcessScheduledActions until we
-    // successfully reach BeginFrame. Synchronous compositor does not use
-    // frame rate controller or have the circular wait in the bug.
-    if (IsBeginMainFrameSentOrStarted() &&
-        !settings_.using_synchronous_renderer_compositor) {
-      needs_advance_commit_state_timer = true;
-    }
-  }
-
-  if (needs_advance_commit_state_timer) {
-    if (advance_commit_state_task_.IsCancelled() &&
-        begin_impl_frame_args_.IsValid()) {
-      // Since we'd rather get a BeginImplFrame by the normal mechanism, we
-      // set the interval to twice the interval from the previous frame.
-      advance_commit_state_task_.Reset(advance_commit_state_closure_);
-      task_runner_->PostDelayedTask(FROM_HERE,
-                                    advance_commit_state_task_.callback(),
-                                    begin_impl_frame_args_.interval * 2);
-    }
-  } else {
-    advance_commit_state_task_.Cancel();
-  }
-}
-
-// BeginFrame is the mechanism that tells us that now is a good time to start
-// making a frame. Usually this means that user input for the frame is complete.
-// If the scheduler is busy, we queue the BeginFrame to be handled later as
-// a BeginRetroFrame.
-bool Scheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
-  TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
-
-  // Deliver BeginFrames to children.
-  if (state_machine_.children_need_begin_frames()) {
-    BeginFrameArgs adjusted_args_for_children(args);
-    // Adjust a deadline for child schedulers.
-    // TODO(simonhong): Once we have commitless update, we can get rid of
-    // BeginMainFrameToCommitDurationEstimate() +
-    // CommitToActivateDurationEstimate().
-    adjusted_args_for_children.deadline -=
-        (client_->BeginMainFrameToCommitDurationEstimate() +
-         client_->CommitToActivateDurationEstimate() +
-         client_->DrawDurationEstimate() + EstimatedParentDrawTime());
-    client_->SendBeginFramesToChildren(adjusted_args_for_children);
-  }
-
-  // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
-  // sent us the last BeginFrame we have missed. As we might not be able to
-  // actually make rendering for this call, handle it like a "retro frame".
-  // TODO(brainderson): Add a test for this functionality ASAP!
-  if (args.type == BeginFrameArgs::MISSED) {
-    begin_retro_frame_args_.push_back(args);
-    PostBeginRetroFrameIfNeeded();
-    return true;
-  }
-
-  BeginFrameArgs adjusted_args(args);
-  adjusted_args.deadline -= EstimatedParentDrawTime();
-
-  bool should_defer_begin_frame;
-  if (settings_.using_synchronous_renderer_compositor) {
-    should_defer_begin_frame = false;
-  } else {
-    should_defer_begin_frame =
-        !begin_retro_frame_args_.empty() ||
-        !begin_retro_frame_task_.IsCancelled() ||
-        !frame_source_->NeedsBeginFrames() ||
-        (state_machine_.begin_impl_frame_state() !=
-         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-  }
-
-  if (should_defer_begin_frame) {
-    begin_retro_frame_args_.push_back(adjusted_args);
-    TRACE_EVENT_INSTANT0(
-        "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
-    // Queuing the frame counts as "using it", so we need to return true.
-  } else {
-    BeginImplFrame(adjusted_args);
-  }
-  return true;
-}
-
-void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) {
-  state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames);
-  ProcessScheduledActions();
-}
-
-// BeginRetroFrame is called for BeginFrames that we've deferred because
-// the scheduler was in the middle of processing a previous BeginFrame.
-void Scheduler::BeginRetroFrame() {
-  TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
-  DCHECK(!settings_.using_synchronous_renderer_compositor);
-  DCHECK(!begin_retro_frame_args_.empty());
-  DCHECK(!begin_retro_frame_task_.IsCancelled());
-  DCHECK_EQ(state_machine_.begin_impl_frame_state(),
-            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-
-  begin_retro_frame_task_.Cancel();
-
-  // Discard expired BeginRetroFrames
-  // Today, we should always end up with at most one un-expired BeginRetroFrame
-  // because deadlines will not be greater than the next frame time. We don't
-  // DCHECK though because some systems don't always have monotonic timestamps.
-  // TODO(brianderson): In the future, long deadlines could result in us not
-  // draining the queue if we don't catch up. If we consistently can't catch
-  // up, our fallback should be to lower our frame rate.
-  base::TimeTicks now = Now();
-
-  while (!begin_retro_frame_args_.empty()) {
-    const BeginFrameArgs& args = begin_retro_frame_args_.front();
-    base::TimeTicks expiration_time = args.frame_time + args.interval;
-    if (now <= expiration_time)
-      break;
-    TRACE_EVENT_INSTANT2(
-        "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD,
-        "expiration_time - now", (expiration_time - now).InMillisecondsF(),
-        "BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
-    begin_retro_frame_args_.pop_front();
-    frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
-  }
-
-  if (begin_retro_frame_args_.empty()) {
-    TRACE_EVENT_INSTANT0("cc",
-                         "Scheduler::BeginRetroFrames all expired",
-                         TRACE_EVENT_SCOPE_THREAD);
-  } else {
-    BeginFrameArgs front = begin_retro_frame_args_.front();
-    begin_retro_frame_args_.pop_front();
-    BeginImplFrame(front);
-  }
-}
-
-// There could be a race between the posted BeginRetroFrame and a new
-// BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
-// will check if there is a pending BeginRetroFrame to ensure we handle
-// BeginFrames in FIFO order.
-void Scheduler::PostBeginRetroFrameIfNeeded() {
-  TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
-               "Scheduler::PostBeginRetroFrameIfNeeded",
-               "state",
-               AsValue());
-  if (!frame_source_->NeedsBeginFrames())
-    return;
-
-  if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
-    return;
-
-  // begin_retro_frame_args_ should always be empty for the
-  // synchronous compositor.
-  DCHECK(!settings_.using_synchronous_renderer_compositor);
-
-  if (state_machine_.begin_impl_frame_state() !=
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
-    return;
-
-  begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
-
-  task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
-}
-
-// BeginImplFrame starts a compositor frame that will wait up until a deadline
-// for a BeginMainFrame+activation to complete before it times out and draws
-// any asynchronous animation and scroll/pinch updates.
-void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
-  bool main_thread_is_in_high_latency_mode =
-      state_machine_.MainThreadIsInHighLatencyMode();
-  TRACE_EVENT2("cc,benchmark",
-               "Scheduler::BeginImplFrame",
-               "args",
-               args.AsValue(),
-               "main_thread_is_high_latency",
-               main_thread_is_in_high_latency_mode);
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
-                 "MainThreadLatency",
-                 main_thread_is_in_high_latency_mode);
-  DCHECK_EQ(state_machine_.begin_impl_frame_state(),
-            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-  DCHECK(state_machine_.HasInitializedOutputSurface());
-
-  advance_commit_state_task_.Cancel();
-
-  begin_impl_frame_args_ = args;
-  begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate();
-
-  if (!state_machine_.impl_latency_takes_priority() &&
-      main_thread_is_in_high_latency_mode &&
-      CanCommitAndActivateBeforeDeadline()) {
-    state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
-  }
-
-  state_machine_.OnBeginImplFrame();
-  client_->WillBeginImplFrame(begin_impl_frame_args_);
-
-  ProcessScheduledActions();
-
-  state_machine_.OnBeginImplFrameDeadlinePending();
-
-  if (settings_.using_synchronous_renderer_compositor) {
-    // The synchronous renderer compositor has to make its GL calls
-    // within this call.
-    // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
-    // so the synchronous renderer compositor can take advantage of splitting
-    // up the BeginImplFrame and deadline as well.
-    OnBeginImplFrameDeadline();
-  } else {
-    ScheduleBeginImplFrameDeadline();
-  }
-}
-
-void Scheduler::ScheduleBeginImplFrameDeadline() {
-  // The synchronous compositor does not post a deadline task.
-  DCHECK(!settings_.using_synchronous_renderer_compositor);
-
-  begin_impl_frame_deadline_task_.Cancel();
-  begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
-
-  begin_impl_frame_deadline_mode_ =
-      state_machine_.CurrentBeginImplFrameDeadlineMode();
-
-  base::TimeTicks deadline;
-  switch (begin_impl_frame_deadline_mode_) {
-    case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE:
-      // We are ready to draw a new active tree immediately.
-      // We don't use Now() here because it's somewhat expensive to call.
-      deadline = base::TimeTicks();
-      break;
-    case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR:
-      // We are animating on the impl thread but we can wait for some time.
-      deadline = begin_impl_frame_args_.deadline;
-      break;
-    case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE:
-      // We are blocked for one reason or another and we should wait.
-      // TODO(brianderson): Handle long deadlines (that are past the next
-      // frame's frame time) properly instead of using this hack.
-      deadline =
-          begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval;
-      break;
-  }
-
-  TRACE_EVENT1(
-      "cc", "Scheduler::ScheduleBeginImplFrameDeadline", "deadline", deadline);
-
-  base::TimeDelta delta = deadline - Now();
-  if (delta <= base::TimeDelta())
-    delta = base::TimeDelta();
-  task_runner_->PostDelayedTask(
-      FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
-}
-
-void Scheduler::RescheduleBeginImplFrameDeadlineIfNeeded() {
-  if (settings_.using_synchronous_renderer_compositor)
-    return;
-
-  if (state_machine_.begin_impl_frame_state() !=
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
-    return;
-
-  if (begin_impl_frame_deadline_mode_ !=
-      state_machine_.CurrentBeginImplFrameDeadlineMode())
-    ScheduleBeginImplFrameDeadline();
-}
-
-void Scheduler::OnBeginImplFrameDeadline() {
-  TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline");
-  begin_impl_frame_deadline_task_.Cancel();
-  // We split the deadline actions up into two phases so the state machine
-  // has a chance to trigger actions that should occur durring and after
-  // the deadline separately. For example:
-  // * Sending the BeginMainFrame will not occur after the deadline in
-  //     order to wait for more user-input before starting the next commit.
-  // * Creating a new OuputSurface will not occur during the deadline in
-  //     order to allow the state machine to "settle" first.
-
-  // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed.
-  tracked_objects::ScopedTracker tracking_profile1(
-      FROM_HERE_WITH_EXPLICIT_FUNCTION(
-          "461509 Scheduler::OnBeginImplFrameDeadline1"));
-  state_machine_.OnBeginImplFrameDeadline();
-  ProcessScheduledActions();
-  state_machine_.OnBeginImplFrameIdle();
-  ProcessScheduledActions();
-
-  client_->DidBeginImplFrameDeadline();
-  frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
-}
-
-void Scheduler::PollForAnticipatedDrawTriggers() {
-  TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers");
-  poll_for_draw_triggers_task_.Cancel();
-  state_machine_.DidEnterPollForAnticipatedDrawTriggers();
-  ProcessScheduledActions();
-  state_machine_.DidLeavePollForAnticipatedDrawTriggers();
-}
-
-void Scheduler::PollToAdvanceCommitState() {
-  TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState");
-  advance_commit_state_task_.Cancel();
-  ProcessScheduledActions();
-}
-
-void Scheduler::DrawAndSwapIfPossible() {
-  DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
-  state_machine_.DidDrawIfPossibleCompleted(result);
-}
-
-void Scheduler::SetDeferCommits(bool defer_commits) {
-  TRACE_EVENT1("cc", "Scheduler::SetDeferCommits",
-                "defer_commits",
-                defer_commits);
-  state_machine_.SetDeferCommits(defer_commits);
-  ProcessScheduledActions();
-}
-
-void Scheduler::ProcessScheduledActions() {
-  // We do not allow ProcessScheduledActions to be recursive.
-  // The top-level call will iteratively execute the next action for us anyway.
-  if (inside_process_scheduled_actions_)
-    return;
-
-  base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);
-
-  SchedulerStateMachine::Action action;
-  do {
-    action = state_machine_.NextAction();
-    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
-                 "SchedulerStateMachine",
-                 "state",
-                 AsValue());
-    VLOG(2) << "Scheduler::ProcessScheduledActions: "
-            << SchedulerStateMachine::ActionToString(action) << " "
-            << state_machine_.GetStatesForDebugging();
-    state_machine_.UpdateState(action);
-    base::AutoReset<SchedulerStateMachine::Action>
-        mark_inside_action(&inside_action_, action);
-    switch (action) {
-      case SchedulerStateMachine::ACTION_NONE:
-        break;
-      case SchedulerStateMachine::ACTION_ANIMATE:
-        client_->ScheduledActionAnimate();
-        break;
-      case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
-        client_->ScheduledActionSendBeginMainFrame();
-        break;
-      case SchedulerStateMachine::ACTION_COMMIT: {
-        // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
-        // fixed.
-        tracked_objects::ScopedTracker tracking_profile4(
-            FROM_HERE_WITH_EXPLICIT_FUNCTION(
-                "461509 Scheduler::ProcessScheduledActions4"));
-        client_->ScheduledActionCommit();
-        break;
-      }
-      case SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE:
-        client_->ScheduledActionActivateSyncTree();
-        break;
-      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
-        // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is
-        // fixed.
-        tracked_objects::ScopedTracker tracking_profile6(
-            FROM_HERE_WITH_EXPLICIT_FUNCTION(
-                "461509 Scheduler::ProcessScheduledActions6"));
-        DrawAndSwapIfPossible();
-        break;
-      }
-      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED:
-        client_->ScheduledActionDrawAndSwapForced();
-        break;
-      case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT:
-        // No action is actually performed, but this allows the state machine to
-        // advance out of its waiting to draw state without actually drawing.
-        break;
-      case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
-        client_->ScheduledActionBeginOutputSurfaceCreation();
-        break;
-      case SchedulerStateMachine::ACTION_PREPARE_TILES:
-        client_->ScheduledActionPrepareTiles();
-        break;
-    }
-  } while (action != SchedulerStateMachine::ACTION_NONE);
-
-  SetupPollingMechanisms();
-
-  client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
-
-  RescheduleBeginImplFrameDeadlineIfNeeded();
-
-  SetupNextBeginFrameIfNeeded();
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue()
-    const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
-  state->BeginDictionary("state_machine");
-  state_machine_.AsValueInto(state);
-  state->EndDictionary();
-
-  // Only trace frame sources when explicitly enabled - http://crbug.com/420607
-  bool frame_tracing_enabled = false;
-  TRACE_EVENT_CATEGORY_GROUP_ENABLED(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
-      &frame_tracing_enabled);
-  if (frame_tracing_enabled) {
-    state->BeginDictionary("frame_source_");
-    frame_source_->AsValueInto(state);
-    state->EndDictionary();
-  }
-
-  state->BeginDictionary("scheduler_state");
-  state->SetDouble("time_until_anticipated_draw_time_ms",
-                   (AnticipatedDrawTime() - Now()).InMillisecondsF());
-  state->SetDouble("estimated_parent_draw_time_ms",
-                   estimated_parent_draw_time_.InMillisecondsF());
-  state->SetBoolean("last_set_needs_begin_frame_",
-                    frame_source_->NeedsBeginFrames());
-  state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
-  state->SetBoolean("begin_retro_frame_task_",
-                    !begin_retro_frame_task_.IsCancelled());
-  state->SetBoolean("begin_impl_frame_deadline_task_",
-                    !begin_impl_frame_deadline_task_.IsCancelled());
-  state->SetBoolean("poll_for_draw_triggers_task_",
-                    !poll_for_draw_triggers_task_.IsCancelled());
-  state->SetBoolean("advance_commit_state_task_",
-                    !advance_commit_state_task_.IsCancelled());
-  state->BeginDictionary("begin_impl_frame_args");
-  begin_impl_frame_args_.AsValueInto(state);
-  state->EndDictionary();
-
-  base::TimeTicks now = Now();
-  base::TimeTicks frame_time = begin_impl_frame_args_.frame_time;
-  base::TimeTicks deadline = begin_impl_frame_args_.deadline;
-  base::TimeDelta interval = begin_impl_frame_args_.interval;
-  state->BeginDictionary("major_timestamps_in_ms");
-  state->SetDouble("0_interval", interval.InMillisecondsF());
-  state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
-  state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
-  state->SetDouble("3_frame_time_to_deadline",
-                   (deadline - frame_time).InMillisecondsF());
-  state->SetDouble("4_now", (now - base::TimeTicks()).InMillisecondsF());
-  state->SetDouble("5_frame_time",
-                   (frame_time - base::TimeTicks()).InMillisecondsF());
-  state->SetDouble("6_deadline",
-                   (deadline - base::TimeTicks()).InMillisecondsF());
-  state->EndDictionary();
-
-  state->EndDictionary();
-
-  state->BeginDictionary("client_state");
-  state->SetDouble("draw_duration_estimate_ms",
-                   client_->DrawDurationEstimate().InMillisecondsF());
-  state->SetDouble(
-      "begin_main_frame_to_commit_duration_estimate_ms",
-      client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
-  state->SetDouble(
-      "commit_to_activate_duration_estimate_ms",
-      client_->CommitToActivateDurationEstimate().InMillisecondsF());
-  state->EndDictionary();
-}
-
-bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
-  // Check if the main thread computation and commit can be finished before the
-  // impl thread's deadline.
-  base::TimeTicks estimated_draw_time =
-      begin_impl_frame_args_.frame_time +
-      client_->BeginMainFrameToCommitDurationEstimate() +
-      client_->CommitToActivateDurationEstimate();
-
-  TRACE_EVENT2(
-      TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
-      "CanCommitAndActivateBeforeDeadline",
-      "time_left_after_drawing_ms",
-      (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
-      "state",
-      AsValue());
-
-  return estimated_draw_time < begin_impl_frame_args_.deadline;
-}
-
-bool Scheduler::IsBeginMainFrameSentOrStarted() const {
-  return (state_machine_.commit_state() ==
-              SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
-          state_machine_.commit_state() ==
-              SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
-}
-
-}  // namespace cc
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
deleted file mode 100644
index 6636efe..0000000
--- a/cc/scheduler/scheduler.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_SCHEDULER_SCHEDULER_H_
-#define CC_SCHEDULER_SCHEDULER_H_
-
-#include <deque>
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/cancelable_callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/output/vsync_parameter_observer.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/scheduler/delay_based_time_source.h"
-#include "cc/scheduler/draw_result.h"
-#include "cc/scheduler/scheduler_settings.h"
-#include "cc/scheduler/scheduler_state_machine.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-}
-class SingleThreadTaskRunner;
-}
-
-namespace cc {
-
-class SchedulerClient {
- public:
-  virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0;
-  virtual void ScheduledActionSendBeginMainFrame() = 0;
-  virtual DrawResult ScheduledActionDrawAndSwapIfPossible() = 0;
-  virtual DrawResult ScheduledActionDrawAndSwapForced() = 0;
-  virtual void ScheduledActionAnimate() = 0;
-  virtual void ScheduledActionCommit() = 0;
-  virtual void ScheduledActionActivateSyncTree() = 0;
-  virtual void ScheduledActionBeginOutputSurfaceCreation() = 0;
-  virtual void ScheduledActionPrepareTiles() = 0;
-  virtual void DidAnticipatedDrawTimeChange(base::TimeTicks time) = 0;
-  virtual base::TimeDelta DrawDurationEstimate() = 0;
-  virtual base::TimeDelta BeginMainFrameToCommitDurationEstimate() = 0;
-  virtual base::TimeDelta CommitToActivateDurationEstimate() = 0;
-  virtual void DidBeginImplFrameDeadline() = 0;
-  virtual void SendBeginFramesToChildren(const BeginFrameArgs& args) = 0;
-  virtual void SendBeginMainFrameNotExpectedSoon() = 0;
-
- protected:
-  virtual ~SchedulerClient() {}
-};
-
-class Scheduler;
-// This class exists to allow tests to override the frame source construction.
-// A virtual method can't be used as this needs to happen in the constructor
-// (see C++ FAQ / Section 23 - http://goo.gl/fnrwom for why).
-// This class exists solely long enough to construct the frame sources.
-class SchedulerFrameSourcesConstructor {
- public:
-  virtual ~SchedulerFrameSourcesConstructor() {}
-  virtual BeginFrameSource* ConstructPrimaryFrameSource(Scheduler* scheduler);
-  virtual BeginFrameSource* ConstructBackgroundFrameSource(
-      Scheduler* scheduler);
-  virtual BeginFrameSource* ConstructUnthrottledFrameSource(
-      Scheduler* scheduler);
-
- protected:
-  SchedulerFrameSourcesConstructor() {}
-
-  friend class Scheduler;
-};
-
-class Scheduler : public BeginFrameObserverMixIn {
- public:
-  static scoped_ptr<Scheduler> Create(
-      SchedulerClient* client,
-      const SchedulerSettings& scheduler_settings,
-      int layer_tree_host_id,
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
-      scoped_ptr<BeginFrameSource> external_begin_frame_source) {
-    SchedulerFrameSourcesConstructor frame_sources_constructor;
-    return make_scoped_ptr(new Scheduler(client,
-                                         scheduler_settings,
-                                         layer_tree_host_id,
-                                         task_runner,
-                                         external_begin_frame_source.Pass(),
-                                         &frame_sources_constructor));
-  }
-
-  ~Scheduler() override;
-
-  // BeginFrameObserverMixin
-  bool OnBeginFrameMixInDelegate(const BeginFrameArgs& args) override;
-
-  const SchedulerSettings& settings() const { return settings_; }
-
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval);
-  void SetEstimatedParentDrawTime(base::TimeDelta draw_time);
-
-  void SetCanStart();
-
-  void SetVisible(bool visible);
-  void SetCanDraw(bool can_draw);
-  void NotifyReadyToActivate();
-  void NotifyReadyToDraw();
-  void SetThrottleFrameProduction(bool throttle);
-
-  void SetNeedsCommit();
-
-  void SetNeedsRedraw();
-
-  void SetNeedsAnimate();
-
-  void SetNeedsPrepareTiles();
-
-  void SetMaxSwapsPending(int max);
-  void DidSwapBuffers();
-  void DidSwapBuffersComplete();
-
-  void SetImplLatencyTakesPriority(bool impl_latency_takes_priority);
-
-  void NotifyReadyToCommit();
-  void BeginMainFrameAborted(CommitEarlyOutReason reason);
-
-  void DidPrepareTiles();
-  void DidLoseOutputSurface();
-  void DidCreateAndInitializeOutputSurface();
-
-  // Tests do not want to shut down until all possible BeginMainFrames have
-  // occured to prevent flakiness.
-  bool MainFrameForTestingWillHappen() const {
-    return state_machine_.CommitPending() ||
-           state_machine_.CouldSendBeginMainFrame();
-  }
-
-  bool CommitPending() const { return state_machine_.CommitPending(); }
-  bool RedrawPending() const { return state_machine_.RedrawPending(); }
-  bool PrepareTilesPending() const {
-    return state_machine_.PrepareTilesPending();
-  }
-  bool MainThreadIsInHighLatencyMode() const {
-    return state_machine_.MainThreadIsInHighLatencyMode();
-  }
-  bool BeginImplFrameDeadlinePending() const {
-    return !begin_impl_frame_deadline_task_.IsCancelled();
-  }
-
-  base::TimeTicks AnticipatedDrawTime() const;
-
-  void NotifyBeginMainFrameStarted();
-
-  base::TimeTicks LastBeginImplFrameTime();
-
-  void SetDeferCommits(bool defer_commits);
-
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* value) const override;
-
-  void SetContinuousPainting(bool continuous_painting) {
-    state_machine_.SetContinuousPainting(continuous_painting);
-  }
-
-  void SetChildrenNeedBeginFrames(bool children_need_begin_frames);
-
- protected:
-  Scheduler(SchedulerClient* client,
-            const SchedulerSettings& scheduler_settings,
-            int layer_tree_host_id,
-            const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
-            scoped_ptr<BeginFrameSource> external_begin_frame_source,
-            SchedulerFrameSourcesConstructor* frame_sources_constructor);
-
-  // virtual for testing - Don't call these in the constructor or
-  // destructor!
-  virtual base::TimeTicks Now() const;
-
-  scoped_ptr<BeginFrameSourceMultiplexer> frame_source_;
-  BeginFrameSource* primary_frame_source_;
-  BeginFrameSource* background_frame_source_;
-  BeginFrameSource* unthrottled_frame_source_;
-
-  // Storage when frame sources are internal
-  scoped_ptr<BeginFrameSource> primary_frame_source_internal_;
-  scoped_ptr<SyntheticBeginFrameSource> background_frame_source_internal_;
-  scoped_ptr<BeginFrameSource> unthrottled_frame_source_internal_;
-
-  VSyncParameterObserver* vsync_observer_;
-  bool throttle_frame_production_;
-
-  const SchedulerSettings settings_;
-  SchedulerClient* client_;
-  int layer_tree_host_id_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-  base::TimeDelta estimated_parent_draw_time_;
-
-  std::deque<BeginFrameArgs> begin_retro_frame_args_;
-  BeginFrameArgs begin_impl_frame_args_;
-  SchedulerStateMachine::BeginImplFrameDeadlineMode
-      begin_impl_frame_deadline_mode_;
-
-  base::Closure begin_retro_frame_closure_;
-  base::Closure begin_impl_frame_deadline_closure_;
-  base::Closure poll_for_draw_triggers_closure_;
-  base::Closure advance_commit_state_closure_;
-  base::CancelableClosure begin_retro_frame_task_;
-  base::CancelableClosure begin_impl_frame_deadline_task_;
-  base::CancelableClosure poll_for_draw_triggers_task_;
-  base::CancelableClosure advance_commit_state_task_;
-
-  SchedulerStateMachine state_machine_;
-  bool inside_process_scheduled_actions_;
-  SchedulerStateMachine::Action inside_action_;
-
- private:
-  void ScheduleBeginImplFrameDeadline();
-  void RescheduleBeginImplFrameDeadlineIfNeeded();
-  void SetupNextBeginFrameIfNeeded();
-  void PostBeginRetroFrameIfNeeded();
-  void SetupPollingMechanisms();
-  void DrawAndSwapIfPossible();
-  void ProcessScheduledActions();
-  bool CanCommitAndActivateBeforeDeadline() const;
-  void AdvanceCommitStateIfPossible();
-  bool IsBeginMainFrameSentOrStarted() const;
-  void BeginRetroFrame();
-  void BeginImplFrame(const BeginFrameArgs& args);
-  void OnBeginImplFrameDeadline();
-  void PollForAnticipatedDrawTriggers();
-  void PollToAdvanceCommitState();
-  void UpdateActiveFrameSource();
-
-  base::TimeDelta EstimatedParentDrawTime() {
-    return estimated_parent_draw_time_;
-  }
-
-  bool IsInsideAction(SchedulerStateMachine::Action action) {
-    return inside_action_ == action;
-  }
-
-  base::WeakPtrFactory<Scheduler> weak_factory_;
-
-  friend class SchedulerFrameSourcesConstructor;
-  friend class TestSchedulerFrameSourcesConstructor;
-
-  DISALLOW_COPY_AND_ASSIGN(Scheduler);
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_SCHEDULER_H_
diff --git a/cc/scheduler/scheduler_settings.cc b/cc/scheduler/scheduler_settings.cc
deleted file mode 100644
index c6c8e8e..0000000
--- a/cc/scheduler/scheduler_settings.cc
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/scheduler/scheduler_settings.h"
-
-#include "base/trace_event/trace_event_argument.h"
-
-namespace cc {
-
-SchedulerSettings::SchedulerSettings()
-    : use_external_begin_frame_source(false),
-      main_frame_before_activation_enabled(false),
-      impl_side_painting(false),
-      timeout_and_draw_when_animation_checkerboards(true),
-      maximum_number_of_failed_draws_before_draw_is_forced_(3),
-      using_synchronous_renderer_compositor(false),
-      throttle_frame_production(true),
-      main_thread_should_always_be_low_latency(false),
-      background_frame_interval(base::TimeDelta::FromSeconds(1)) {
-}
-
-SchedulerSettings::~SchedulerSettings() {}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-SchedulerSettings::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  state->SetBoolean("use_external_begin_frame_source",
-                    use_external_begin_frame_source);
-  state->SetBoolean("main_frame_before_activation_enabled",
-                    main_frame_before_activation_enabled);
-  state->SetBoolean("impl_side_painting", impl_side_painting);
-  state->SetBoolean("timeout_and_draw_when_animation_checkerboards",
-                    timeout_and_draw_when_animation_checkerboards);
-  state->SetInteger("maximum_number_of_failed_draws_before_draw_is_forced_",
-                    maximum_number_of_failed_draws_before_draw_is_forced_);
-  state->SetBoolean("using_synchronous_renderer_compositor",
-                    using_synchronous_renderer_compositor);
-  state->SetBoolean("throttle_frame_production", throttle_frame_production);
-  state->SetBoolean("main_thread_should_always_be_low_latency",
-                    main_thread_should_always_be_low_latency);
-  state->SetInteger("background_frame_interval",
-                    background_frame_interval.InMicroseconds());
-  return state;
-}
-
-}  // namespace cc
diff --git a/cc/scheduler/scheduler_settings.h b/cc/scheduler/scheduler_settings.h
deleted file mode 100644
index 12a6551..0000000
--- a/cc/scheduler/scheduler_settings.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_SCHEDULER_SCHEDULER_SETTINGS_H_
-#define CC_SCHEDULER_SCHEDULER_SETTINGS_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/time/time.h"
-#include "base/values.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-}
-}
-
-namespace cc {
-
-class SchedulerSettings {
- public:
-  SchedulerSettings();
-  ~SchedulerSettings();
-
-  bool use_external_begin_frame_source;
-  bool main_frame_before_activation_enabled;
-  bool impl_side_painting;
-  bool timeout_and_draw_when_animation_checkerboards;
-  int maximum_number_of_failed_draws_before_draw_is_forced_;
-  bool using_synchronous_renderer_compositor;
-  bool throttle_frame_production;
-
-  // In main thread low latency mode the entire
-  // BeginMainFrame->Commit->Activation->Draw cycle should complete before
-  // starting the next cycle.  Additionally, BeginMainFrame and Commit are
-  // completed atomically with no other tasks or actions occuring between them.
-  bool main_thread_should_always_be_low_latency;
-
-  base::TimeDelta background_frame_interval;
-
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_SCHEDULER_SETTINGS_H_
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
deleted file mode 100644
index c512987..0000000
--- a/cc/scheduler/scheduler_state_machine.cc
+++ /dev/null
@@ -1,1089 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/scheduler_state_machine.h"
-
-#include "base/format_macros.h"
-#include "base/logging.h"
-#include "base/strings/stringprintf.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-#include "base/values.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-
-SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
-    : settings_(settings),
-      output_surface_state_(OUTPUT_SURFACE_LOST),
-      begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE),
-      commit_state_(COMMIT_STATE_IDLE),
-      forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
-      commit_count_(0),
-      current_frame_number_(0),
-      last_frame_number_animate_performed_(-1),
-      last_frame_number_swap_performed_(-1),
-      last_frame_number_swap_requested_(-1),
-      last_frame_number_begin_main_frame_sent_(-1),
-      animate_funnel_(false),
-      perform_swap_funnel_(false),
-      request_swap_funnel_(false),
-      send_begin_main_frame_funnel_(false),
-      prepare_tiles_funnel_(0),
-      consecutive_checkerboard_animations_(0),
-      max_pending_swaps_(1),
-      pending_swaps_(0),
-      needs_redraw_(false),
-      needs_animate_(false),
-      needs_prepare_tiles_(false),
-      needs_commit_(false),
-      inside_poll_for_anticipated_draw_triggers_(false),
-      visible_(false),
-      can_start_(false),
-      can_draw_(false),
-      has_pending_tree_(false),
-      pending_tree_is_ready_for_activation_(false),
-      active_tree_needs_first_draw_(false),
-      did_create_and_initialize_first_output_surface_(false),
-      impl_latency_takes_priority_(false),
-      skip_next_begin_main_frame_to_reduce_latency_(false),
-      skip_begin_main_frame_to_reduce_latency_(false),
-      continuous_painting_(false),
-      children_need_begin_frames_(false),
-      defer_commits_(false),
-      last_commit_had_no_updates_(false) {
-}
-
-const char* SchedulerStateMachine::OutputSurfaceStateToString(
-    OutputSurfaceState state) {
-  switch (state) {
-    case OUTPUT_SURFACE_ACTIVE:
-      return "OUTPUT_SURFACE_ACTIVE";
-    case OUTPUT_SURFACE_LOST:
-      return "OUTPUT_SURFACE_LOST";
-    case OUTPUT_SURFACE_CREATING:
-      return "OUTPUT_SURFACE_CREATING";
-    case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
-      return "OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT";
-    case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
-      return "OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-const char* SchedulerStateMachine::BeginImplFrameStateToString(
-    BeginImplFrameState state) {
-  switch (state) {
-    case BEGIN_IMPL_FRAME_STATE_IDLE:
-      return "BEGIN_IMPL_FRAME_STATE_IDLE";
-    case BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING:
-      return "BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING";
-    case BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME:
-      return "BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME";
-    case BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE:
-      return "BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
-  switch (state) {
-    case COMMIT_STATE_IDLE:
-      return "COMMIT_STATE_IDLE";
-    case COMMIT_STATE_BEGIN_MAIN_FRAME_SENT:
-      return "COMMIT_STATE_BEGIN_MAIN_FRAME_SENT";
-    case COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED:
-      return "COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED";
-    case COMMIT_STATE_READY_TO_COMMIT:
-      return "COMMIT_STATE_READY_TO_COMMIT";
-    case COMMIT_STATE_WAITING_FOR_ACTIVATION:
-      return "COMMIT_STATE_WAITING_FOR_ACTIVATION";
-    case COMMIT_STATE_WAITING_FOR_DRAW:
-      return "COMMIT_STATE_WAITING_FOR_DRAW";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString(
-    ForcedRedrawOnTimeoutState state) {
-  switch (state) {
-    case FORCED_REDRAW_STATE_IDLE:
-      return "FORCED_REDRAW_STATE_IDLE";
-    case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT:
-      return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT";
-    case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION:
-      return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION";
-    case FORCED_REDRAW_STATE_WAITING_FOR_DRAW:
-      return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-const char* SchedulerStateMachine::ActionToString(Action action) {
-  switch (action) {
-    case ACTION_NONE:
-      return "ACTION_NONE";
-    case ACTION_ANIMATE:
-      return "ACTION_ANIMATE";
-    case ACTION_SEND_BEGIN_MAIN_FRAME:
-      return "ACTION_SEND_BEGIN_MAIN_FRAME";
-    case ACTION_COMMIT:
-      return "ACTION_COMMIT";
-    case ACTION_ACTIVATE_SYNC_TREE:
-      return "ACTION_ACTIVATE_SYNC_TREE";
-    case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
-      return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
-    case ACTION_DRAW_AND_SWAP_FORCED:
-      return "ACTION_DRAW_AND_SWAP_FORCED";
-    case ACTION_DRAW_AND_SWAP_ABORT:
-      return "ACTION_DRAW_AND_SWAP_ABORT";
-    case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
-      return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
-    case ACTION_PREPARE_TILES:
-      return "ACTION_PREPARE_TILES";
-  }
-  NOTREACHED();
-  return "???";
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-SchedulerStateMachine::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-void SchedulerStateMachine::AsValueInto(
-    base::trace_event::TracedValue* state) const {
-  state->BeginDictionary("major_state");
-  state->SetString("next_action", ActionToString(NextAction()));
-  state->SetString("begin_impl_frame_state",
-                   BeginImplFrameStateToString(begin_impl_frame_state_));
-  state->SetString("commit_state", CommitStateToString(commit_state_));
-  state->SetString("output_surface_state_",
-                   OutputSurfaceStateToString(output_surface_state_));
-  state->SetString("forced_redraw_state",
-                   ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
-  state->EndDictionary();
-
-  state->BeginDictionary("minor_state");
-  state->SetInteger("commit_count", commit_count_);
-  state->SetInteger("current_frame_number", current_frame_number_);
-  state->SetInteger("last_frame_number_animate_performed",
-                    last_frame_number_animate_performed_);
-  state->SetInteger("last_frame_number_swap_performed",
-                    last_frame_number_swap_performed_);
-  state->SetInteger("last_frame_number_swap_requested",
-                    last_frame_number_swap_requested_);
-  state->SetInteger("last_frame_number_begin_main_frame_sent",
-                    last_frame_number_begin_main_frame_sent_);
-  state->SetBoolean("funnel: animate_funnel", animate_funnel_);
-  state->SetBoolean("funnel: perform_swap_funnel", perform_swap_funnel_);
-  state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_);
-  state->SetBoolean("funnel: send_begin_main_frame_funnel",
-                    send_begin_main_frame_funnel_);
-  state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_);
-  state->SetInteger("consecutive_checkerboard_animations",
-                    consecutive_checkerboard_animations_);
-  state->SetInteger("max_pending_swaps_", max_pending_swaps_);
-  state->SetInteger("pending_swaps_", pending_swaps_);
-  state->SetBoolean("needs_redraw", needs_redraw_);
-  state->SetBoolean("needs_animate_", needs_animate_);
-  state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
-  state->SetBoolean("needs_commit", needs_commit_);
-  state->SetBoolean("visible", visible_);
-  state->SetBoolean("can_start", can_start_);
-  state->SetBoolean("can_draw", can_draw_);
-  state->SetBoolean("has_pending_tree", has_pending_tree_);
-  state->SetBoolean("pending_tree_is_ready_for_activation",
-                    pending_tree_is_ready_for_activation_);
-  state->SetBoolean("active_tree_needs_first_draw",
-                    active_tree_needs_first_draw_);
-  state->SetBoolean("did_create_and_initialize_first_output_surface",
-                    did_create_and_initialize_first_output_surface_);
-  state->SetBoolean("impl_latency_takes_priority",
-                    impl_latency_takes_priority_);
-  state->SetBoolean("main_thread_is_in_high_latency_mode",
-                    MainThreadIsInHighLatencyMode());
-  state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
-                    skip_begin_main_frame_to_reduce_latency_);
-  state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
-                    skip_next_begin_main_frame_to_reduce_latency_);
-  state->SetBoolean("continuous_painting", continuous_painting_);
-  state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
-  state->SetBoolean("defer_commits", defer_commits_);
-  state->EndDictionary();
-}
-
-void SchedulerStateMachine::AdvanceCurrentFrameNumber() {
-  current_frame_number_++;
-
-  animate_funnel_ = false;
-  perform_swap_funnel_ = false;
-  request_swap_funnel_ = false;
-  send_begin_main_frame_funnel_ = false;
-
-  // "Drain" the PrepareTiles funnel.
-  if (prepare_tiles_funnel_ > 0)
-    prepare_tiles_funnel_--;
-
-  skip_begin_main_frame_to_reduce_latency_ =
-      skip_next_begin_main_frame_to_reduce_latency_;
-  skip_next_begin_main_frame_to_reduce_latency_ = false;
-}
-
-bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
-  // These are all the cases where we normally cannot or do not want to draw
-  // but, if needs_redraw_ is true and we do not draw to make forward progress,
-  // we might deadlock with the main thread.
-  // This should be a superset of PendingActivationsShouldBeForced() since
-  // activation of the pending tree is blocked by drawing of the active tree and
-  // the main thread might be blocked on activation of the most recent commit.
-  if (PendingActivationsShouldBeForced())
-    return true;
-
-  // Additional states where we should abort draws.
-  if (!can_draw_)
-    return true;
-  return false;
-}
-
-bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
-  // There is no output surface to trigger our activations.
-  // If we do not force activations to make forward progress, we might deadlock
-  // with the main thread.
-  if (output_surface_state_ == OUTPUT_SURFACE_LOST)
-    return true;
-
-  // If we're not visible, we should force activation.
-  // Since we set RequiresHighResToDraw when becoming visible, we ensure that we
-  // don't checkerboard until all visible resources are done. Furthermore, if we
-  // do keep the pending tree around, when becoming visible we might activate
-  // prematurely causing RequiresHighResToDraw flag to be reset. In all cases,
-  // we can simply activate on becoming invisible since we don't need to draw
-  // the active tree when we're in this state.
-  if (!visible_)
-    return true;
-
-  return false;
-}
-
-bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const {
-  // Don't try to initialize too early.
-  if (!can_start_)
-    return false;
-
-  // We only want to start output surface initialization after the
-  // previous commit is complete.
-  if (commit_state_ != COMMIT_STATE_IDLE)
-    return false;
-
-  // Make sure the BeginImplFrame from any previous OutputSurfaces
-  // are complete before creating the new OutputSurface.
-  if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_IDLE)
-    return false;
-
-  // We want to clear the pipline of any pending draws and activations
-  // before starting output surface initialization. This allows us to avoid
-  // weird corner cases where we abort draws or force activation while we
-  // are initializing the output surface.
-  if (active_tree_needs_first_draw_ || has_pending_tree_)
-    return false;
-
-  // We need to create the output surface if we don't have one and we haven't
-  // started creating one yet.
-  return output_surface_state_ == OUTPUT_SURFACE_LOST;
-}
-
-bool SchedulerStateMachine::ShouldDraw() const {
-  // If we need to abort draws, we should do so ASAP since the draw could
-  // be blocking other important actions (like output surface initialization),
-  // from occuring. If we are waiting for the first draw, then perfom the
-  // aborted draw to keep things moving. If we are not waiting for the first
-  // draw however, we don't want to abort for no reason.
-  if (PendingDrawsShouldBeAborted())
-    return active_tree_needs_first_draw_;
-
-  // Do not draw too many times in a single frame. It's okay that we don't check
-  // this before checking for aborted draws because aborted draws do not request
-  // a swap.
-  if (request_swap_funnel_)
-    return false;
-
-  // Don't draw if we are waiting on the first commit after a surface.
-  if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
-    return false;
-
-  // Do not queue too many swaps.
-  if (pending_swaps_ >= max_pending_swaps_)
-    return false;
-
-  // Except for the cases above, do not draw outside of the BeginImplFrame
-  // deadline.
-  if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
-    return false;
-
-  // Only handle forced redraws due to timeouts on the regular deadline.
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
-    return true;
-
-  return needs_redraw_;
-}
-
-bool SchedulerStateMachine::ShouldActivatePendingTree() const {
-  // There is nothing to activate.
-  if (!has_pending_tree_)
-    return false;
-
-  // We should not activate a second tree before drawing the first one.
-  // Even if we need to force activation of the pending tree, we should abort
-  // drawing the active tree first.
-  if (active_tree_needs_first_draw_)
-    return false;
-
-  // If we want to force activation, do so ASAP.
-  if (PendingActivationsShouldBeForced())
-    return true;
-
-  // At this point, only activate if we are ready to activate.
-  return pending_tree_is_ready_for_activation_;
-}
-
-bool SchedulerStateMachine::ShouldAnimate() const {
-  // Do not animate too many times in a single frame.
-  if (animate_funnel_)
-    return false;
-
-  // Don't animate if we are waiting on the first commit after a surface.
-  if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
-    return false;
-
-  if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
-      begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
-    return false;
-
-  return needs_redraw_ || needs_animate_;
-}
-
-bool SchedulerStateMachine::CouldSendBeginMainFrame() const {
-  // Do not send begin main frame too many times in a single frame.
-  if (send_begin_main_frame_funnel_)
-    return false;
-
-  if (!needs_commit_)
-    return false;
-
-  // We can not perform commits if we are not visible.
-  if (!visible_)
-    return false;
-
-  // Do not make a new commits when it is deferred.
-  if (defer_commits_)
-    return false;
-
-  return true;
-}
-
-bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
-  if (!CouldSendBeginMainFrame())
-    return false;
-
-  // Only send BeginMainFrame when there isn't another commit pending already.
-  if (commit_state_ != COMMIT_STATE_IDLE)
-    return false;
-
-  // Don't send BeginMainFrame early if we are prioritizing the active tree
-  // because of impl_latency_takes_priority_.
-  if (impl_latency_takes_priority_ &&
-      (has_pending_tree_ || active_tree_needs_first_draw_)) {
-    return false;
-  }
-
-  // We should not send BeginMainFrame while we are in
-  // BEGIN_IMPL_FRAME_STATE_IDLE since we might have new
-  // user input arriving soon.
-  // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
-  // thread isn't consuming user input.
-  if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_IDLE &&
-      BeginFrameNeeded())
-    return false;
-
-  // We need a new commit for the forced redraw. This honors the
-  // single commit per interval because the result will be swapped to screen.
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
-    return true;
-
-  // We shouldn't normally accept commits if there isn't an OutputSurface.
-  if (!HasInitializedOutputSurface())
-    return false;
-
-  // SwapAck throttle the BeginMainFrames unless we just swapped.
-  // TODO(brianderson): Remove this restriction to improve throughput.
-  bool just_swapped_in_deadline =
-      begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
-      perform_swap_funnel_;
-  if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline)
-    return false;
-
-  if (skip_begin_main_frame_to_reduce_latency_)
-    return false;
-
-  return true;
-}
-
-bool SchedulerStateMachine::ShouldCommit() const {
-  if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT)
-    return false;
-
-  // We must not finish the commit until the pending tree is free.
-  if (has_pending_tree_) {
-    DCHECK(settings_.main_frame_before_activation_enabled);
-    return false;
-  }
-
-  // Prioritize drawing the previous commit before finishing the next commit.
-  if (active_tree_needs_first_draw_)
-    return false;
-
-  return true;
-}
-
-bool SchedulerStateMachine::ShouldPrepareTiles() const {
-  // PrepareTiles only really needs to be called immediately after commit
-  // and then periodically after that. Use a funnel to make sure we average
-  // one PrepareTiles per BeginImplFrame in the long run.
-  if (prepare_tiles_funnel_ > 0)
-    return false;
-
-  // Limiting to once per-frame is not enough, since we only want to
-  // prepare tiles _after_ draws. Polling for draw triggers and
-  // begin-frame are mutually exclusive, so we limit to these two cases.
-  if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
-      !inside_poll_for_anticipated_draw_triggers_)
-    return false;
-  return needs_prepare_tiles_;
-}
-
-SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
-  if (ShouldActivatePendingTree())
-    return ACTION_ACTIVATE_SYNC_TREE;
-  if (ShouldCommit())
-    return ACTION_COMMIT;
-  if (ShouldAnimate())
-    return ACTION_ANIMATE;
-  if (ShouldDraw()) {
-    if (PendingDrawsShouldBeAborted())
-      return ACTION_DRAW_AND_SWAP_ABORT;
-    else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
-      return ACTION_DRAW_AND_SWAP_FORCED;
-    else
-      return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
-  }
-  if (ShouldPrepareTiles())
-    return ACTION_PREPARE_TILES;
-  if (ShouldSendBeginMainFrame())
-    return ACTION_SEND_BEGIN_MAIN_FRAME;
-  if (ShouldBeginOutputSurfaceCreation())
-    return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
-  return ACTION_NONE;
-}
-
-void SchedulerStateMachine::UpdateState(Action action) {
-  switch (action) {
-    case ACTION_NONE:
-      return;
-
-    case ACTION_ACTIVATE_SYNC_TREE:
-      UpdateStateOnActivation();
-      return;
-
-    case ACTION_ANIMATE:
-      DCHECK(!animate_funnel_);
-      last_frame_number_animate_performed_ = current_frame_number_;
-      animate_funnel_ = true;
-      needs_animate_ = false;
-      // TODO(skyostil): Instead of assuming this, require the client to tell
-      // us.
-      SetNeedsRedraw();
-      return;
-
-    case ACTION_SEND_BEGIN_MAIN_FRAME:
-      DCHECK(!has_pending_tree_ ||
-             settings_.main_frame_before_activation_enabled);
-      DCHECK(visible_);
-      DCHECK(!send_begin_main_frame_funnel_);
-      commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
-      needs_commit_ = false;
-      send_begin_main_frame_funnel_ = true;
-      last_frame_number_begin_main_frame_sent_ =
-          current_frame_number_;
-      return;
-
-    case ACTION_COMMIT: {
-      bool commit_has_no_updates = false;
-      UpdateStateOnCommit(commit_has_no_updates);
-      return;
-    }
-
-    case ACTION_DRAW_AND_SWAP_FORCED:
-    case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
-      bool did_request_swap = true;
-      UpdateStateOnDraw(did_request_swap);
-      return;
-    }
-
-    case ACTION_DRAW_AND_SWAP_ABORT: {
-      bool did_request_swap = false;
-      UpdateStateOnDraw(did_request_swap);
-      return;
-    }
-
-    case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
-      DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
-      output_surface_state_ = OUTPUT_SURFACE_CREATING;
-
-      // The following DCHECKs make sure we are in the proper quiescent state.
-      // The pipeline should be flushed entirely before we start output
-      // surface creation to avoid complicated corner cases.
-      DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
-      DCHECK(!has_pending_tree_);
-      DCHECK(!active_tree_needs_first_draw_);
-      return;
-
-    case ACTION_PREPARE_TILES:
-      UpdateStateOnPrepareTiles();
-      return;
-  }
-}
-
-void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) {
-  commit_count_++;
-
-  if (!commit_has_no_updates)
-    animate_funnel_ = false;
-
-  if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
-    commit_state_ = COMMIT_STATE_IDLE;
-  } else if (settings_.impl_side_painting) {
-    commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
-  } else {
-    commit_state_ = settings_.main_thread_should_always_be_low_latency
-                        ? COMMIT_STATE_WAITING_FOR_DRAW
-                        : COMMIT_STATE_IDLE;
-  }
-
-  // If we are impl-side-painting but the commit was aborted, then we behave
-  // mostly as if we are not impl-side-painting since there is no pending tree.
-  has_pending_tree_ = settings_.impl_side_painting && !commit_has_no_updates;
-
-  // Update state related to forced draws.
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
-    forced_redraw_state_ = has_pending_tree_
-                               ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
-                               : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
-  }
-
-  // Update the output surface state.
-  DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
-  if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
-    if (has_pending_tree_) {
-      output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
-    } else {
-      output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
-      needs_redraw_ = true;
-    }
-  }
-
-  // Update state if we have a new active tree to draw, or if the active tree
-  // was unchanged but we need to do a forced draw.
-  if (!has_pending_tree_ &&
-      (!commit_has_no_updates ||
-       forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
-    needs_redraw_ = true;
-    active_tree_needs_first_draw_ = true;
-  }
-
-  // This post-commit work is common to both completed and aborted commits.
-  pending_tree_is_ready_for_activation_ = false;
-
-  if (continuous_painting_)
-    needs_commit_ = true;
-  last_commit_had_no_updates_ = commit_has_no_updates;
-}
-
-void SchedulerStateMachine::UpdateStateOnActivation() {
-  if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) {
-    commit_state_ = settings_.main_thread_should_always_be_low_latency
-                        ? COMMIT_STATE_WAITING_FOR_DRAW
-                        : COMMIT_STATE_IDLE;
-  }
-
-  if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
-    output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
-
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION)
-    forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
-
-  has_pending_tree_ = false;
-  pending_tree_is_ready_for_activation_ = false;
-  active_tree_needs_first_draw_ = true;
-  needs_redraw_ = true;
-}
-
-void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) {
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
-    forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
-
-  if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW)
-    commit_state_ = COMMIT_STATE_IDLE;
-
-  needs_redraw_ = false;
-  active_tree_needs_first_draw_ = false;
-
-  if (did_request_swap) {
-    DCHECK(!request_swap_funnel_);
-    request_swap_funnel_ = true;
-    last_frame_number_swap_requested_ = current_frame_number_;
-  }
-}
-
-void SchedulerStateMachine::UpdateStateOnPrepareTiles() {
-  needs_prepare_tiles_ = false;
-}
-
-void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
-  TRACE_EVENT_INSTANT0("cc",
-                       "Scheduler: SkipNextBeginMainFrameToReduceLatency",
-                       TRACE_EVENT_SCOPE_THREAD);
-  skip_next_begin_main_frame_to_reduce_latency_ = true;
-}
-
-bool SchedulerStateMachine::BeginFrameNeededForChildren() const {
-  if (HasInitializedOutputSurface())
-    return children_need_begin_frames_;
-
-  return false;
-}
-
-bool SchedulerStateMachine::BeginFrameNeeded() const {
-  // We can't handle BeginFrames when output surface isn't initialized.
-  // TODO(brianderson): Support output surface creation inside a BeginFrame.
-  if (!HasInitializedOutputSurface())
-    return false;
-
-  if (SupportsProactiveBeginFrame()) {
-    return (BeginFrameNeededToAnimateOrDraw() ||
-            BeginFrameNeededForChildren() ||
-            ProactiveBeginFrameWanted());
-  }
-
-  // Proactive BeginFrames are bad for the synchronous compositor because we
-  // have to draw when we get the BeginFrame and could end up drawing many
-  // duplicate frames if our new frame isn't ready in time.
-  // To poll for state with the synchronous compositor without having to draw,
-  // we rely on ShouldPollForAnticipatedDrawTriggers instead.
-  // Synchronous compositor doesn't have a browser.
-  DCHECK(!children_need_begin_frames_);
-  return BeginFrameNeededToAnimateOrDraw();
-}
-
-bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
-  // ShouldPollForAnticipatedDrawTriggers is what we use in place of
-  // ProactiveBeginFrameWanted when we are using the synchronous
-  // compositor.
-  if (!SupportsProactiveBeginFrame()) {
-    return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
-  }
-
-  // Non synchronous compositors should rely on
-  // ProactiveBeginFrameWanted to poll for state instead.
-  return false;
-}
-
-// Note: If SupportsProactiveBeginFrame is false, the scheduler should poll
-// for changes in it's draw state so it can request a BeginFrame when it's
-// actually ready.
-bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
-  // It is undesirable to proactively request BeginFrames if we are
-  // using a synchronous compositor because we *must* draw for every
-  // BeginFrame, which could cause duplicate draws.
-  return !settings_.using_synchronous_renderer_compositor;
-}
-
-void SchedulerStateMachine::SetChildrenNeedBeginFrames(
-    bool children_need_begin_frames) {
-  children_need_begin_frames_ = children_need_begin_frames;
-}
-
-void SchedulerStateMachine::SetDeferCommits(bool defer_commits) {
-  defer_commits_ = defer_commits;
-}
-
-// These are the cases where we definitely (or almost definitely) have a
-// new frame to animate and/or draw and can draw.
-bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const {
-  // The forced draw respects our normal draw scheduling, so we need to
-  // request a BeginImplFrame for it.
-  if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
-    return true;
-
-  return needs_animate_ || needs_redraw_;
-}
-
-// These are cases where we are very likely to draw soon, but might not
-// actually have a new frame to draw when we receive the next BeginImplFrame.
-// Proactively requesting the BeginImplFrame helps hide the round trip latency
-// of the SetNeedsBeginFrame request that has to go to the Browser.
-bool SchedulerStateMachine::ProactiveBeginFrameWanted() const {
-  // Do not be proactive when invisible.
-  if (!visible_)
-    return false;
-
-  // We should proactively request a BeginImplFrame if a commit is pending
-  // because we will want to draw if the commit completes quickly.
-  if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
-    return true;
-
-  // If the pending tree activates quickly, we'll want a BeginImplFrame soon
-  // to draw the new active tree.
-  if (has_pending_tree_)
-    return true;
-
-  // Changing priorities may allow us to activate (given the new priorities),
-  // which may result in a new frame.
-  if (needs_prepare_tiles_)
-    return true;
-
-  // If we just sent a swap request, it's likely that we are going to produce
-  // another frame soon. This helps avoid negative glitches in our
-  // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame
-  // provider and get sampled at an inopportune time, delaying the next
-  // BeginImplFrame.
-  if (request_swap_funnel_)
-    return true;
-
-  // If the last commit was aborted because of early out (no updates), we should
-  // still want a begin frame in case there is a commit coming again.
-  if (last_commit_had_no_updates_)
-    return true;
-
-  return false;
-}
-
-void SchedulerStateMachine::OnBeginImplFrame() {
-  AdvanceCurrentFrameNumber();
-  DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE)
-      << AsValue()->ToString();
-  begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING;
-  last_commit_had_no_updates_ = false;
-}
-
-void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
-  DCHECK_EQ(begin_impl_frame_state_,
-            BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)
-      << AsValue()->ToString();
-  begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
-}
-
-void SchedulerStateMachine::OnBeginImplFrameDeadline() {
-  DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
-      << AsValue()->ToString();
-  begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
-}
-
-void SchedulerStateMachine::OnBeginImplFrameIdle() {
-  DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
-      << AsValue()->ToString();
-  begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
-}
-
-SchedulerStateMachine::BeginImplFrameDeadlineMode
-SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
-  if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
-    return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
-  } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) {
-    // We have an animation or fast input path on the impl thread that wants
-    // to draw, so don't wait too long for a new active tree.
-    // If we are swap throttled we should wait until we are unblocked.
-    return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
-  } else {
-    // The impl thread doesn't have anything it wants to draw and we are just
-    // waiting for a new active tree or we are swap throttled. In short we are
-    // blocked.
-    return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
-  }
-}
-
-bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
-    const {
-  // TODO(brianderson): This should take into account multiple commit sources.
-
-  if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
-    return false;
-
-  // If we've lost the output surface, end the current BeginImplFrame ASAP
-  // so we can start creating the next output surface.
-  if (output_surface_state_ == OUTPUT_SURFACE_LOST)
-    return true;
-
-  // SwapAck throttle the deadline since we wont draw and swap anyway.
-  if (pending_swaps_ >= max_pending_swaps_)
-    return false;
-
-  if (active_tree_needs_first_draw_)
-    return true;
-
-  if (!needs_redraw_)
-    return false;
-
-  // This is used to prioritize impl-thread draws when the main thread isn't
-  // producing anything, e.g., after an aborted commit. We also check that we
-  // don't have a pending tree -- otherwise we should give it a chance to
-  // activate.
-  // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
-  if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_)
-    return true;
-
-  // Prioritize impl-thread draws in impl_latency_takes_priority_ mode.
-  if (impl_latency_takes_priority_)
-    return true;
-
-  return false;
-}
-
-bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const {
-  // If a commit is pending before the previous commit has been drawn, we
-  // are definitely in a high latency mode.
-  if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_))
-    return true;
-
-  // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main
-  // thread is in a low latency mode.
-  if (send_begin_main_frame_funnel_ &&
-      (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING ||
-       begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME))
-    return false;
-
-  // If there's a commit in progress it must either be from the previous frame
-  // or it started after the impl thread's deadline. In either case the main
-  // thread is in high latency mode.
-  if (CommitPending())
-    return true;
-
-  // Similarly, if there's a pending tree the main thread is in high latency
-  // mode, because either
-  //   it's from the previous frame
-  // or
-  //   we're currently drawing the active tree and the pending tree will thus
-  //   only be drawn in the next frame.
-  if (has_pending_tree_)
-    return true;
-
-  if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
-    // Even if there's a new active tree to draw at the deadline or we've just
-    // swapped it, it may have been triggered by a previous BeginImplFrame, in
-    // which case the main thread is in a high latency mode.
-    return (active_tree_needs_first_draw_ || perform_swap_funnel_) &&
-           !send_begin_main_frame_funnel_;
-  }
-
-  // If the active tree needs its first draw in any other state, we know the
-  // main thread is in a high latency mode.
-  return active_tree_needs_first_draw_;
-}
-
-void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() {
-  AdvanceCurrentFrameNumber();
-  inside_poll_for_anticipated_draw_triggers_ = true;
-}
-
-void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() {
-  inside_poll_for_anticipated_draw_triggers_ = false;
-}
-
-void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
-
-void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
-
-void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
-
-void SchedulerStateMachine::SetNeedsAnimate() {
-  needs_animate_ = true;
-}
-
-void SchedulerStateMachine::SetNeedsPrepareTiles() {
-  if (!needs_prepare_tiles_) {
-    TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
-    needs_prepare_tiles_ = true;
-  }
-}
-
-void SchedulerStateMachine::SetMaxSwapsPending(int max) {
-  max_pending_swaps_ = max;
-}
-
-void SchedulerStateMachine::DidSwapBuffers() {
-  pending_swaps_++;
-  DCHECK_LE(pending_swaps_, max_pending_swaps_);
-  DCHECK(!perform_swap_funnel_);
-
-  perform_swap_funnel_ = true;
-  last_frame_number_swap_performed_ = current_frame_number_;
-}
-
-void SchedulerStateMachine::DidSwapBuffersComplete() {
-  DCHECK_GT(pending_swaps_, 0);
-  pending_swaps_--;
-}
-
-void SchedulerStateMachine::SetImplLatencyTakesPriority(
-    bool impl_latency_takes_priority) {
-  impl_latency_takes_priority_ = impl_latency_takes_priority;
-}
-
-void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) {
-  switch (result) {
-    case INVALID_RESULT:
-      NOTREACHED() << "Uninitialized DrawResult.";
-      break;
-    case DRAW_ABORTED_CANT_DRAW:
-    case DRAW_ABORTED_CONTEXT_LOST:
-      NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:"
-                   << result;
-      break;
-    case DRAW_SUCCESS:
-      consecutive_checkerboard_animations_ = 0;
-      forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
-      break;
-    case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS:
-      needs_redraw_ = true;
-
-      // If we're already in the middle of a redraw, we don't need to
-      // restart it.
-      if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE)
-        return;
-
-      needs_commit_ = true;
-      consecutive_checkerboard_animations_++;
-      if (settings_.timeout_and_draw_when_animation_checkerboards &&
-          consecutive_checkerboard_animations_ >=
-              settings_.maximum_number_of_failed_draws_before_draw_is_forced_) {
-        consecutive_checkerboard_animations_ = 0;
-        // We need to force a draw, but it doesn't make sense to do this until
-        // we've committed and have new textures.
-        forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
-      }
-      break;
-    case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT:
-      // It's not clear whether this missing content is because of missing
-      // pictures (which requires a commit) or because of memory pressure
-      // removing textures (which might not).  To be safe, request a commit
-      // anyway.
-      needs_commit_ = true;
-      break;
-  }
-}
-
-void SchedulerStateMachine::SetNeedsCommit() {
-  needs_commit_ = true;
-}
-
-void SchedulerStateMachine::NotifyReadyToCommit() {
-  DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED)
-      << AsValue()->ToString();
-  commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
-  // In main thread low latency mode, commit should happen right after
-  // BeginFrame, meaning when this function is called, next action should be
-  // commit.
-  if (settings_.main_thread_should_always_be_low_latency)
-    DCHECK(ShouldCommit());
-}
-
-void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) {
-  DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  switch (reason) {
-    case CommitEarlyOutReason::ABORTED_OUTPUT_SURFACE_LOST:
-    case CommitEarlyOutReason::ABORTED_NOT_VISIBLE:
-    case CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT:
-      commit_state_ = COMMIT_STATE_IDLE;
-      SetNeedsCommit();
-      return;
-    case CommitEarlyOutReason::FINISHED_NO_UPDATES:
-      bool commit_has_no_updates = true;
-      UpdateStateOnCommit(commit_has_no_updates);
-      return;
-  }
-}
-
-void SchedulerStateMachine::DidPrepareTiles() {
-  needs_prepare_tiles_ = false;
-  // "Fill" the PrepareTiles funnel.
-  prepare_tiles_funnel_++;
-}
-
-void SchedulerStateMachine::DidLoseOutputSurface() {
-  if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
-      output_surface_state_ == OUTPUT_SURFACE_CREATING)
-    return;
-  output_surface_state_ = OUTPUT_SURFACE_LOST;
-  needs_redraw_ = false;
-}
-
-void SchedulerStateMachine::NotifyReadyToActivate() {
-  if (has_pending_tree_)
-    pending_tree_is_ready_for_activation_ = true;
-}
-
-void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
-  DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
-  output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
-
-  if (did_create_and_initialize_first_output_surface_) {
-    // TODO(boliu): See if we can remove this when impl-side painting is always
-    // on. Does anything on the main thread need to update after recreate?
-    needs_commit_ = true;
-  }
-  did_create_and_initialize_first_output_surface_ = true;
-  pending_swaps_ = 0;
-}
-
-void SchedulerStateMachine::NotifyBeginMainFrameStarted() {
-  DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED;
-}
-
-bool SchedulerStateMachine::HasInitializedOutputSurface() const {
-  switch (output_surface_state_) {
-    case OUTPUT_SURFACE_LOST:
-    case OUTPUT_SURFACE_CREATING:
-      return false;
-
-    case OUTPUT_SURFACE_ACTIVE:
-    case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
-    case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
-      return true;
-  }
-  NOTREACHED();
-  return false;
-}
-
-std::string SchedulerStateMachine::GetStatesForDebugging() const {
-  return base::StringPrintf("%c %d %d %d %c %c %c %d %d",
-      needs_commit_ ? 'T' : 'F',
-      static_cast<int>(output_surface_state_),
-      static_cast<int>(begin_impl_frame_state_),
-      static_cast<int>(commit_state_),
-      has_pending_tree_ ? 'T' : 'F',
-      pending_tree_is_ready_for_activation_ ? 'T' : 'F',
-      active_tree_needs_first_draw_ ? 'T' : 'F',
-      max_pending_swaps_,
-      pending_swaps_);
-}
-
-}  // namespace cc
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
deleted file mode 100644
index c5121d9..0000000
--- a/cc/scheduler/scheduler_state_machine.h
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
-#define CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/scheduler/commit_earlyout_reason.h"
-#include "cc/scheduler/draw_result.h"
-#include "cc/scheduler/scheduler_settings.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-class TracedValue;
-}
-class Value;
-}
-
-namespace cc {
-
-// The SchedulerStateMachine decides how to coordinate main thread activites
-// like painting/running javascript with rendering and input activities on the
-// impl thread.
-//
-// The state machine tracks internal state but is also influenced by external
-// state.  Internal state includes things like whether a frame has been
-// requested, while external state includes things like the current time being
-// near to the vblank time.
-//
-// The scheduler seperates "what to do next" from the updating of its internal
-// state to make testing cleaner.
-class SchedulerStateMachine {
- public:
-  // settings must be valid for the lifetime of this class.
-  explicit SchedulerStateMachine(const SchedulerSettings& settings);
-
-  enum OutputSurfaceState {
-    OUTPUT_SURFACE_ACTIVE,
-    OUTPUT_SURFACE_LOST,
-    OUTPUT_SURFACE_CREATING,
-    OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT,
-    OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION,
-  };
-  static const char* OutputSurfaceStateToString(OutputSurfaceState state);
-
-  // Note: BeginImplFrameState will always cycle through all the states in
-  // order. Whether or not it actually waits or draws, it will at least try to
-  // wait in BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME and try to draw in
-  // BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
-  enum BeginImplFrameState {
-    BEGIN_IMPL_FRAME_STATE_IDLE,
-    BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
-    BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
-    BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
-  };
-  static const char* BeginImplFrameStateToString(BeginImplFrameState state);
-
-  enum BeginImplFrameDeadlineMode {
-    BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE,
-    BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR,
-    BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE,
-  };
-  static const char* BeginImplFrameDeadlineModeToString(
-      BeginImplFrameDeadlineMode mode);
-
-  enum CommitState {
-    COMMIT_STATE_IDLE,
-    COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
-    COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
-    COMMIT_STATE_READY_TO_COMMIT,
-    COMMIT_STATE_WAITING_FOR_ACTIVATION,
-    COMMIT_STATE_WAITING_FOR_DRAW,
-  };
-  static const char* CommitStateToString(CommitState state);
-
-  enum ForcedRedrawOnTimeoutState {
-    FORCED_REDRAW_STATE_IDLE,
-    FORCED_REDRAW_STATE_WAITING_FOR_COMMIT,
-    FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION,
-    FORCED_REDRAW_STATE_WAITING_FOR_DRAW,
-  };
-  static const char* ForcedRedrawOnTimeoutStateToString(
-      ForcedRedrawOnTimeoutState state);
-
-  bool CommitPending() const {
-    return commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
-           commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED ||
-           commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
-  }
-  CommitState commit_state() const { return commit_state_; }
-
-  bool RedrawPending() const { return needs_redraw_; }
-  bool PrepareTilesPending() const { return needs_prepare_tiles_; }
-
-  enum Action {
-    ACTION_NONE,
-    ACTION_ANIMATE,
-    ACTION_SEND_BEGIN_MAIN_FRAME,
-    ACTION_COMMIT,
-    ACTION_ACTIVATE_SYNC_TREE,
-    ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-    ACTION_DRAW_AND_SWAP_FORCED,
-    ACTION_DRAW_AND_SWAP_ABORT,
-    ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
-    ACTION_PREPARE_TILES,
-  };
-  static const char* ActionToString(Action action);
-
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* dict) const;
-
-  Action NextAction() const;
-  void UpdateState(Action action);
-
-  // Indicates whether the impl thread needs a BeginImplFrame callback in order
-  // to make progress.
-  bool BeginFrameNeeded() const;
-
-  // Indicates that we need to independently poll for new state and actions
-  // because we can't expect a BeginImplFrame. This is mostly used to avoid
-  // drawing repeat frames with the synchronous compositor without dropping
-  // necessary actions on the floor.
-  bool ShouldPollForAnticipatedDrawTriggers() const;
-
-  // Indicates that the system has entered and left a BeginImplFrame callback.
-  // The scheduler will not draw more than once in a given BeginImplFrame
-  // callback nor send more than one BeginMainFrame message.
-  void OnBeginImplFrame();
-  void OnBeginImplFrameDeadlinePending();
-  void OnBeginImplFrameDeadline();
-  void OnBeginImplFrameIdle();
-  BeginImplFrameState begin_impl_frame_state() const {
-    return begin_impl_frame_state_;
-  }
-  BeginImplFrameDeadlineMode CurrentBeginImplFrameDeadlineMode() const;
-
-  // If the main thread didn't manage to produce a new frame in time for the
-  // impl thread to draw, it is in a high latency mode.
-  bool MainThreadIsInHighLatencyMode() const;
-
-  // PollForAnticipatedDrawTriggers is used by the synchronous compositor to
-  // avoid requesting BeginImplFrames when we won't actually draw but still
-  // need to advance our state at vsync intervals.
-  void DidEnterPollForAnticipatedDrawTriggers();
-  void DidLeavePollForAnticipatedDrawTriggers();
-  bool inside_poll_for_anticipated_draw_triggers() const {
-    return inside_poll_for_anticipated_draw_triggers_;
-  }
-
-  // Indicates whether the LayerTreeHostImpl is visible.
-  void SetVisible(bool visible);
-  bool visible() const { return visible_; }
-
-  // Indicates that a redraw is required, either due to the impl tree changing
-  // or the screen being damaged and simply needing redisplay.
-  void SetNeedsRedraw();
-  bool needs_redraw() const { return needs_redraw_; }
-
-  void SetNeedsAnimate();
-  bool needs_animate() const { return needs_animate_; }
-
-  // Indicates that prepare-tiles is required. This guarantees another
-  // PrepareTiles will occur shortly (even if no redraw is required).
-  void SetNeedsPrepareTiles();
-
-  // Sets how many swaps can be pending to the OutputSurface.
-  void SetMaxSwapsPending(int max);
-
-  // If the scheduler attempted to draw and swap, this provides feedback
-  // regarding whether or not the swap actually occured. We might skip the
-  // swap when there is not damage, for example.
-  void DidSwapBuffers();
-
-  // Indicates whether a redraw is required because we are currently rendering
-  // with a low resolution or checkerboarded tile.
-  void SetSwapUsedIncompleteTile(bool used_incomplete_tile);
-
-  // Notification from the OutputSurface that a swap has been consumed.
-  void DidSwapBuffersComplete();
-
-  // Indicates whether to prioritize impl thread latency (i.e., animation
-  // smoothness) over new content activation.
-  void SetImplLatencyTakesPriority(bool impl_latency_takes_priority);
-  bool impl_latency_takes_priority() const {
-    return impl_latency_takes_priority_;
-  }
-
-  // Indicates whether ACTION_DRAW_AND_SWAP_IF_POSSIBLE drew to the screen.
-  void DidDrawIfPossibleCompleted(DrawResult result);
-
-  // Indicates that a new commit flow needs to be performed, either to pull
-  // updates from the main thread to the impl, or to push deltas from the impl
-  // thread to main.
-  void SetNeedsCommit();
-
-  // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
-  // from NextAction.
-  // Indicates that all painting is complete.
-  void NotifyReadyToCommit();
-
-  // Call this only in response to receiving an ACTION_SEND_BEGIN_MAIN_FRAME
-  // from NextAction if the client rejects the BeginMainFrame message.
-  void BeginMainFrameAborted(CommitEarlyOutReason reason);
-
-  // Set that we can create the first OutputSurface and start the scheduler.
-  void SetCanStart() { can_start_ = true; }
-  // Allow access of the can_start_ state in tests.
-  bool CanStartForTesting() const { return can_start_; }
-
-  void SetSkipNextBeginMainFrameToReduceLatency();
-
-  // Indicates whether drawing would, at this time, make sense.
-  // CanDraw can be used to suppress flashes or checkerboarding
-  // when such behavior would be undesirable.
-  void SetCanDraw(bool can);
-
-  // Indicates that scheduled BeginMainFrame is started.
-  void NotifyBeginMainFrameStarted();
-
-  // Indicates that the pending tree is ready for activation.
-  void NotifyReadyToActivate();
-
-  bool has_pending_tree() const { return has_pending_tree_; }
-  bool active_tree_needs_first_draw() const {
-    return active_tree_needs_first_draw_;
-  }
-
-  void DidPrepareTiles();
-  void DidLoseOutputSurface();
-  void DidCreateAndInitializeOutputSurface();
-  bool HasInitializedOutputSurface() const;
-
-  // True if we need to abort draws to make forward progress.
-  bool PendingDrawsShouldBeAborted() const;
-
-  bool SupportsProactiveBeginFrame() const;
-
-  void SetContinuousPainting(bool continuous_painting) {
-    continuous_painting_ = continuous_painting;
-  }
-
-  bool CouldSendBeginMainFrame() const;
-
-  void SetDeferCommits(bool defer_commits);
-
-  // TODO(zmo): This is temporary for debugging crbug.com/393331.
-  // We should remove it afterwards.
-  std::string GetStatesForDebugging() const;
-
-  void SetChildrenNeedBeginFrames(bool children_need_begin_frames);
-  bool children_need_begin_frames() const {
-    return children_need_begin_frames_;
-  }
-
- protected:
-  bool BeginFrameNeededToAnimateOrDraw() const;
-  bool BeginFrameNeededForChildren() const;
-  bool ProactiveBeginFrameWanted() const;
-
-  bool ShouldTriggerBeginImplFrameDeadlineImmediately() const;
-
-  // True if we need to force activations to make forward progress.
-  bool PendingActivationsShouldBeForced() const;
-
-  bool ShouldAnimate() const;
-  bool ShouldBeginOutputSurfaceCreation() const;
-  bool ShouldDraw() const;
-  bool ShouldActivatePendingTree() const;
-  bool ShouldSendBeginMainFrame() const;
-  bool ShouldCommit() const;
-  bool ShouldPrepareTiles() const;
-
-  void AdvanceCurrentFrameNumber();
-
-  void UpdateStateOnCommit(bool commit_had_no_updates);
-  void UpdateStateOnActivation();
-  void UpdateStateOnDraw(bool did_request_swap);
-  void UpdateStateOnPrepareTiles();
-
-  const SchedulerSettings settings_;
-
-  OutputSurfaceState output_surface_state_;
-  BeginImplFrameState begin_impl_frame_state_;
-  CommitState commit_state_;
-  ForcedRedrawOnTimeoutState forced_redraw_state_;
-
-  // These are used for tracing only.
-  int commit_count_;
-  int current_frame_number_;
-  int last_frame_number_animate_performed_;
-  int last_frame_number_swap_performed_;
-  int last_frame_number_swap_requested_;
-  int last_frame_number_begin_main_frame_sent_;
-
-  // These are used to ensure that an action only happens once per frame,
-  // deadline, etc.
-  bool animate_funnel_;
-  bool perform_swap_funnel_;
-  bool request_swap_funnel_;
-  bool send_begin_main_frame_funnel_;
-  // prepare_tiles_funnel_ is "filled" each time PrepareTiles is called
-  // and "drained" on each BeginImplFrame. If the funnel gets too full,
-  // we start throttling ACTION_PREPARE_TILES such that we average one
-  // PrepareTiles per BeginImplFrame.
-  int prepare_tiles_funnel_;
-
-  int consecutive_checkerboard_animations_;
-  int max_pending_swaps_;
-  int pending_swaps_;
-  bool needs_redraw_;
-  bool needs_animate_;
-  bool needs_prepare_tiles_;
-  bool needs_commit_;
-  bool inside_poll_for_anticipated_draw_triggers_;
-  bool visible_;
-  bool can_start_;
-  bool can_draw_;
-  bool has_pending_tree_;
-  bool pending_tree_is_ready_for_activation_;
-  bool active_tree_needs_first_draw_;
-  bool did_create_and_initialize_first_output_surface_;
-  bool impl_latency_takes_priority_;
-  bool skip_next_begin_main_frame_to_reduce_latency_;
-  bool skip_begin_main_frame_to_reduce_latency_;
-  bool continuous_painting_;
-  bool children_need_begin_frames_;
-  bool defer_commits_;
-  bool last_commit_had_no_updates_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine);
-};
-
-}  // namespace cc
-
-#endif  // CC_SCHEDULER_SCHEDULER_STATE_MACHINE_H_
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
deleted file mode 100644
index 4c2c267..0000000
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ /dev/null
@@ -1,1850 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/scheduler_state_machine.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/scheduler/scheduler.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// Macro to compare two enum values and get nice output.
-// Without:
-//   Value of: actual()      Actual: 7
-//   Expected: expected()  Which is: 0
-// With:
-//   Value of: actual()      Actual: "ACTION_ANIMATE"
-//   Expected: expected()  Which is: "ACTION_NONE"
-#define EXPECT_ENUM_EQ(enum_tostring, expected, actual)        \
-  EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \
-               SchedulerStateMachine::enum_tostring(actual))
-
-#define EXPECT_IMPL_FRAME_STATE(expected)               \
-  EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \
-                 state.begin_impl_frame_state())        \
-      << state.AsValue()->ToString()
-
-#define EXPECT_COMMIT_STATE(expected) \
-  EXPECT_ENUM_EQ(CommitStateToString, expected, state.CommitState())
-
-#define EXPECT_ACTION(expected)                                \
-  EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \
-      << state.AsValue()->ToString()
-
-#define EXPECT_ACTION_UPDATE_STATE(action)                                  \
-  EXPECT_ACTION(action);                                                    \
-  if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE ||  \
-      action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) {       \
-    EXPECT_IMPL_FRAME_STATE(                                                \
-        SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);     \
-  }                                                                         \
-  state.UpdateState(action);                                                \
-  if (action == SchedulerStateMachine::ACTION_NONE) {                       \
-    if (state.begin_impl_frame_state() ==                                   \
-        SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
-      state.OnBeginImplFrameDeadlinePending();                              \
-    if (state.begin_impl_frame_state() ==                                   \
-        SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)      \
-      state.OnBeginImplFrameIdle();                                         \
-  }
-
-#define SET_UP_STATE(state)                                    \
-  state.SetCanStart();                                         \
-  state.UpdateState(state.NextAction());                       \
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit(); \
-  state.SetVisible(true);                                      \
-  state.SetCanDraw(true);
-
-namespace cc {
-
-namespace {
-
-const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
-    {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
-     SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
-     SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
-     SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
-
-const SchedulerStateMachine::CommitState all_commit_states[] = {
-    SchedulerStateMachine::COMMIT_STATE_IDLE,
-    SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
-    SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
-    SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
-    SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
-    SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW};
-
-// Exposes the protected state fields of the SchedulerStateMachine for testing
-class StateMachine : public SchedulerStateMachine {
- public:
-  explicit StateMachine(const SchedulerSettings& scheduler_settings)
-      : SchedulerStateMachine(scheduler_settings) {}
-
-  void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
-    DidCreateAndInitializeOutputSurface();
-    output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
-  }
-
-  void SetCommitState(CommitState cs) { commit_state_ = cs; }
-  CommitState CommitState() const { return commit_state_; }
-
-  ForcedRedrawOnTimeoutState ForcedRedrawState() const {
-    return forced_redraw_state_;
-  }
-
-  void SetBeginImplFrameState(BeginImplFrameState bifs) {
-    begin_impl_frame_state_ = bifs;
-  }
-
-  BeginImplFrameState begin_impl_frame_state() const {
-    return begin_impl_frame_state_;
-  }
-
-  OutputSurfaceState output_surface_state() const {
-    return output_surface_state_;
-  }
-
-  bool NeedsCommit() const { return needs_commit_; }
-
-  void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
-
-  void SetNeedsForcedRedrawForTimeout(bool b) {
-    forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
-    active_tree_needs_first_draw_ = true;
-  }
-  bool NeedsForcedRedrawForTimeout() const {
-    return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
-  }
-
-  void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
-    active_tree_needs_first_draw_ = needs_first_draw;
-  }
-
-  bool CanDraw() const { return can_draw_; }
-  bool Visible() const { return visible_; }
-
-  bool PendingActivationsShouldBeForced() const {
-    return SchedulerStateMachine::PendingActivationsShouldBeForced();
-  }
-
-  void SetHasPendingTree(bool has_pending_tree) {
-    has_pending_tree_ = has_pending_tree;
-  }
-
-  using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately;
-  using SchedulerStateMachine::ProactiveBeginFrameWanted;
-  using SchedulerStateMachine::UpdateStateOnCommit;
-};
-
-TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
-  SchedulerSettings default_scheduler_settings;
-
-  // If no commit needed, do nothing.
-  {
-    StateMachine state(default_scheduler_settings);
-    state.SetCanStart();
-    EXPECT_ACTION_UPDATE_STATE(
-        SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
-    state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-    state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
-    state.SetNeedsRedraw(false);
-    state.SetVisible(true);
-
-    EXPECT_FALSE(state.BeginFrameNeeded());
-
-    EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-    EXPECT_FALSE(state.BeginFrameNeeded());
-    state.OnBeginImplFrame();
-
-    EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-    state.OnBeginImplFrameDeadline();
-  }
-
-  // If commit requested but can_start is still false, do nothing.
-  {
-    StateMachine state(default_scheduler_settings);
-    state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
-    state.SetNeedsRedraw(false);
-    state.SetVisible(true);
-    state.SetNeedsCommit();
-
-    EXPECT_FALSE(state.BeginFrameNeeded());
-
-    EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-    EXPECT_FALSE(state.BeginFrameNeeded());
-    state.OnBeginImplFrame();
-    EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-    state.OnBeginImplFrameDeadline();
-  }
-
-  // If commit requested, begin a main frame.
-  {
-    StateMachine state(default_scheduler_settings);
-    state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
-    state.SetCanStart();
-    state.UpdateState(state.NextAction());
-    state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-    state.SetNeedsRedraw(false);
-    state.SetVisible(true);
-    state.SetNeedsCommit();
-
-    EXPECT_TRUE(state.BeginFrameNeeded());
-
-    state.OnBeginImplFrame();
-    EXPECT_ACTION_UPDATE_STATE(
-        SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  }
-
-  // Begin the frame, make sure needs_commit and commit_state update correctly.
-  {
-    StateMachine state(default_scheduler_settings);
-    state.SetCanStart();
-    state.UpdateState(state.NextAction());
-    state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-    state.SetVisible(true);
-    state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-    EXPECT_COMMIT_STATE(
-        SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-    EXPECT_FALSE(state.NeedsCommit());
-  }
-}
-
-// Explicitly test main_frame_before_activation_enabled = true
-TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
-  SchedulerSettings scheduler_settings;
-  scheduler_settings.impl_side_painting = true;
-  scheduler_settings.main_frame_before_activation_enabled = true;
-  StateMachine state(scheduler_settings);
-  state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  SET_UP_STATE(state)
-  state.SetNeedsRedraw(false);
-  state.SetNeedsCommit();
-
-  EXPECT_TRUE(state.BeginFrameNeeded());
-
-  // Commit to the pending tree.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify that the next commit starts while there is still a pending tree.
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify the pending commit doesn't overwrite the pending
-  // tree until the pending tree has been activated.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify NotifyReadyToActivate unblocks activation, draw, and
-  // commit in that order.
-  state.NotifyReadyToActivate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsRedraw(true);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-
-  // We're drawing now.
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  EXPECT_FALSE(state.RedrawPending());
-  EXPECT_FALSE(state.CommitPending());
-
-  // Failing the draw makes us require a commit.
-  state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_TRUE(state.CommitPending());
-}
-
-TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsRedraw(true);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_TRUE(state.BeginFrameNeeded());
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_FALSE(state.RedrawPending());
-  EXPECT_FALSE(state.CommitPending());
-
-  // Missing high res content requires a commit (but not a redraw)
-  state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_FALSE(state.RedrawPending());
-  EXPECT_TRUE(state.CommitPending());
-}
-
-TEST(SchedulerStateMachineTest,
-     TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsRedraw(true);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-
-  // We're drawing now.
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_FALSE(state.RedrawPending());
-  EXPECT_FALSE(state.CommitPending());
-
-  // While still in the same BeginMainFrame callback on the main thread,
-  // set needs redraw again. This should not redraw.
-  state.SetNeedsRedraw(true);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Failing the draw for animation checkerboards makes us require a commit.
-  state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_TRUE(state.RedrawPending());
-}
-
-TEST(SchedulerStateMachineTest,
-     TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
-  SchedulerSettings scheduler_settings;
-  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start a commit.
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.CommitPending());
-
-  // Then initiate a draw.
-  state.SetNeedsRedraw(true);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-
-  // Fail the draw.
-  state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  EXPECT_TRUE(state.RedrawPending());
-  // But the commit is ongoing.
-  EXPECT_TRUE(state.CommitPending());
-
-  // Finish the commit. Note, we should not yet be forcing a draw, but should
-  // continue the commit as usual.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.RedrawPending());
-
-  // The redraw should be forced at the end of the next BeginImplFrame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-}
-
-TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
-  SchedulerSettings scheduler_settings;
-  int draw_limit = 1;
-  scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
-      draw_limit;
-  scheduler_settings.impl_side_painting = true;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start a commit.
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.CommitPending());
-
-  // Then initiate a draw.
-  state.SetNeedsRedraw(true);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-
-  // Fail the draw enough times to force a redraw,
-  // then once more for good measure.
-  for (int i = 0; i < draw_limit + 1; ++i)
-    state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  EXPECT_TRUE(state.RedrawPending());
-  // But the commit is ongoing.
-  EXPECT_TRUE(state.CommitPending());
-  EXPECT_TRUE(state.ForcedRedrawState() ==
-              SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_FALSE(state.CommitPending());
-
-  // Now force redraw should be in waiting for activation
-  EXPECT_TRUE(state.ForcedRedrawState() ==
-    SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
-
-  // After failing additional draws, we should still be in a forced
-  // redraw, but not back in WAITING_FOR_COMMIT.
-  for (int i = 0; i < draw_limit + 1; ++i)
-    state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_TRUE(state.ForcedRedrawState() ==
-    SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
-}
-
-TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start a draw.
-  state.SetNeedsRedraw(true);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_TRUE(state.RedrawPending());
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-
-  // Failing the draw for animation checkerboards makes us require a commit.
-  state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.RedrawPending());
-
-  // We should not be trying to draw again now, but we have a commit pending.
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // We should try to draw again at the end of the next BeginImplFrame on
-  // the impl thread.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsRedraw(true);
-
-  // Draw the first frame.
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Before the next BeginImplFrame, set needs redraw again.
-  // This should not redraw until the next BeginImplFrame.
-  state.SetNeedsRedraw(true);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Move to another frame. This should now draw.
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  state.OnBeginImplFrame();
-
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // We just swapped, so we should proactively request another BeginImplFrame.
-  EXPECT_TRUE(state.BeginFrameNeeded());
-}
-
-TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
-  SchedulerSettings default_scheduler_settings;
-
-  // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
-  // but not visible, don't draw.
-  size_t num_commit_states =
-      sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
-  size_t num_begin_impl_frame_states =
-      sizeof(all_begin_impl_frame_states) /
-      sizeof(SchedulerStateMachine::BeginImplFrameState);
-  for (size_t i = 0; i < num_commit_states; ++i) {
-    for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
-      StateMachine state(default_scheduler_settings);
-      state.SetCanStart();
-      state.UpdateState(state.NextAction());
-      state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-      state.SetCommitState(all_commit_states[i]);
-      state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
-      bool visible =
-          (all_begin_impl_frame_states[j] !=
-           SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-      state.SetVisible(visible);
-
-      // Case 1: needs_commit=false
-      EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-                state.NextAction());
-
-      // Case 2: needs_commit=true
-      state.SetNeedsCommit();
-      EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-                state.NextAction())
-          << state.AsValue()->ToString();
-    }
-  }
-
-  // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
-  // except if we're ready to commit, in which case we expect a commit first.
-  for (size_t i = 0; i < num_commit_states; ++i) {
-    StateMachine state(default_scheduler_settings);
-    state.SetCanStart();
-    state.UpdateState(state.NextAction());
-    state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-    state.SetCanDraw(true);
-    state.SetCommitState(all_commit_states[i]);
-    state.SetBeginImplFrameState(
-        SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-
-    state.SetNeedsRedraw(true);
-    state.SetVisible(true);
-
-    SchedulerStateMachine::Action expected_action;
-    if (all_commit_states[i] ==
-        SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
-      expected_action = SchedulerStateMachine::ACTION_COMMIT;
-    } else {
-      expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
-      EXPECT_ACTION(SchedulerStateMachine::ACTION_ANIMATE);
-      state.UpdateState(state.NextAction());
-    }
-
-    // Case 1: needs_commit=false.
-    EXPECT_ACTION(expected_action);
-
-    // Case 2: needs_commit=true.
-    state.SetNeedsCommit();
-    EXPECT_ACTION(expected_action);
-  }
-}
-
-TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
-  SchedulerSettings default_scheduler_settings;
-
-  size_t num_commit_states =
-      sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
-  for (size_t i = 0; i < num_commit_states; ++i) {
-    // There shouldn't be any drawing regardless of BeginImplFrame.
-    for (size_t j = 0; j < 2; ++j) {
-      StateMachine state(default_scheduler_settings);
-      state.SetCanStart();
-      state.UpdateState(state.NextAction());
-      state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-      state.SetCommitState(all_commit_states[i]);
-      state.SetVisible(false);
-      state.SetNeedsRedraw(true);
-      if (j == 1) {
-        state.SetBeginImplFrameState(
-            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-      }
-
-      // Case 1: needs_commit=false.
-      EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-                state.NextAction());
-
-      // Case 2: needs_commit=true.
-      state.SetNeedsCommit();
-      EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-                state.NextAction())
-          << state.AsValue()->ToString();
-    }
-  }
-}
-
-TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
-  SchedulerSettings default_scheduler_settings;
-
-  size_t num_commit_states =
-      sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
-  for (size_t i = 0; i < num_commit_states; ++i) {
-    // There shouldn't be any drawing regardless of BeginImplFrame.
-    for (size_t j = 0; j < 2; ++j) {
-      StateMachine state(default_scheduler_settings);
-      state.SetCanStart();
-      state.UpdateState(state.NextAction());
-      state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-      state.SetCommitState(all_commit_states[i]);
-      state.SetVisible(false);
-      state.SetNeedsRedraw(true);
-      if (j == 1)
-        state.OnBeginImplFrame();
-
-      state.SetCanDraw(false);
-      EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
-                state.NextAction());
-    }
-  }
-}
-
-TEST(SchedulerStateMachineTest,
-     TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.UpdateState(state.NextAction());
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-
-  state.SetActiveTreeNeedsFirstDraw(true);
-  state.SetNeedsCommit();
-  state.SetNeedsRedraw(true);
-  state.SetVisible(true);
-  state.SetCanDraw(false);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
-  SchedulerSettings scheduler_settings;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsCommit();
-
-  EXPECT_TRUE(state.BeginFrameNeeded());
-
-  // Begin the frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-
-  // Now, while the frame is in progress, set another commit.
-  state.SetNeedsCommit();
-  EXPECT_TRUE(state.NeedsCommit());
-
-  // Let the frame finish.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
-  // Expect to commit regardless of BeginImplFrame state.
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-
-  state.OnBeginImplFrameDeadlinePending();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-
-  state.OnBeginImplFrameIdle();
-  EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-
-  state.OnBeginImplFrame();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-
-  // Finish the commit, then make sure we start the next commit immediately
-  // and draw on the next BeginImplFrame.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, TestFullCycle) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start clean and set commit.
-  state.SetNeedsCommit();
-
-  // Begin the frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Tell the scheduler the frame finished.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
-  // Commit.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_TRUE(state.needs_redraw());
-
-  // Expect to do nothing until BeginImplFrame deadline
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // At BeginImplFrame deadline, draw.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-
-  // Should be synchronized, no draw needed, no action needed.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_FALSE(state.needs_redraw());
-}
-
-TEST(SchedulerStateMachineTest, TestFullCycleWithMainThreadLowLatencyMode) {
-  SchedulerSettings scheduler_settings;
-  scheduler_settings.main_thread_should_always_be_low_latency = true;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start clean and set commit.
-  state.SetNeedsCommit();
-
-  // Begin the frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Tell the scheduler the frame finished.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
-  // Commit.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_TRUE(state.needs_redraw());
-
-  // Now commit should wait for draw.
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
-
-  // Swap throttled. Do not draw.
-  state.DidSwapBuffers();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.DidSwapBuffersComplete();
-
-  // Haven't draw since last commit, do not begin new main frame.
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // At BeginImplFrame deadline, draw.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-
-  // Now will be able to start main frame.
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_FALSE(state.needs_redraw());
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestFullCycleWithMainThreadLowLatencyMode_ImplSidePaint) {
-  SchedulerSettings scheduler_settings;
-  scheduler_settings.main_thread_should_always_be_low_latency = true;
-  scheduler_settings.impl_side_painting = true;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start clean and set commit.
-  state.SetNeedsCommit();
-
-  // Begin the frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Tell the scheduler the frame finished.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
-  // Commit.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-
-  // Now commit should wait for activation.
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
-
-  // No activation yet, so this commit is not drawn yet. Force to draw this
-  // frame, and still block BeginMainFrame.
-  state.SetNeedsRedraw(true);
-  state.SetNeedsCommit();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Cannot BeginMainFrame yet since last commit is not yet activated and drawn.
-  state.OnBeginImplFrame();
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Now activate sync tree.
-  state.NotifyReadyToActivate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_TRUE(state.needs_redraw());
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_DRAW);
-
-  // Swap throttled. Do not draw.
-  state.DidSwapBuffers();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.DidSwapBuffersComplete();
-
-  // Haven't draw since last commit, do not begin new main frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-
-  // Now will be able to start main frame.
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_FALSE(state.needs_redraw());
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start clean and set commit.
-  state.SetNeedsCommit();
-
-  // Begin the frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Request another commit while the commit is in flight.
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Tell the scheduler the frame finished.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT);
-
-  // First commit.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_TRUE(state.needs_redraw());
-
-  // Expect to do nothing until BeginImplFrame deadline.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // At BeginImplFrame deadline, draw.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
-  state.DidSwapBuffersComplete();
-
-  // Should be synchronized, no draw needed, no action needed.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_FALSE(state.needs_redraw());
-
-  // Next BeginImplFrame should initiate second commit.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.UpdateState(state.NextAction());
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-// See ThreadProxy::BeginMainFrame "EarlyOut_NotVisible" /
-// "EarlyOut_OutputSurfaceLost" cases.
-TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseInvisible) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Start clean and set commit.
-  state.SetNeedsCommit();
-
-  // Begin the frame while visible.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Become invisible and abort BeginMainFrame.
-  state.SetVisible(false);
-  state.BeginMainFrameAborted(CommitEarlyOutReason::ABORTED_NOT_VISIBLE);
-
-  // NeedsCommit should now be true again because we never actually did a
-  // commit.
-  EXPECT_TRUE(state.NeedsCommit());
-
-  // We should now be back in the idle state as if we never started the frame.
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // We shouldn't do anything on the BeginImplFrame deadline.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Become visible again.
-  state.SetVisible(true);
-
-  // Although we have aborted on this frame and haven't cancelled the commit
-  // (i.e. need another), don't send another BeginMainFrame yet.
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.NeedsCommit());
-
-  // Start a new frame.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-
-  // We should be starting the commit now.
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-// See ThreadProxy::BeginMainFrame "EarlyOut_NoUpdates" case.
-TEST(SchedulerStateMachineTest, TestAbortBeginMainFrameBecauseCommitNotNeeded) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.UpdateState(state.NextAction());
-  state.DidCreateAndInitializeOutputSurface();
-  state.SetVisible(true);
-  state.SetCanDraw(true);
-
-  // Get into a begin frame / commit state.
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  // Abort the commit, true means that the BeginMainFrame was sent but there
-  // was no work to do on the main thread.
-  state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
-
-  // NeedsCommit should now be false because the commit was actually handled.
-  EXPECT_FALSE(state.NeedsCommit());
-
-  // Even though the commit was aborted, we still expect to draw the new frame.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify another commit doesn't start on another frame either.
-  EXPECT_FALSE(state.NeedsCommit());
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify another commit can start if requested, though.
-  state.SetNeedsCommit();
-  EXPECT_COMMIT_STATE(SchedulerStateMachine::COMMIT_STATE_IDLE);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.SetVisible(true);
-  state.SetCanDraw(true);
-
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Check that the first init does not SetNeedsCommit.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Check that a needs commit initiates a BeginMainFrame.
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
-            state.NextAction());
-  state.DidLoseOutputSurface();
-
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-  state.UpdateState(state.NextAction());
-
-  // Once context recreation begins, nothing should happen.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Recreate the context.
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-
-  // When the context is recreated, we should begin a commit.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
-  SchedulerSettings default_scheduler_settings;
-  // We use impl side painting because it's the more complicated version.
-  default_scheduler_settings.impl_side_painting = true;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
-            state.NextAction());
-  state.DidLoseOutputSurface();
-  EXPECT_EQ(state.output_surface_state(),
-            SchedulerStateMachine::OUTPUT_SURFACE_LOST);
-
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Once context recreation begins, nothing should happen.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // While context is recreating, commits shouldn't begin.
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Recreate the context
-  state.DidCreateAndInitializeOutputSurface();
-  EXPECT_EQ(state.output_surface_state(),
-            SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
-  EXPECT_FALSE(state.RedrawPending());
-
-  // When the context is recreated, we wait until the next BeginImplFrame
-  // before starting.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // When the BeginFrame comes in we should begin a commit
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_COMMIT_STATE(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-
-  // Until that commit finishes, we shouldn't be drawing or animate.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Finish the commit, which should make the surface active.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_EQ(state.output_surface_state(),
-            SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
-  state.NotifyReadyToActivate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_EQ(state.output_surface_state(),
-            SchedulerStateMachine::OUTPUT_SURFACE_ACTIVE);
-
-  // Finishing the first commit after initializing an output surface should
-  // automatically cause a redraw.
-  EXPECT_TRUE(state.RedrawPending());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_FALSE(state.RedrawPending());
-
-  // Next frame as no work to do.
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Once the context is recreated, whether we draw should be based on
-  // SetCanDraw if waiting on first draw after activate.
-  state.SetNeedsRedraw(true);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.SetCanDraw(false);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-  state.SetCanDraw(true);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Once the context is recreated, whether we draw should be based on
-  // SetCanDraw if waiting on first draw after activate.
-  state.SetNeedsRedraw(true);
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  // Activate so we need the first draw
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  state.NotifyReadyToActivate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_TRUE(state.needs_redraw());
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.SetCanDraw(false);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-  state.SetCanDraw(true);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-}
-
-TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
-  SchedulerSettings scheduler_settings;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Get a commit in flight.
-  state.SetNeedsCommit();
-
-  // Set damage and expect a draw.
-  state.SetNeedsRedraw(true);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Cause a lost context while the BeginMainFrame is in flight.
-  state.DidLoseOutputSurface();
-
-  // Ask for another draw. Expect nothing happens.
-  state.SetNeedsRedraw(true);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  // Finish the frame, and commit.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-
-  // We will abort the draw when the output surface is lost if we are
-  // waiting for the first draw to unblock the main thread.
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-
-  // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
-  EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-
-  state.OnBeginImplFrame();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadlinePending();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
-  SchedulerSettings scheduler_settings;
-  StateMachine state(scheduler_settings);
-  SET_UP_STATE(state)
-
-  // Get a commit in flight.
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Set damage and expect a draw.
-  state.SetNeedsRedraw(true);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Cause a lost context while the BeginMainFrame is in flight.
-  state.DidLoseOutputSurface();
-
-  // Ask for another draw and also set needs commit. Expect nothing happens.
-  state.SetNeedsRedraw(true);
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Finish the frame, and commit.
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-
-  // Because the output surface is missing, we expect the draw to abort.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-
-  // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
-  EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-
-  state.OnBeginImplFrame();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadlinePending();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_IMPL_FRAME_STATE(
-      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameIdle();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-
-  // After we get a new output surface, the commit flow should start.
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  state.SetNeedsRedraw(true);
-
-  // Cause a lost output surface, and restore it.
-  state.DidLoseOutputSurface();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-  state.UpdateState(state.NextAction());
-  state.DidCreateAndInitializeOutputSurface();
-
-  EXPECT_FALSE(state.RedrawPending());
-  state.OnBeginImplFrame();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  state.SetCommitState(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-
-  // Cause a lost context.
-  state.DidLoseOutputSurface();
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-
-  EXPECT_TRUE(state.PendingActivationsShouldBeForced());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-
-  EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-}
-
-TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.UpdateState(state.NextAction());
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-  state.SetVisible(false);
-  state.SetNeedsCommit();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  state.SetCanStart();
-  state.UpdateState(state.NextAction());
-  state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
-  state.SetVisible(false);
-  state.SetCommitState(
-      SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
-  state.SetNeedsCommit();
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_COMMIT);
-  state.UpdateState(state.NextAction());
-
-  EXPECT_TRUE(state.active_tree_needs_first_draw());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
-}
-
-TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  state.SetNeedsCommit();
-  state.DidLoseOutputSurface();
-
-  // When we are visible, we normally want to begin output surface creation
-  // as soon as possible.
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
-
-  state.DidCreateAndInitializeOutputSurface();
-  EXPECT_EQ(state.output_surface_state(),
-            SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
-
-  // We should not send a BeginMainFrame when we are invisible, even if we've
-  // lost the output surface and are trying to get the first commit, since the
-  // main thread will just abort anyway.
-  state.SetVisible(false);
-  EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-  EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
-
-  state.SetCanDraw(false);
-  state.SetVisible(true);
-  EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
-  state.SetCanDraw(true);
-  state.SetVisible(false);
-  EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
-  state.SetCanDraw(false);
-  state.SetVisible(false);
-  EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
-  state.SetCanDraw(true);
-  state.SetVisible(true);
-  EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
-}
-
-TEST(SchedulerStateMachineTest,
-     TestTriggerDeadlineImmediatelyAfterAbortedCommit) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // This test mirrors what happens during the first frame of a scroll gesture.
-  // First we get the input event and a BeginFrame.
-  state.OnBeginImplFrame();
-
-  // As a response the compositor requests a redraw and a commit to tell the
-  // main thread about the new scroll offset.
-  state.SetNeedsRedraw(true);
-  state.SetNeedsCommit();
-
-  // We should start the commit normally.
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Since only the scroll offset changed, the main thread will abort the
-  // commit.
-  state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES);
-
-  // Since the commit was aborted, we should draw right away instead of waiting
-  // for the deadline.
-  EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-}
-
-void FinishPreviousCommitAndDrawWithoutExitingDeadline(
-    StateMachine* state_ptr) {
-  // Gross, but allows us to use macros below.
-  StateMachine& state = *state_ptr;
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.NotifyReadyToActivate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-}
-
-TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // This test ensures that impl-draws are prioritized over main thread updates
-  // in prefer impl latency mode.
-  state.SetNeedsRedraw(true);
-  state.SetNeedsCommit();
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify the deadline is not triggered early until we enter
-  // prefer impl latency mode.
-  EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-  state.SetImplLatencyTakesPriority(true);
-  EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-
-  // Trigger the deadline.
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-  state.DidSwapBuffers();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.DidSwapBuffersComplete();
-
-  // Request a new commit and finish the previous one.
-  state.SetNeedsCommit();
-  FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.DidSwapBuffersComplete();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Finish the previous commit and draw it.
-  FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  // Verify we do not send another BeginMainFrame if was are swap throttled
-  // and did not just swap.
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-}
-
-TEST(SchedulerStateMachineTest,
-     TestTriggerDeadlineImmediatelyOnLostOutputSurface) {
-  SchedulerSettings default_scheduler_settings;
-  StateMachine state(default_scheduler_settings);
-  SET_UP_STATE(state)
-
-  state.SetNeedsCommit();
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-
-  state.DidLoseOutputSurface();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  // The deadline should be triggered immediately when output surface is lost.
-  EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
-}
-
-TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // Test requesting an animation that, when run, causes us to draw.
-  state.SetNeedsAnimate();
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-
-  state.OnBeginImplFrameDeadlinePending();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-}
-
-TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // Check that animations are updated before we start a commit.
-  state.SetNeedsAnimate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-
-  state.OnBeginImplFrameDeadlinePending();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-}
-
-TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // Check that animations are updated before we start a commit.
-  state.SetNeedsAnimate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  state.SetNeedsCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-
-  state.NotifyBeginMainFrameStarted();
-  state.NotifyReadyToCommit();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
-
-  state.OnBeginImplFrameDeadlinePending();
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-}
-
-TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
-  SchedulerSettings settings;
-  settings.impl_side_painting = true;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  // Test requesting an animation after we have already animated during this
-  // frame.
-  state.SetNeedsRedraw(true);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
-
-  state.SetNeedsAnimate();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
-}
-
-TEST(SchedulerStateMachineTest, TestForwardBeginFramesToChildren) {
-  SchedulerSettings settings;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  EXPECT_FALSE(state.BeginFrameNeeded());
-  state.SetChildrenNeedBeginFrames(true);
-  EXPECT_TRUE(state.BeginFrameNeeded());
-}
-
-TEST(SchedulerStateMachineTest, TestDeferCommit) {
-  SchedulerSettings settings;
-  StateMachine state(settings);
-  SET_UP_STATE(state)
-
-  state.SetDeferCommits(true);
-
-  state.SetNeedsCommit();
-  EXPECT_TRUE(state.BeginFrameNeeded());
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.OnBeginImplFrameDeadline();
-  EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
-
-  state.SetDeferCommits(false);
-  state.OnBeginImplFrame();
-  EXPECT_ACTION_UPDATE_STATE(
-      SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
-}
-
-TEST(SchedulerStateMachineTest, EarlyOutCommitWantsProactiveBeginFrame) {
-  SchedulerSettings settings;
-  StateMachine state(settings);
-  SET_UP_STATE(state);
-
-  EXPECT_FALSE(state.ProactiveBeginFrameWanted());
-  bool commit_has_no_updates = true;
-  state.UpdateStateOnCommit(commit_has_no_updates);
-  EXPECT_TRUE(state.ProactiveBeginFrameWanted());
-  state.OnBeginImplFrame();
-  EXPECT_FALSE(state.ProactiveBeginFrameWanted());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
deleted file mode 100644
index b59359c..0000000
--- a/cc/scheduler/scheduler_unittest.cc
+++ /dev/null
@@ -1,2276 +0,0 @@
-// Copyright 2011 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.
-
-#include "cc/scheduler/scheduler.h"
-
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/time/time.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "cc/test/scheduler_test_common.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#define EXPECT_ACTION(action, client, action_index, expected_num_actions)  \
-  do {                                                                     \
-    EXPECT_EQ(expected_num_actions, client->num_actions_());               \
-    if (action_index >= 0) {                                               \
-      ASSERT_LT(action_index, client->num_actions_()) << scheduler_.get(); \
-      EXPECT_STREQ(action, client->Action(action_index));                  \
-    }                                                                      \
-    for (int i = expected_num_actions; i < client->num_actions_(); ++i)    \
-      ADD_FAILURE() << "Unexpected action: " << client->Action(i)          \
-                    << " with state:\n" << client->StateForAction(i);      \
-  } while (false)
-
-#define EXPECT_NO_ACTION(client) EXPECT_ACTION("", client, -1, 0)
-
-#define EXPECT_SINGLE_ACTION(action, client) \
-  EXPECT_ACTION(action, client, 0, 1)
-
-#define EXPECT_SCOPED(statements) \
-  {                               \
-    SCOPED_TRACE("");             \
-    statements;                   \
-  }
-
-namespace cc {
-namespace {
-
-class FakeSchedulerClient : public SchedulerClient {
- public:
-  FakeSchedulerClient()
-      : automatic_swap_ack_(true),
-        begin_frame_is_sent_to_children_(false),
-        scheduler_(nullptr) {
-    Reset();
-  }
-
-  void Reset() {
-    actions_.clear();
-    states_.clear();
-    draw_will_happen_ = true;
-    swap_will_happen_if_draw_happens_ = true;
-    num_draws_ = 0;
-    log_anticipated_draw_time_change_ = false;
-    begin_frame_is_sent_to_children_ = false;
-  }
-
-  void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; }
-
-  // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
-  // for tests that do.
-  void set_log_anticipated_draw_time_change(bool log) {
-    log_anticipated_draw_time_change_ = log;
-  }
-  bool needs_begin_frames() {
-    return scheduler_->frame_source().NeedsBeginFrames();
-  }
-  int num_draws() const { return num_draws_; }
-  int num_actions_() const { return static_cast<int>(actions_.size()); }
-  const char* Action(int i) const { return actions_[i]; }
-  std::string StateForAction(int i) const { return states_[i]->ToString(); }
-  base::TimeTicks posted_begin_impl_frame_deadline() const {
-    return posted_begin_impl_frame_deadline_;
-  }
-
-  int ActionIndex(const char* action) const {
-    for (size_t i = 0; i < actions_.size(); i++)
-      if (!strcmp(actions_[i], action))
-        return i;
-    return -1;
-  }
-
-  bool HasAction(const char* action) const {
-    return ActionIndex(action) >= 0;
-  }
-
-  void SetDrawWillHappen(bool draw_will_happen) {
-    draw_will_happen_ = draw_will_happen;
-  }
-  void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) {
-    swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens;
-  }
-  void SetAutomaticSwapAck(bool automatic_swap_ack) {
-    automatic_swap_ack_ = automatic_swap_ack;
-  }
-  // SchedulerClient implementation.
-  void WillBeginImplFrame(const BeginFrameArgs& args) override {
-    PushAction("WillBeginImplFrame");
-  }
-  void ScheduledActionSendBeginMainFrame() override {
-    PushAction("ScheduledActionSendBeginMainFrame");
-  }
-  void ScheduledActionAnimate() override {
-    PushAction("ScheduledActionAnimate");
-  }
-  DrawResult ScheduledActionDrawAndSwapIfPossible() override {
-    PushAction("ScheduledActionDrawAndSwapIfPossible");
-    num_draws_++;
-    DrawResult result =
-        draw_will_happen_ ? DRAW_SUCCESS : DRAW_ABORTED_CHECKERBOARD_ANIMATIONS;
-    bool swap_will_happen =
-        draw_will_happen_ && swap_will_happen_if_draw_happens_;
-    if (swap_will_happen) {
-      scheduler_->DidSwapBuffers();
-
-      if (automatic_swap_ack_)
-        scheduler_->DidSwapBuffersComplete();
-    }
-    return result;
-  }
-  DrawResult ScheduledActionDrawAndSwapForced() override {
-    PushAction("ScheduledActionDrawAndSwapForced");
-    return DRAW_SUCCESS;
-  }
-  void ScheduledActionCommit() override { PushAction("ScheduledActionCommit"); }
-  void ScheduledActionActivateSyncTree() override {
-    PushAction("ScheduledActionActivateSyncTree");
-  }
-  void ScheduledActionBeginOutputSurfaceCreation() override {
-    PushAction("ScheduledActionBeginOutputSurfaceCreation");
-  }
-  void ScheduledActionPrepareTiles() override {
-    PushAction("ScheduledActionPrepareTiles");
-  }
-  void DidAnticipatedDrawTimeChange(base::TimeTicks) override {
-    if (log_anticipated_draw_time_change_)
-      PushAction("DidAnticipatedDrawTimeChange");
-  }
-  base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); }
-  base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
-    return base::TimeDelta();
-  }
-  base::TimeDelta CommitToActivateDurationEstimate() override {
-    return base::TimeDelta();
-  }
-
-  void DidBeginImplFrameDeadline() override {}
-
-  void SendBeginFramesToChildren(const BeginFrameArgs& args) override {
-    begin_frame_is_sent_to_children_ = true;
-  }
-
-  void SendBeginMainFrameNotExpectedSoon() override {
-    PushAction("SendBeginMainFrameNotExpectedSoon");
-  }
-
-  base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) {
-    return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback,
-                      base::Unretained(this),
-                      state);
-  }
-
-  bool begin_frame_is_sent_to_children() const {
-    return begin_frame_is_sent_to_children_;
-  }
-
-  void PushAction(const char* description) {
-    actions_.push_back(description);
-    states_.push_back(scheduler_->AsValue());
-  }
-
- protected:
-  bool ImplFrameDeadlinePendingCallback(bool state) {
-    return scheduler_->BeginImplFrameDeadlinePending() == state;
-  }
-
-  bool draw_will_happen_;
-  bool swap_will_happen_if_draw_happens_;
-  bool automatic_swap_ack_;
-  int num_draws_;
-  bool log_anticipated_draw_time_change_;
-  bool begin_frame_is_sent_to_children_;
-  base::TimeTicks posted_begin_impl_frame_deadline_;
-  std::vector<const char*> actions_;
-  std::vector<scoped_refptr<base::trace_event::ConvertableToTraceFormat>>
-      states_;
-  TestScheduler* scheduler_;
-};
-
-class FakeExternalBeginFrameSource : public BeginFrameSourceMixIn {
- public:
-  explicit FakeExternalBeginFrameSource(FakeSchedulerClient* client)
-      : client_(client) {}
-  ~FakeExternalBeginFrameSource() override {}
-
-  void OnNeedsBeginFramesChange(bool needs_begin_frames) override {
-    if (needs_begin_frames) {
-      client_->PushAction("SetNeedsBeginFrames(true)");
-    } else {
-      client_->PushAction("SetNeedsBeginFrames(false)");
-    }
-  }
-
-  void TestOnBeginFrame(const BeginFrameArgs& args) {
-    return CallOnBeginFrame(args);
-  }
-
- private:
-  FakeSchedulerClient* client_;
-};
-
-class SchedulerTest : public testing::Test {
- public:
-  SchedulerTest()
-      : now_src_(TestNowSource::Create()),
-        task_runner_(new OrderedSimpleTaskRunner(now_src_, true)),
-        fake_external_begin_frame_source_(nullptr) {
-    // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
-    now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
-    // Fail if we need to run 100 tasks in a row.
-    task_runner_->SetRunTaskLimit(100);
-  }
-
-  ~SchedulerTest() override {}
-
- protected:
-  TestScheduler* CreateScheduler() {
-    scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source;
-    if (scheduler_settings_.use_external_begin_frame_source) {
-      fake_external_begin_frame_source.reset(
-          new FakeExternalBeginFrameSource(client_.get()));
-      fake_external_begin_frame_source_ =
-          fake_external_begin_frame_source.get();
-    }
-    scheduler_ = TestScheduler::Create(now_src_, client_.get(),
-                                       scheduler_settings_, 0, task_runner_,
-                                       fake_external_begin_frame_source.Pass());
-    DCHECK(scheduler_);
-    client_->set_scheduler(scheduler_.get());
-    return scheduler_.get();
-  }
-
-  void CreateSchedulerAndInitSurface() {
-    CreateScheduler();
-    EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit());
-  }
-
-  void SetUpScheduler(bool initSurface) {
-    SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface);
-  }
-
-  void SetUpScheduler(scoped_ptr<FakeSchedulerClient> client,
-                      bool initSurface) {
-    client_ = client.Pass();
-    if (initSurface)
-      CreateSchedulerAndInitSurface();
-    else
-      CreateScheduler();
-  }
-
-  OrderedSimpleTaskRunner& task_runner() { return *task_runner_; }
-  TestNowSource* now_src() { return now_src_.get(); }
-
-  // As this function contains EXPECT macros, to allow debugging it should be
-  // called inside EXPECT_SCOPED like so;
-  //   EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler));
-  void InitializeOutputSurfaceAndFirstCommit() {
-    TRACE_EVENT0("cc",
-                 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
-    DCHECK(scheduler_);
-
-    // Check the client doesn't have any actions queued when calling this
-    // function.
-    EXPECT_NO_ACTION(client_);
-    EXPECT_FALSE(client_->needs_begin_frames());
-
-    // Start the initial output surface creation.
-    EXPECT_FALSE(scheduler_->CanStart());
-    scheduler_->SetCanStart();
-    scheduler_->SetVisible(true);
-    scheduler_->SetCanDraw(true);
-    EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
-
-    client_->Reset();
-
-    // We don't see anything happening until the first impl frame.
-    scheduler_->DidCreateAndInitializeOutputSurface();
-    scheduler_->SetNeedsCommit();
-    EXPECT_TRUE(client_->needs_begin_frames());
-    EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-    client_->Reset();
-
-    {
-      SCOPED_TRACE("Do first frame to commit after initialize.");
-      AdvanceFrame();
-
-      scheduler_->NotifyBeginMainFrameStarted();
-      scheduler_->NotifyReadyToCommitThenActivateIfNeeded();
-
-      // Run the posted deadline task.
-      EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-      task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-      EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-      EXPECT_FALSE(scheduler_->CommitPending());
-    }
-
-    client_->Reset();
-
-    {
-      SCOPED_TRACE(
-          "Run second frame so Scheduler calls SetNeedsBeginFrame(false).");
-      AdvanceFrame();
-
-      // Run the posted deadline task.
-      EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-      task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-      EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-    }
-
-    EXPECT_FALSE(client_->needs_begin_frames());
-    client_->Reset();
-  }
-
-  // As this function contains EXPECT macros, to allow debugging it should be
-  // called inside EXPECT_SCOPED like so;
-  //   EXPECT_SCOPED(client.AdvanceFrame());
-  void AdvanceFrame() {
-    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
-                 "FakeSchedulerClient::AdvanceFrame");
-    // Consume any previous deadline first, if no deadline is currently
-    // pending, ImplFrameDeadlinePending will return false straight away and we
-    // will run no tasks.
-    task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-    EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-    // Send the next BeginFrame message if using an external source, otherwise
-    // it will be already in the task queue.
-    if (scheduler_->settings().use_external_begin_frame_source &&
-        scheduler_->FrameProductionThrottled()) {
-      SendNextBeginFrame();
-      EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-    }
-
-    // Then run tasks until new deadline is scheduled.
-    EXPECT_TRUE(
-        task_runner_->RunTasksWhile(client_->ImplFrameDeadlinePending(false)));
-    EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  }
-
-  void SendNextBeginFrame() {
-    DCHECK(scheduler_->settings().use_external_begin_frame_source);
-    // Creep the time forward so that any BeginFrameArgs is not equal to the
-    // last one otherwise we violate the BeginFrameSource contract.
-    now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval());
-    fake_external_begin_frame_source_->TestOnBeginFrame(
-        CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()));
-  }
-
-  FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
-    return fake_external_begin_frame_source_;
-  }
-
-  void MainFrameInHighLatencyMode(
-      int64 begin_main_frame_to_commit_estimate_in_ms,
-      int64 commit_to_activate_estimate_in_ms,
-      bool impl_latency_takes_priority,
-      bool should_send_begin_main_frame);
-  void BeginFramesNotFromClient(bool use_external_begin_frame_source,
-                                bool throttle_frame_production);
-  void BeginFramesNotFromClient_SwapThrottled(
-      bool use_external_begin_frame_source,
-      bool throttle_frame_production);
-  void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
-      bool impl_side_painting);
-  void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting);
-
-  scoped_refptr<TestNowSource> now_src_;
-  scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
-  FakeExternalBeginFrameSource* fake_external_begin_frame_source_;
-  SchedulerSettings scheduler_settings_;
-  scoped_ptr<FakeSchedulerClient> client_;
-  scoped_ptr<TestScheduler> scheduler_;
-};
-
-TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(false);
-  scheduler_->SetCanStart();
-  scheduler_->SetVisible(true);
-  scheduler_->SetCanDraw(true);
-
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
-  client_->Reset();
-  scheduler_->DidCreateAndInitializeOutputSurface();
-  EXPECT_NO_ACTION(client_);
-}
-
-TEST_F(SchedulerTest, SendBeginFramesToChildren) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  EXPECT_FALSE(client_->begin_frame_is_sent_to_children());
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  scheduler_->SetChildrenNeedBeginFrames(true);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(client_->needs_begin_frames());
-}
-
-TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  EXPECT_FALSE(client_->needs_begin_frames());
-  scheduler_->SetChildrenNeedBeginFrames(true);
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_TRUE(client_->begin_frame_is_sent_to_children());
-}
-
-TEST_F(SchedulerTest, RequestCommit) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // If we don't swap on the deadline, we wait for the next BeginFrame.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // NotifyReadyToCommit should trigger the commit.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // BeginImplFrame should prepare the draw.
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // BeginImplFrame deadline should draw.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
-  // to avoid excessive toggles.
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  client_->Reset();
-}
-
-TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetDeferCommits(true);
-
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  AdvanceFrame();
-  // BeginMainFrame is not sent during the defer commit is on.
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  // There is no posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  client_->Reset();
-  scheduler_->SetDeferCommits(false);
-  EXPECT_NO_ACTION(client_);
-
-  // Start new BeginMainFrame after defer commit is off.
-  client_->Reset();
-  AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-}
-
-TEST_F(SchedulerTest, DeferCommitWithRedraw) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetDeferCommits(true);
-
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_NO_ACTION(client_);
-
-  client_->Reset();
-  AdvanceFrame();
-  // BeginMainFrame is not sent during the defer commit is on.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  client_->Reset();
-  AdvanceFrame();
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-}
-
-TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Now SetNeedsCommit again. Calling here means we need a second commit.
-  scheduler_->SetNeedsCommit();
-  EXPECT_EQ(client_->num_actions_(), 0);
-  client_->Reset();
-
-  // Finish the first commit.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Because we just swapped, the Scheduler should also request the next
-  // BeginImplFrame from the OutputSurface.
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-  // Since another commit is needed, the next BeginImplFrame should initiate
-  // the second commit.
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // Finishing the commit before the deadline should post a new deadline task
-  // to trigger the deadline early.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // On the next BeginImplFrame, verify we go back to a quiescent state and
-  // no longer request BeginImplFrames.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_FALSE(client_->needs_begin_frames());
-  client_->Reset();
-}
-
-class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
- public:
-  SchedulerClientThatsetNeedsDrawInsideDraw()
-      : FakeSchedulerClient(), request_redraws_(false) {}
-
-  void ScheduledActionSendBeginMainFrame() override {}
-
-  void SetRequestRedrawsInsideDraw(bool enable) { request_redraws_ = enable; }
-
-  DrawResult ScheduledActionDrawAndSwapIfPossible() override {
-    // Only SetNeedsRedraw the first time this is called
-    if (request_redraws_) {
-      scheduler_->SetNeedsRedraw();
-    }
-    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
-  }
-
-  DrawResult ScheduledActionDrawAndSwapForced() override {
-    NOTREACHED();
-    return DRAW_SUCCESS;
-  }
-
-  void ScheduledActionCommit() override {}
-  void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
-
- private:
-  bool request_redraws_;
-};
-
-// Tests for two different situations:
-// 1. the scheduler dropping SetNeedsRedraw requests that happen inside
-//    a ScheduledActionDrawAndSwap
-// 2. the scheduler drawing twice inside a single tick
-TEST_F(SchedulerTest, RequestRedrawInsideDraw) {
-  SchedulerClientThatsetNeedsDrawInsideDraw* client =
-      new SchedulerClientThatsetNeedsDrawInsideDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-  client->SetRequestRedrawsInsideDraw(true);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  client->SetRequestRedrawsInsideDraw(false);
-
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client_->num_draws());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
-  // swap.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(client->needs_begin_frames());
-}
-
-// Test that requesting redraw inside a failed draw doesn't lose the request.
-TEST_F(SchedulerTest, RequestRedrawInsideFailedDraw) {
-  SchedulerClientThatsetNeedsDrawInsideDraw* client =
-      new SchedulerClientThatsetNeedsDrawInsideDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  client->SetRequestRedrawsInsideDraw(true);
-  client->SetDrawWillHappen(false);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-
-  // Fail the draw.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-
-  // We have a commit pending and the draw failed, and we didn't lose the redraw
-  // request.
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  client->SetRequestRedrawsInsideDraw(false);
-
-  // Fail the draw again.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // Draw successfully.
-  client->SetDrawWillHappen(true);
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(3, client->num_draws());
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-}
-
-class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
- public:
-  SchedulerClientThatSetNeedsCommitInsideDraw()
-      : set_needs_commit_on_next_draw_(false) {}
-
-  void ScheduledActionSendBeginMainFrame() override {}
-  DrawResult ScheduledActionDrawAndSwapIfPossible() override {
-    // Only SetNeedsCommit the first time this is called
-    if (set_needs_commit_on_next_draw_) {
-      scheduler_->SetNeedsCommit();
-      set_needs_commit_on_next_draw_ = false;
-    }
-    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
-  }
-
-  DrawResult ScheduledActionDrawAndSwapForced() override {
-    NOTREACHED();
-    return DRAW_SUCCESS;
-  }
-
-  void ScheduledActionCommit() override {}
-  void DidAnticipatedDrawTimeChange(base::TimeTicks) override {}
-
-  void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
-
- private:
-  bool set_needs_commit_on_next_draw_;
-};
-
-// Tests for the scheduler infinite-looping on SetNeedsCommit requests that
-// happen inside a ScheduledActionDrawAndSwap
-TEST_F(SchedulerTest, RequestCommitInsideDraw) {
-  SchedulerClientThatSetNeedsCommitInsideDraw* client =
-      new SchedulerClientThatSetNeedsCommitInsideDraw;
-
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  EXPECT_FALSE(client->needs_begin_frames());
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_EQ(0, client->num_draws());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  client->SetNeedsCommitOnNextDraw();
-  EXPECT_SCOPED(AdvanceFrame());
-  client->SetNeedsCommitOnNextDraw();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->CommitPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // We stop requesting BeginImplFrames after a BeginImplFrame where we don't
-  // swap.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->CommitPending());
-  EXPECT_FALSE(client->needs_begin_frames());
-}
-
-// Tests that when a draw fails then the pending commit should not be dropped.
-TEST_F(SchedulerTest, RequestCommitInsideFailedDraw) {
-  SchedulerClientThatsetNeedsDrawInsideDraw* client =
-      new SchedulerClientThatsetNeedsDrawInsideDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  client->SetDrawWillHappen(false);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-
-  // Fail the draw.
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-
-  // We have a commit pending and the draw failed, and we didn't lose the commit
-  // request.
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // Fail the draw again.
-  EXPECT_SCOPED(AdvanceFrame());
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // Draw successfully.
-  client->SetDrawWillHappen(true);
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(3, client->num_draws());
-  EXPECT_TRUE(scheduler_->CommitPending());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-}
-
-TEST_F(SchedulerTest, NoSwapWhenDrawFails) {
-  SchedulerClientThatSetNeedsCommitInsideDraw* client =
-      new SchedulerClientThatSetNeedsCommitInsideDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-
-  // Draw successfully, this starts a new frame.
-  client->SetNeedsCommitOnNextDraw();
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-
-  // Fail to draw, this should not start a frame.
-  client->SetDrawWillHappen(false);
-  client->SetNeedsCommitOnNextDraw();
-  EXPECT_SCOPED(AdvanceFrame());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(2, client->num_draws());
-}
-
-class SchedulerClientNeedsPrepareTilesInDraw : public FakeSchedulerClient {
- public:
-  DrawResult ScheduledActionDrawAndSwapIfPossible() override {
-    scheduler_->SetNeedsPrepareTiles();
-    return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
-  }
-};
-
-// Test prepare tiles is independant of draws.
-TEST_F(SchedulerTest, PrepareTiles) {
-  SchedulerClientNeedsPrepareTilesInDraw* client =
-      new SchedulerClientNeedsPrepareTilesInDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  // Request both draw and prepare tiles. PrepareTiles shouldn't
-  // be trigged until BeginImplFrame.
-  client->Reset();
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-  EXPECT_FALSE(client->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-
-  // We have no immediate actions to perform, so the BeginImplFrame should post
-  // the deadline task.
-  client->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // On the deadline, he actions should have occured in the right order.
-  client->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-  EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
-            client->ActionIndex("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Request a draw. We don't need a PrepareTiles yet.
-  client->Reset();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_TRUE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_EQ(0, client->num_draws());
-
-  // We have no immediate actions to perform, so the BeginImplFrame should post
-  // the deadline task.
-  client->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Draw. The draw will trigger SetNeedsPrepareTiles, and
-  // then the PrepareTiles action will be triggered after the Draw.
-  // Afterwards, neither a draw nor PrepareTiles are pending.
-  client->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client->num_draws());
-  EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
-            client->ActionIndex("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // We need a BeginImplFrame where we don't swap to go idle.
-  client->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_EQ(0, client->num_draws());
-
-  // Now trigger a PrepareTiles outside of a draw. We will then need
-  // a begin-frame for the PrepareTiles, but we don't need a draw.
-  client->Reset();
-  EXPECT_FALSE(client->needs_begin_frames());
-  scheduler_->SetNeedsPrepareTiles();
-  EXPECT_TRUE(client->needs_begin_frames());
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->RedrawPending());
-
-  // BeginImplFrame. There will be no draw, only PrepareTiles.
-  client->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(0, client->num_draws());
-  EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-}
-
-// Test that PrepareTiles only happens once per frame.  If an external caller
-// initiates it, then the state machine should not PrepareTiles on that frame.
-TEST_F(SchedulerTest, PrepareTilesOncePerFrame) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // If DidPrepareTiles during a frame, then PrepareTiles should not occur
-  // again.
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-  scheduler_->DidPrepareTiles();  // An explicit PrepareTiles.
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client_->num_draws());
-  EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Next frame without DidPrepareTiles should PrepareTiles with draw.
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client_->num_draws());
-  EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
-            client_->ActionIndex("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  scheduler_->DidPrepareTiles();  // Corresponds to ScheduledActionPrepareTiles
-
-  // If we get another DidPrepareTiles within the same frame, we should
-  // not PrepareTiles on the next frame.
-  scheduler_->DidPrepareTiles();  // An explicit PrepareTiles.
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client_->num_draws());
-  EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // If we get another DidPrepareTiles, we should not PrepareTiles on the next
-  // frame. This verifies we don't alternate calling PrepareTiles once and
-  // twice.
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-  scheduler_->DidPrepareTiles();  // An explicit PrepareTiles.
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  EXPECT_TRUE(scheduler_->PrepareTilesPending());
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client_->num_draws());
-  EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Next frame without DidPrepareTiles should PrepareTiles with draw.
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(1, client_->num_draws());
-  EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible"));
-  EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles"));
-  EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"),
-            client_->ActionIndex("ScheduledActionPrepareTiles"));
-  EXPECT_FALSE(scheduler_->RedrawPending());
-  EXPECT_FALSE(scheduler_->PrepareTilesPending());
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  scheduler_->DidPrepareTiles();  // Corresponds to ScheduledActionPrepareTiles
-}
-
-TEST_F(SchedulerTest, TriggerBeginFrameDeadlineEarly) {
-  SchedulerClientNeedsPrepareTilesInDraw* client =
-      new SchedulerClientNeedsPrepareTilesInDraw;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_SCOPED(AdvanceFrame());
-
-  // The deadline should be zero since there is no work other than drawing
-  // pending.
-  EXPECT_EQ(base::TimeTicks(), client->posted_begin_impl_frame_deadline());
-}
-
-class SchedulerClientWithFixedEstimates : public FakeSchedulerClient {
- public:
-  SchedulerClientWithFixedEstimates(
-      base::TimeDelta draw_duration,
-      base::TimeDelta begin_main_frame_to_commit_duration,
-      base::TimeDelta commit_to_activate_duration)
-      : draw_duration_(draw_duration),
-        begin_main_frame_to_commit_duration_(
-            begin_main_frame_to_commit_duration),
-        commit_to_activate_duration_(commit_to_activate_duration) {}
-
-  base::TimeDelta DrawDurationEstimate() override { return draw_duration_; }
-  base::TimeDelta BeginMainFrameToCommitDurationEstimate() override {
-    return begin_main_frame_to_commit_duration_;
-  }
-  base::TimeDelta CommitToActivateDurationEstimate() override {
-    return commit_to_activate_duration_;
-  }
-
- private:
-    base::TimeDelta draw_duration_;
-    base::TimeDelta begin_main_frame_to_commit_duration_;
-    base::TimeDelta commit_to_activate_duration_;
-};
-
-void SchedulerTest::MainFrameInHighLatencyMode(
-    int64 begin_main_frame_to_commit_estimate_in_ms,
-    int64 commit_to_activate_estimate_in_ms,
-    bool impl_latency_takes_priority,
-    bool should_send_begin_main_frame) {
-  // Set up client with specified estimates (draw duration is set to 1).
-  SchedulerClientWithFixedEstimates* client =
-      new SchedulerClientWithFixedEstimates(
-          base::TimeDelta::FromMilliseconds(1),
-          base::TimeDelta::FromMilliseconds(
-              begin_main_frame_to_commit_estimate_in_ms),
-          base::TimeDelta::FromMilliseconds(commit_to_activate_estimate_in_ms));
-
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  scheduler_->SetImplLatencyTakesPriority(impl_latency_takes_priority);
-
-  // Impl thread hits deadline before commit finishes.
-  scheduler_->SetNeedsCommit();
-  EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_FALSE(scheduler_->MainThreadIsInHighLatencyMode());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
-  EXPECT_TRUE(client->HasAction("ScheduledActionSendBeginMainFrame"));
-
-  client->Reset();
-  scheduler_->SetNeedsCommit();
-  EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_TRUE(scheduler_->MainThreadIsInHighLatencyMode());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_EQ(scheduler_->MainThreadIsInHighLatencyMode(),
-            should_send_begin_main_frame);
-  EXPECT_EQ(client->HasAction("ScheduledActionSendBeginMainFrame"),
-            should_send_begin_main_frame);
-}
-
-TEST_F(SchedulerTest,
-       SkipMainFrameIfHighLatencyAndCanCommitAndActivateBeforeDeadline) {
-  // Set up client so that estimates indicate that we can commit and activate
-  // before the deadline (~8ms by default).
-  MainFrameInHighLatencyMode(1, 1, false, false);
-}
-
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanCommitTooLong) {
-  // Set up client so that estimates indicate that the commit cannot finish
-  // before the deadline (~8ms by default).
-  MainFrameInHighLatencyMode(10, 1, false, true);
-}
-
-TEST_F(SchedulerTest, NotSkipMainFrameIfHighLatencyAndCanActivateTooLong) {
-  // Set up client so that estimates indicate that the activate cannot finish
-  // before the deadline (~8ms by default).
-  MainFrameInHighLatencyMode(1, 10, false, true);
-}
-
-TEST_F(SchedulerTest, NotSkipMainFrameInPreferImplLatencyMode) {
-  // Set up client so that estimates indicate that we can commit and activate
-  // before the deadline (~8ms by default), but also enable impl latency takes
-  // priority mode.
-  MainFrameInHighLatencyMode(1, 1, true, true);
-}
-
-TEST_F(SchedulerTest, PollForCommitCompletion) {
-  // Since we are simulating a long commit, set up a client with draw duration
-  // estimates that prevent skipping main frames to get to low latency mode.
-  SchedulerClientWithFixedEstimates* client =
-      new SchedulerClientWithFixedEstimates(
-          base::TimeDelta::FromMilliseconds(1),
-          base::TimeDelta::FromMilliseconds(32),
-          base::TimeDelta::FromMilliseconds(32));
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(make_scoped_ptr(client).Pass(), true);
-
-  client->set_log_anticipated_draw_time_change(true);
-
-  BeginFrameArgs frame_args =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
-  frame_args.interval = base::TimeDelta::FromMilliseconds(1000);
-
-  // At this point, we've drawn a frame. Start another commit, but hold off on
-  // the NotifyReadyToCommit for now.
-  EXPECT_FALSE(scheduler_->CommitPending());
-  scheduler_->SetNeedsCommit();
-  fake_external_begin_frame_source()->TestOnBeginFrame(frame_args);
-  EXPECT_TRUE(scheduler_->CommitPending());
-
-  // Draw and swap the frame, but don't ack the swap to simulate the Browser
-  // blocking on the renderer.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  scheduler_->DidSwapBuffers();
-
-  // Spin the event loop a few times and make sure we get more
-  // DidAnticipateDrawTimeChange calls every time.
-  int actions_so_far = client->num_actions_();
-
-  // Does three iterations to make sure that the timer is properly repeating.
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
-              task_runner().DelayToNextTaskTime().InMicroseconds())
-        << scheduler_->AsValue()->ToString();
-    task_runner().RunPendingTasks();
-    EXPECT_GT(client->num_actions_(), actions_so_far);
-    EXPECT_STREQ(client->Action(client->num_actions_() - 1),
-                 "DidAnticipatedDrawTimeChange");
-    actions_so_far = client->num_actions_();
-  }
-
-  // Do the same thing after BeginMainFrame starts but still before activation.
-  scheduler_->NotifyBeginMainFrameStarted();
-  for (int i = 0; i < 3; ++i) {
-    EXPECT_EQ((frame_args.interval * 2).InMicroseconds(),
-              task_runner().DelayToNextTaskTime().InMicroseconds())
-        << scheduler_->AsValue()->ToString();
-    task_runner().RunPendingTasks();
-    EXPECT_GT(client->num_actions_(), actions_so_far);
-    EXPECT_STREQ(client->Action(client->num_actions_() - 1),
-                 "DidAnticipatedDrawTimeChange");
-    actions_so_far = client->num_actions_();
-  }
-}
-
-TEST_F(SchedulerTest, BeginRetroFrame) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  // Create a BeginFrame with a long deadline to avoid race conditions.
-  // This is the first BeginFrame, which will be handled immediately.
-  BeginFrameArgs args =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
-  args.deadline += base::TimeDelta::FromHours(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Queue BeginFrames while we are still handling the previous BeginFrame.
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-
-  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // NotifyReadyToCommit should trigger the commit.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // BeginImplFrame should prepare the draw.
-  task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // BeginImplFrame deadline should draw.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
-  // to avoid excessive toggles.
-  task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  client_->Reset();
-}
-
-TEST_F(SchedulerTest, BeginRetroFrame_SwapThrottled) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
-
-  // To test swap ack throttling, this test disables automatic swap acks.
-  scheduler_->SetMaxSwapsPending(1);
-  client_->SetAutomaticSwapAck(false);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  client_->Reset();
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Queue BeginFrame while we are still handling the previous BeginFrame.
-  SendNextBeginFrame();
-  EXPECT_NO_ACTION(client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // NotifyReadyToCommit should trigger the pending commit and draw.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Swapping will put us into a swap throttled state.
-  // Run posted deadline.
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // While swap throttled, BeginRetroFrames should trigger BeginImplFrames
-  // but not a BeginMainFrame or draw.
-  scheduler_->SetNeedsCommit();
-  scheduler_->SetNeedsRedraw();
-  // Run posted BeginRetroFrame.
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Let time pass sufficiently beyond the regular deadline but not beyond the
-  // late deadline.
-  now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
-                        base::TimeDelta::FromMicroseconds(1));
-  task_runner().RunUntilTime(now_src()->Now());
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Take us out of a swap throttled state.
-  scheduler_->DidSwapBuffersComplete();
-  EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  // Verify that the deadline was rescheduled.
-  task_runner().RunUntilTime(now_src()->Now());
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-}
-
-TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetNeedsCommit();
-  EXPECT_TRUE(client_->needs_begin_frames());
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-
-  client_->Reset();
-  SendNextBeginFrame();
-  // This BeginFrame is queued up as a retro frame.
-  EXPECT_NO_ACTION(client_);
-  // The previous deadline is still pending.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  // This commit should schedule the (previous) deadline to trigger immediately.
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-
-  client_->Reset();
-  // The deadline task should trigger causing a draw.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-
-  // Keep animating.
-  client_->Reset();
-  scheduler_->SetNeedsAnimate();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_NO_ACTION(client_);
-
-  // Let's advance sufficiently past the next frame's deadline.
-  now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
-                        BeginFrameArgs::DefaultEstimatedParentDrawTime() +
-                        base::TimeDelta::FromMicroseconds(1));
-
-  // The retro frame hasn't expired yet.
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // This is an immediate deadline case.
-  client_->Reset();
-  task_runner().RunPendingTasks();
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
-}
-
-TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetNeedsCommit();
-  EXPECT_TRUE(client_->needs_begin_frames());
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-
-  client_->Reset();
-  SendNextBeginFrame();
-  // This BeginFrame is queued up as a retro frame.
-  EXPECT_NO_ACTION(client_);
-  // The previous deadline is still pending.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  // This commit should schedule the (previous) deadline to trigger immediately.
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-
-  client_->Reset();
-  // The deadline task should trigger causing a draw.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-
-  // Keep animating.
-  client_->Reset();
-  scheduler_->SetNeedsAnimate();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_NO_ACTION(client_);
-
-  // Let's advance sufficiently past the next frame's deadline.
-  now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() +
-                        base::TimeDelta::FromMicroseconds(1));
-
-  // The retro frame should've expired.
-  EXPECT_NO_ACTION(client_);
-}
-
-void SchedulerTest::BeginFramesNotFromClient(
-    bool use_external_begin_frame_source,
-    bool throttle_frame_production) {
-  scheduler_settings_.use_external_begin_frame_source =
-      use_external_begin_frame_source;
-  scheduler_settings_.throttle_frame_production = throttle_frame_production;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame
-  // without calling SetNeedsBeginFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_NO_ACTION(client_);
-  client_->Reset();
-
-  // When the client-driven BeginFrame are disabled, the scheduler posts it's
-  // own BeginFrame tasks.
-  task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // If we don't swap on the deadline, we wait for the next BeginFrame.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // NotifyReadyToCommit should trigger the commit.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  client_->Reset();
-
-  // BeginImplFrame should prepare the draw.
-  task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // BeginImplFrame deadline should draw.
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
-  // to avoid excessive toggles.
-  task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // Make sure SetNeedsBeginFrame isn't called on the client
-  // when the BeginFrame is no longer needed.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_SINGLE_ACTION("SendBeginMainFrameNotExpectedSoon", client_);
-  client_->Reset();
-}
-
-TEST_F(SchedulerTest, SyntheticBeginFrames) {
-  bool use_external_begin_frame_source = false;
-  bool throttle_frame_production = true;
-  BeginFramesNotFromClient(use_external_begin_frame_source,
-                           throttle_frame_production);
-}
-
-TEST_F(SchedulerTest, VSyncThrottlingDisabled) {
-  bool use_external_begin_frame_source = true;
-  bool throttle_frame_production = false;
-  BeginFramesNotFromClient(use_external_begin_frame_source,
-                           throttle_frame_production);
-}
-
-TEST_F(SchedulerTest, SyntheticBeginFrames_And_VSyncThrottlingDisabled) {
-  bool use_external_begin_frame_source = false;
-  bool throttle_frame_production = false;
-  BeginFramesNotFromClient(use_external_begin_frame_source,
-                           throttle_frame_production);
-}
-
-void SchedulerTest::BeginFramesNotFromClient_SwapThrottled(
-    bool use_external_begin_frame_source,
-    bool throttle_frame_production) {
-  scheduler_settings_.use_external_begin_frame_source =
-      use_external_begin_frame_source;
-  scheduler_settings_.throttle_frame_production = throttle_frame_production;
-  SetUpScheduler(true);
-
-  scheduler_->SetEstimatedParentDrawTime(base::TimeDelta::FromMicroseconds(1));
-
-  // To test swap ack throttling, this test disables automatic swap acks.
-  scheduler_->SetMaxSwapsPending(1);
-  client_->SetAutomaticSwapAck(false);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  client_->Reset();
-  scheduler_->SetNeedsCommit();
-  EXPECT_NO_ACTION(client_);
-  client_->Reset();
-
-  // Trigger the first BeginImplFrame and BeginMainFrame
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // NotifyReadyToCommit should trigger the pending commit and draw.
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  client_->Reset();
-
-  // Swapping will put us into a swap throttled state.
-  // Run posted deadline.
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // While swap throttled, BeginFrames should trigger BeginImplFrames,
-  // but not a BeginMainFrame or draw.
-  scheduler_->SetNeedsCommit();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_SCOPED(AdvanceFrame());  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // Let time pass sufficiently beyond the regular deadline but not beyond the
-  // late deadline.
-  now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() -
-                        base::TimeDelta::FromMicroseconds(1));
-  task_runner().RunUntilTime(now_src()->Now());
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // Take us out of a swap throttled state.
-  scheduler_->DidSwapBuffersComplete();
-  EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // Verify that the deadline was rescheduled.
-  // We can't use RunUntilTime(now) here because the next frame is also
-  // scheduled if throttle_frame_production = false.
-  base::TimeTicks before_deadline = now_src()->Now();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  base::TimeTicks after_deadline = now_src()->Now();
-  EXPECT_EQ(after_deadline, before_deadline);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-}
-
-TEST_F(SchedulerTest, SyntheticBeginFrames_SwapThrottled) {
-  bool use_external_begin_frame_source = false;
-  bool throttle_frame_production = true;
-  BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
-                                         throttle_frame_production);
-}
-
-TEST_F(SchedulerTest, VSyncThrottlingDisabled_SwapThrottled) {
-  bool use_external_begin_frame_source = true;
-  bool throttle_frame_production = false;
-  BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
-                                         throttle_frame_production);
-}
-
-TEST_F(SchedulerTest,
-       SyntheticBeginFrames_And_VSyncThrottlingDisabled_SwapThrottled) {
-  bool use_external_begin_frame_source = false;
-  bool throttle_frame_production = false;
-  BeginFramesNotFromClient_SwapThrottled(use_external_begin_frame_source,
-                                         throttle_frame_production);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterOutputSurfaceIsInitialized) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(false);
-
-  scheduler_->SetCanStart();
-  scheduler_->SetVisible(true);
-  scheduler_->SetCanDraw(true);
-
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
-  client_->Reset();
-  scheduler_->DidCreateAndInitializeOutputSurface();
-  EXPECT_NO_ACTION(client_);
-
-  scheduler_->DidLoseOutputSurface();
-  EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginFrameStarted) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  // SetNeedsBeginFrames(false) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_ACTION("ScheduledActionCommit", client_, 0, 1);
-
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
-}
-
-void SchedulerTest::DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(
-    bool impl_side_painting) {
-  scheduler_settings_.impl_side_painting = impl_side_painting;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  // Do nothing when impl frame is in deadine pending state.
-  EXPECT_NO_ACTION(client_);
-
-  client_->Reset();
-  // Run posted deadline.
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  // OnBeginImplFrameDeadline didn't schedule output surface creation because
-  // main frame is not yet completed.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  // BeginImplFrame is not started.
-  client_->Reset();
-  task_runner().RunUntilTime(now_src()->Now() +
-                             base::TimeDelta::FromMilliseconds(10));
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  if (impl_side_painting) {
-    EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3);
-    EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3);
-    EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 2, 3);
-  } else {
-    EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2);
-    EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 2);
-  }
-}
-
-TEST_F(SchedulerTest,
-       DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency) {
-  bool impl_side_painting = false;
-  DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
-}
-
-TEST_F(SchedulerTest,
-       DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatencyWithImplPaint) {
-  bool impl_side_painting = true;
-  DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency(impl_side_painting);
-}
-
-void SchedulerTest::DidLoseOutputSurfaceAfterReadyToCommit(
-    bool impl_side_painting) {
-  scheduler_settings_.impl_side_painting = impl_side_painting;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  // SetNeedsBeginFrames(false) is not called until the end of the frame.
-  if (impl_side_painting) {
-    // Sync tree should be forced to activate.
-    EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_);
-  } else {
-    EXPECT_NO_ACTION(client_);
-  }
-
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommit) {
-  DidLoseOutputSurfaceAfterReadyToCommit(false);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterReadyToCommitWithImplPainting) {
-  DidLoseOutputSurfaceAfterReadyToCommit(true);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterSetNeedsPrepareTiles) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetNeedsPrepareTiles();
-  scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  // SetNeedsBeginFrames(false) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
-
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 0, 4);
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 1, 4);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 2, 4);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceAfterBeginRetroFramePosted) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  // Create a BeginFrame with a long deadline to avoid race conditions.
-  // This is the first BeginFrame, which will be handled immediately.
-  client_->Reset();
-  BeginFrameArgs args =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
-  args.deadline += base::TimeDelta::FromHours(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  // Queue BeginFrames while we are still handling the previous BeginFrame.
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-
-  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  // NotifyReadyToCommit should trigger the commit.
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  client_->Reset();
-  EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
-  scheduler_->DidLoseOutputSurface();
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
-  EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty());
-
-  // Posted BeginRetroFrame is aborted.
-  client_->Reset();
-  task_runner().RunPendingTasks();
-  EXPECT_NO_ACTION(client_);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceDuringBeginRetroFrameRunning) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  // Create a BeginFrame with a long deadline to avoid race conditions.
-  // This is the first BeginFrame, which will be handled immediately.
-  client_->Reset();
-  BeginFrameArgs args =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
-  args.deadline += base::TimeDelta::FromHours(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  // Queue BeginFrames while we are still handling the previous BeginFrame.
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-  args.frame_time += base::TimeDelta::FromSeconds(1);
-  fake_external_begin_frame_source()->TestOnBeginFrame(args);
-
-  // If we don't swap on the deadline, we wait for the next BeginImplFrame.
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  // NotifyReadyToCommit should trigger the commit.
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  // BeginImplFrame should prepare the draw.
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted BeginRetroFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-
-  client_->Reset();
-  EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty());
-  scheduler_->DidLoseOutputSurface();
-  EXPECT_NO_ACTION(client_);
-  EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty());
-
-  // BeginImplFrame deadline should abort drawing.
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_FALSE(client_->needs_begin_frames());
-
-  // No more BeginRetroFrame because BeginRetroFrame queue is cleared.
-  client_->Reset();
-  task_runner().RunPendingTasks();
-  EXPECT_NO_ACTION(client_);
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceWithSyntheticBeginFrameSource) {
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
-  scheduler_->SetNeedsCommit();
-  EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
-
-  client_->Reset();
-  AdvanceFrame();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
-
-  // NotifyReadyToCommit should trigger the commit.
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-  EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
-
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  // SetNeedsBeginFrames(false) is not called until the end of the frame.
-  EXPECT_NO_ACTION(client_);
-  EXPECT_TRUE(scheduler_->frame_source().NeedsBeginFrames());
-
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->frame_source().NeedsBeginFrames());
-}
-
-TEST_F(SchedulerTest, DidLoseOutputSurfaceWhenIdle) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-
-  client_->Reset();
-  task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(true));
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-
-  // Idle time between BeginFrames.
-  client_->Reset();
-  scheduler_->DidLoseOutputSurface();
-  EXPECT_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_, 0, 3);
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 1, 3);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3);
-}
-
-TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
-  scheduler_settings_.impl_side_painting = true;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-
-  client_->Reset();
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-
-  client_->Reset();
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_);
-
-  client_->Reset();
-  scheduler_->SetVisible(false);
-  // Sync tree should be forced to activate.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2);
-}
-
-// Tests to ensure frame sources can be successfully changed while drawing.
-TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  scheduler_->SetNeedsRedraw();
-
-  // Switch to an unthrottled frame source.
-  scheduler_->SetThrottleFrameProduction(false);
-  client_->Reset();
-
-  // Unthrottled frame source will immediately begin a new frame.
-  task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // If we don't swap on the deadline, we wait for the next BeginFrame.
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-}
-
-// Tests to ensure frame sources can be successfully changed while a frame
-// deadline is pending.
-TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsRedraw();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-
-  // Switch to an unthrottled frame source before the frame deadline is hit.
-  scheduler_->SetThrottleFrameProduction(false);
-  client_->Reset();
-
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline and BeginFrame.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2);
-  // Unthrottled frame source will immediately begin a new frame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2);
-  scheduler_->SetNeedsRedraw();
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-}
-
-// Tests to ensure that the active frame source can successfully be changed from
-// unthrottled to throttled.
-TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) {
-  scheduler_settings_.throttle_frame_production = false;
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  scheduler_->SetNeedsRedraw();
-  EXPECT_NO_ACTION(client_);
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted BeginFrame.
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-  EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  // Switch to a throttled frame source.
-  scheduler_->SetThrottleFrameProduction(true);
-  client_->Reset();
-
-  // SetNeedsRedraw should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsRedraw();
-  task_runner().RunPendingTasks();
-  EXPECT_NO_ACTION(client_);
-  client_->Reset();
-
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  EXPECT_TRUE(client_->needs_begin_frames());
-  client_->Reset();
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1);
-}
-
-// Tests to ensure that we send a BeginMainFrameNotExpectedSoon when expected.
-TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) {
-  scheduler_settings_.use_external_begin_frame_source = true;
-  SetUpScheduler(true);
-
-  // SetNeedsCommit should begin the frame on the next BeginImplFrame.
-  scheduler_->SetNeedsCommit();
-  EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
-  client_->Reset();
-
-  // Trigger a frame draw.
-  EXPECT_SCOPED(AdvanceFrame());
-  scheduler_->NotifyBeginMainFrameStarted();
-  scheduler_->NotifyReadyToCommit();
-  task_runner().RunPendingTasks();
-  EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5);
-  EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5);
-  EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5);
-  EXPECT_ACTION("ScheduledActionAnimate", client_, 3, 5);
-  EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5);
-  client_->Reset();
-
-  // The following BeginImplFrame deadline should SetNeedsBeginFrame(false)
-  // and send a SendBeginMainFrameNotExpectedSoon.
-  EXPECT_SCOPED(AdvanceFrame());
-  EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_);
-  EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
-  client_->Reset();
-
-  task_runner().RunPendingTasks();  // Run posted deadline.
-  EXPECT_ACTION("SetNeedsBeginFrames(false)", client_, 0, 2);
-  EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2);
-  client_->Reset();
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/BUILD.gn b/cc/surfaces/BUILD.gn
deleted file mode 100644
index e43d4e5..0000000
--- a/cc/surfaces/BUILD.gn
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2014 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.
-
-source_set("surface_id") {
-  sources = [
-    "surface_id.h",
-  ]
-
-  deps = [
-    "//base",
-  ]
-}
-
-component("surfaces") {
-  output_name = "cc_surfaces"
-  sources = [
-    "display.cc",
-    "display.h",
-    "display_client.h",
-    "onscreen_display_client.cc",
-    "onscreen_display_client.h",
-    "surface.cc",
-    "surface.h",
-    "surface_aggregator.cc",
-    "surface_aggregator.h",
-    "surface_display_output_surface.cc",
-    "surface_display_output_surface.h",
-    "surface_factory.cc",
-    "surface_factory.h",
-    "surface_factory_client.h",
-    "surface_id_allocator.cc",
-    "surface_id_allocator.h",
-    "surface_manager.cc",
-    "surface_manager.h",
-    "surface_resource_holder.cc",
-    "surface_resource_holder.h",
-    "surfaces_export.h",
-  ]
-
-  defines = [ "CC_SURFACES_IMPLEMENTATION=1" ]
-
-  deps = [
-    ":surface_id",
-    "//base",
-    "//base/third_party/dynamic_annotations",
-    "//cc",
-    "//skia",
-    "//ui/events:events_base",
-    "//ui/gfx",
-    "//ui/gfx/geometry",
-  ]
-
-  if (is_android && !is_debug) {
-    configs -= [ "//build/config/compiler:optimize" ]
-    configs += [ "//build/config/compiler:optimize_max" ]
-  }
-}
diff --git a/cc/surfaces/OWNERS b/cc/surfaces/OWNERS
deleted file mode 100644
index 023e5fc..0000000
--- a/cc/surfaces/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-jamesr@chromium.org
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
deleted file mode 100644
index d352712..0000000
--- a/cc/surfaces/display.cc
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/display.h"
-
-#include "base/message_loop/message_loop.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/renderer_settings.h"
-#include "cc/output/software_renderer.h"
-#include "cc/resources/texture_mailbox_deleter.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_manager.h"
-
-namespace cc {
-
-Display::Display(DisplayClient* client,
-                 SurfaceManager* manager,
-                 SharedBitmapManager* bitmap_manager,
-                 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-                 const RendererSettings& settings)
-    : client_(client),
-      manager_(manager),
-      bitmap_manager_(bitmap_manager),
-      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
-      settings_(settings),
-      device_scale_factor_(1.f),
-      texture_mailbox_deleter_(
-          new TextureMailboxDeleter(base::MessageLoopProxy::current())) {
-  manager_->AddObserver(this);
-}
-
-Display::~Display() {
-  manager_->RemoveObserver(this);
-  if (aggregator_) {
-    for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
-      Surface* surface = manager_->GetSurfaceForId(id_entry.first);
-      if (surface)
-        surface->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
-    }
-  }
-}
-
-bool Display::Initialize(scoped_ptr<OutputSurface> output_surface) {
-  output_surface_ = output_surface.Pass();
-  return output_surface_->BindToClient(this);
-}
-
-void Display::SetSurfaceId(SurfaceId id, float device_scale_factor) {
-  current_surface_id_ = id;
-  device_scale_factor_ = device_scale_factor;
-  client_->DisplayDamaged();
-}
-
-void Display::Resize(const gfx::Size& size) {
-  if (size == current_surface_size_)
-    return;
-  // Need to ensure all pending swaps have executed before the window is
-  // resized, or D3D11 will scale the swap output.
-  if (renderer_ && settings_.finish_rendering_on_resize)
-    renderer_->Finish();
-  current_surface_size_ = size;
-  client_->DisplayDamaged();
-}
-
-void Display::InitializeRenderer() {
-  if (resource_provider_)
-    return;
-
-  scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(
-      output_surface_.get(), bitmap_manager_, gpu_memory_buffer_manager_,
-      nullptr, settings_.highp_threshold_min, settings_.use_rgba_4444_textures,
-      settings_.texture_id_allocation_chunk_size);
-  if (!resource_provider)
-    return;
-
-  if (output_surface_->context_provider()) {
-    scoped_ptr<GLRenderer> renderer = GLRenderer::Create(
-        this, &settings_, output_surface_.get(), resource_provider.get(),
-        texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
-    if (!renderer)
-      return;
-    renderer_ = renderer.Pass();
-  } else {
-    scoped_ptr<SoftwareRenderer> renderer = SoftwareRenderer::Create(
-        this, &settings_, output_surface_.get(), resource_provider.get());
-    if (!renderer)
-      return;
-    renderer_ = renderer.Pass();
-  }
-
-  resource_provider_ = resource_provider.Pass();
-  aggregator_.reset(new SurfaceAggregator(manager_, resource_provider_.get()));
-}
-
-void Display::DidLoseOutputSurface() {
-  client_->OutputSurfaceLost();
-}
-
-bool Display::Draw() {
-  if (current_surface_id_.is_null())
-    return false;
-
-  InitializeRenderer();
-  if (!output_surface_)
-    return false;
-
-  // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks
-  // while Aggregate is called to immediately run release callbacks afterward.
-  scoped_ptr<CompositorFrame> frame =
-      aggregator_->Aggregate(current_surface_id_);
-  if (!frame)
-    return false;
-
-  TRACE_EVENT0("cc", "Display::Draw");
-
-  // Run callbacks early to allow pipelining.
-  for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
-    Surface* surface = manager_->GetSurfaceForId(id_entry.first);
-    if (surface)
-      surface->RunDrawCallbacks(SurfaceDrawStatus::DRAWN);
-  }
-  DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
-
-  frame->metadata.latency_info.insert(frame->metadata.latency_info.end(),
-                                      stored_latency_info_.begin(),
-                                      stored_latency_info_.end());
-  stored_latency_info_.clear();
-  bool have_copy_requests = false;
-  for (const auto* pass : frame_data->render_pass_list) {
-    have_copy_requests |= !pass->copy_requests.empty();
-  }
-
-  gfx::Size surface_size;
-  bool have_damage = false;
-  if (!frame_data->render_pass_list.empty()) {
-    surface_size = frame_data->render_pass_list.back()->output_rect.size();
-    have_damage =
-        !frame_data->render_pass_list.back()->damage_rect.size().IsEmpty();
-  }
-  bool avoid_swap = surface_size != current_surface_size_;
-  bool should_draw = !frame->metadata.latency_info.empty() ||
-                     have_copy_requests || (have_damage && !avoid_swap);
-
-  if (should_draw) {
-    gfx::Rect device_viewport_rect = gfx::Rect(current_surface_size_);
-    gfx::Rect device_clip_rect = device_viewport_rect;
-    bool disable_picture_quad_image_filtering = false;
-
-    renderer_->DecideRenderPassAllocationsForFrame(
-        frame_data->render_pass_list);
-    renderer_->DrawFrame(&frame_data->render_pass_list, device_scale_factor_,
-                         device_viewport_rect, device_clip_rect,
-                         disable_picture_quad_image_filtering);
-  }
-
-  if (should_draw && !avoid_swap) {
-    renderer_->SwapBuffers(frame->metadata);
-  } else {
-    stored_latency_info_.insert(stored_latency_info_.end(),
-                                frame->metadata.latency_info.begin(),
-                                frame->metadata.latency_info.end());
-    DidSwapBuffers();
-    DidSwapBuffersComplete();
-  }
-
-  return true;
-}
-
-void Display::DidSwapBuffers() {
-  client_->DidSwapBuffers();
-}
-
-void Display::DidSwapBuffersComplete() {
-  client_->DidSwapBuffersComplete();
-}
-
-void Display::CommitVSyncParameters(base::TimeTicks timebase,
-                                    base::TimeDelta interval) {
-  client_->CommitVSyncParameters(timebase, interval);
-}
-
-void Display::OnSurfaceDamaged(SurfaceId surface_id, bool* changed) {
-  if (aggregator_ &&
-      aggregator_->previous_contained_surfaces().count(surface_id)) {
-    Surface* surface = manager_->GetSurfaceForId(surface_id);
-    if (surface) {
-      const CompositorFrame* current_frame = surface->GetEligibleFrame();
-      if (!current_frame || !current_frame->delegated_frame_data ||
-          !current_frame->delegated_frame_data->resource_list.size())
-        aggregator_->ReleaseResources(surface_id);
-    }
-    client_->DisplayDamaged();
-    *changed = true;
-  } else if (surface_id == current_surface_id_) {
-    client_->DisplayDamaged();
-    *changed = true;
-  }
-}
-
-SurfaceId Display::CurrentSurfaceId() {
-  return current_surface_id_;
-}
-
-int Display::GetMaxFramesPending() {
-  int max_frames_pending =
-      output_surface_ ? output_surface_->capabilities().max_frames_pending : 0;
-  if (max_frames_pending <= 0)
-    max_frames_pending = OutputSurface::DEFAULT_MAX_FRAMES_PENDING;
-  return max_frames_pending;
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h
deleted file mode 100644
index e788d11..0000000
--- a/cc/surfaces/display.h
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_DISPLAY_H_
-#define CC_SURFACES_DISPLAY_H_
-
-#include <vector>
-
-#include "base/memory/scoped_ptr.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/output/renderer.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "ui/events/latency_info.h"
-
-namespace gpu {
-class GpuMemoryBufferManager;
-}
-
-namespace gfx {
-class Size;
-}
-
-namespace cc {
-
-class DirectRenderer;
-class DisplayClient;
-class OutputSurface;
-class RendererSettings;
-class ResourceProvider;
-class SharedBitmapManager;
-class Surface;
-class SurfaceAggregator;
-class SurfaceIdAllocator;
-class SurfaceFactory;
-class TextureMailboxDeleter;
-
-// A Display produces a surface that can be used to draw to a physical display
-// (OutputSurface). The client is responsible for creating and sizing the
-// surface IDs used to draw into the display and deciding when to draw.
-class CC_SURFACES_EXPORT Display : public OutputSurfaceClient,
-                                   public RendererClient,
-                                   public SurfaceDamageObserver {
- public:
-  Display(DisplayClient* client,
-          SurfaceManager* manager,
-          SharedBitmapManager* bitmap_manager,
-          gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-          const RendererSettings& settings);
-  ~Display() override;
-
-  bool Initialize(scoped_ptr<OutputSurface> output_surface);
-
-  // device_scale_factor is used to communicate to the external window system
-  // what scale this was rendered at.
-  void SetSurfaceId(SurfaceId id, float device_scale_factor);
-  void Resize(const gfx::Size& new_size);
-  bool Draw();
-
-  SurfaceId CurrentSurfaceId();
-  int GetMaxFramesPending();
-
-  // OutputSurfaceClient implementation.
-  void DeferredInitialize() override {}
-  void ReleaseGL() override {}
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval) override;
-  void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override {}
-  void DidSwapBuffers() override;
-  void DidSwapBuffersComplete() override;
-  void ReclaimResources(const CompositorFrameAck* ack) override {}
-  void DidLoseOutputSurface() override;
-  void SetExternalDrawConstraints(
-      const gfx::Transform& transform,
-      const gfx::Rect& viewport,
-      const gfx::Rect& clip,
-      const gfx::Rect& viewport_rect_for_tile_priority,
-      const gfx::Transform& transform_for_tile_priority,
-      bool resourceless_software_draw) override {}
-  void SetTreeActivationCallback(const base::Closure& callback) override {}
-
-  // RendererClient implementation.
-  void SetFullRootLayerDamage() override {}
-
-  // SurfaceDamageObserver implementation.
-  void OnSurfaceDamaged(SurfaceId surface, bool* changed) override;
-
- private:
-  void InitializeRenderer();
-
-  DisplayClient* client_;
-  SurfaceManager* manager_;
-  SharedBitmapManager* bitmap_manager_;
-  gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_;
-  RendererSettings settings_;
-  SurfaceId current_surface_id_;
-  gfx::Size current_surface_size_;
-  float device_scale_factor_;
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<SurfaceAggregator> aggregator_;
-  scoped_ptr<DirectRenderer> renderer_;
-  scoped_ptr<TextureMailboxDeleter> texture_mailbox_deleter_;
-  std::vector<ui::LatencyInfo> stored_latency_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(Display);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DISPLAY_H_
diff --git a/cc/surfaces/display_client.h b/cc/surfaces/display_client.h
deleted file mode 100644
index d2421e2..0000000
--- a/cc/surfaces/display_client.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_DISPLAY_CLIENT_H_
-#define CC_SURFACES_DISPLAY_CLIENT_H_
-
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-
-namespace cc {
-
-struct ManagedMemoryPolicy;
-
-class DisplayClient {
- public:
-  virtual void DisplayDamaged() = 0;
-  virtual void DidSwapBuffers() = 0;
-  virtual void DidSwapBuffersComplete() = 0;
-  virtual void CommitVSyncParameters(base::TimeTicks timebase,
-                                     base::TimeDelta interval) = 0;
-  virtual void OutputSurfaceLost() = 0;
-
- protected:
-  virtual ~DisplayClient() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DISPLAY_CLIENT_H_
diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc
deleted file mode 100644
index 7b01244..0000000
--- a/cc/surfaces/display_unittest.cc
+++ /dev/null
@@ -1,239 +0,0 @@
-// 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.
-
-#include "cc/output/compositor_frame.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/quads/render_pass.h"
-#include "cc/resources/shared_bitmap_manager.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_factory_client.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
- public:
-  void ReturnResources(const ReturnedResourceArray& resources) override {}
-};
-
-class DisplayTest : public testing::Test {
- public:
-  DisplayTest() : factory_(&manager_, &empty_client_) {}
-
-  void SetUp() override {
-    output_surface_ = FakeOutputSurface::CreateSoftware(
-        make_scoped_ptr(new SoftwareOutputDevice));
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-    output_surface_ptr_ = output_surface_.get();
-  }
-
- protected:
-  void SubmitFrame(RenderPassList* pass_list, SurfaceId surface_id) {
-    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-    pass_list->swap(frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-    frame->delegated_frame_data = frame_data.Pass();
-
-    factory_.SubmitFrame(surface_id, frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  SurfaceManager manager_;
-  EmptySurfaceFactoryClient empty_client_;
-  SurfaceFactory factory_;
-  scoped_ptr<FakeOutputSurface> output_surface_;
-  FakeOutputSurface* output_surface_ptr_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-};
-
-class TestDisplayClient : public DisplayClient {
- public:
-  TestDisplayClient() : damaged(false), swapped(false) {}
-  ~TestDisplayClient() override {}
-
-  void DisplayDamaged() override { damaged = true; }
-  void DidSwapBuffers() override { swapped = true; }
-  void DidSwapBuffersComplete() override {}
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval) override {}
-  void OutputSurfaceLost() override {}
-  void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override {}
-
-  bool damaged;
-  bool swapped;
-};
-
-void CopyCallback(bool* called, scoped_ptr<CopyOutputResult> result) {
-  *called = true;
-}
-
-// Check that frame is damaged and swapped only under correct conditions.
-TEST_F(DisplayTest, DisplayDamaged) {
-  TestDisplayClient client;
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  Display display(&client, &manager_, shared_bitmap_manager_.get(), nullptr,
-                  settings);
-
-  display.Initialize(output_surface_.Pass());
-
-  SurfaceId surface_id(7u);
-  EXPECT_FALSE(client.damaged);
-  display.SetSurfaceId(surface_id, 1.f);
-  EXPECT_TRUE(client.damaged);
-
-  client.damaged = false;
-  display.Resize(gfx::Size(100, 100));
-  EXPECT_TRUE(client.damaged);
-
-  factory_.Create(surface_id);
-
-  // First draw from surface should have full damage.
-  RenderPassList pass_list;
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  pass->output_rect = gfx::Rect(0, 0, 100, 100);
-  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-  pass->id = RenderPassId(1, 1);
-  pass_list.push_back(pass.Pass());
-
-  client.damaged = false;
-  SubmitFrame(&pass_list, surface_id);
-  EXPECT_TRUE(client.damaged);
-
-  EXPECT_FALSE(client.swapped);
-  EXPECT_EQ(0u, output_surface_ptr_->num_sent_frames());
-  display.Draw();
-  EXPECT_TRUE(client.swapped);
-  EXPECT_EQ(1u, output_surface_ptr_->num_sent_frames());
-  SoftwareFrameData* software_data =
-      output_surface_ptr_->last_sent_frame().software_frame_data.get();
-  ASSERT_NE(nullptr, software_data);
-  EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
-  EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
-            software_data->damage_rect.ToString());
-
-  {
-    // Only damaged portion should be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-    pass->id = RenderPassId(1, 1);
-
-    pass_list.push_back(pass.Pass());
-    client.damaged = false;
-    SubmitFrame(&pass_list, surface_id);
-    EXPECT_TRUE(client.damaged);
-
-    client.swapped = false;
-    display.Draw();
-    EXPECT_TRUE(client.swapped);
-    EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
-    software_data =
-        output_surface_ptr_->last_sent_frame().software_frame_data.get();
-    ASSERT_NE(nullptr, software_data);
-    EXPECT_EQ(gfx::Size(100, 100).ToString(), software_data->size.ToString());
-    EXPECT_EQ(gfx::Rect(10, 10, 1, 1).ToString(),
-              software_data->damage_rect.ToString());
-  }
-
-  {
-    // Pass has no damage so shouldn't be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = RenderPassId(1, 1);
-
-    pass_list.push_back(pass.Pass());
-    client.damaged = false;
-    SubmitFrame(&pass_list, surface_id);
-    EXPECT_TRUE(client.damaged);
-
-    client.swapped = false;
-    display.Draw();
-    EXPECT_TRUE(client.swapped);
-    EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
-  }
-
-  {
-    // Pass is wrong size so shouldn't be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 99, 99);
-    pass->damage_rect = gfx::Rect(10, 10, 10, 10);
-    pass->id = RenderPassId(1, 1);
-
-    pass_list.push_back(pass.Pass());
-    client.damaged = false;
-    SubmitFrame(&pass_list, surface_id);
-    EXPECT_TRUE(client.damaged);
-
-    client.swapped = false;
-    display.Draw();
-    EXPECT_TRUE(client.swapped);
-    EXPECT_EQ(2u, output_surface_ptr_->num_sent_frames());
-  }
-
-  {
-    // Pass has copy output request so should be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    bool copy_called = false;
-    pass->copy_requests.push_back(CopyOutputRequest::CreateRequest(
-        base::Bind(&CopyCallback, &copy_called)));
-    pass->id = RenderPassId(1, 1);
-
-    pass_list.push_back(pass.Pass());
-    client.damaged = false;
-    SubmitFrame(&pass_list, surface_id);
-    EXPECT_TRUE(client.damaged);
-
-    client.swapped = false;
-    display.Draw();
-    EXPECT_TRUE(client.swapped);
-    EXPECT_EQ(3u, output_surface_ptr_->num_sent_frames());
-    EXPECT_TRUE(copy_called);
-  }
-
-  // Pass has latency info so should be swapped.
-  {
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = RenderPassId(1, 1);
-
-    pass_list.push_back(pass.Pass());
-    client.damaged = false;
-    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-    pass_list.swap(frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-    frame->delegated_frame_data = frame_data.Pass();
-    frame->metadata.latency_info.push_back(ui::LatencyInfo());
-
-    factory_.SubmitFrame(surface_id, frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-    EXPECT_TRUE(client.damaged);
-
-    client.swapped = false;
-    display.Draw();
-    EXPECT_TRUE(client.swapped);
-    EXPECT_EQ(4u, output_surface_ptr_->num_sent_frames());
-  }
-
-  factory_.Destroy(surface_id);
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/onscreen_display_client.cc b/cc/surfaces/onscreen_display_client.cc
deleted file mode 100644
index 5154dbc..0000000
--- a/cc/surfaces/onscreen_display_client.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/onscreen_display_client.h"
-
-#include "base/trace_event/trace_event.h"
-#include "cc/output/output_surface.h"
-#include "cc/surfaces/surface_display_output_surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_manager.h"
-
-namespace cc {
-
-OnscreenDisplayClient::OnscreenDisplayClient(
-    scoped_ptr<OutputSurface> output_surface,
-    SurfaceManager* manager,
-    SharedBitmapManager* bitmap_manager,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    const RendererSettings& settings,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner)
-    : output_surface_(output_surface.Pass()),
-      display_(new Display(this,
-                           manager,
-                           bitmap_manager,
-                           gpu_memory_buffer_manager,
-                           settings)),
-      task_runner_(task_runner),
-      scheduled_draw_(false),
-      output_surface_lost_(false),
-      deferred_draw_(false),
-      pending_frames_(0),
-      weak_ptr_factory_(this) {
-}
-
-OnscreenDisplayClient::~OnscreenDisplayClient() {
-}
-
-bool OnscreenDisplayClient::Initialize() {
-  return display_->Initialize(output_surface_.Pass());
-}
-
-void OnscreenDisplayClient::CommitVSyncParameters(base::TimeTicks timebase,
-                                                  base::TimeDelta interval) {
-  surface_display_output_surface_->ReceivedVSyncParameters(timebase, interval);
-}
-
-void OnscreenDisplayClient::DisplayDamaged() {
-  if (scheduled_draw_ || deferred_draw_)
-    return;
-  TRACE_EVENT0("content", "OnscreenDisplayClient::DisplayDamaged");
-  if (pending_frames_ >= display_->GetMaxFramesPending()) {
-    deferred_draw_ = true;
-  } else {
-    ScheduleDraw();
-  }
-}
-
-void OnscreenDisplayClient::ScheduleDraw() {
-  DCHECK(!deferred_draw_);
-  DCHECK(!scheduled_draw_);
-  scheduled_draw_ = true;
-  task_runner_->PostTask(FROM_HERE, base::Bind(&OnscreenDisplayClient::Draw,
-                                               weak_ptr_factory_.GetWeakPtr()));
-}
-
-void OnscreenDisplayClient::OutputSurfaceLost() {
-  output_surface_lost_ = true;
-  surface_display_output_surface_->DidLoseOutputSurface();
-}
-
-void OnscreenDisplayClient::Draw() {
-  TRACE_EVENT0("content", "OnscreenDisplayClient::Draw");
-  if (output_surface_lost_)
-    return;
-  scheduled_draw_ = false;
-  display_->Draw();
-}
-
-void OnscreenDisplayClient::DidSwapBuffers() {
-  pending_frames_++;
-}
-
-void OnscreenDisplayClient::DidSwapBuffersComplete() {
-  pending_frames_--;
-  if ((pending_frames_ < display_->GetMaxFramesPending()) && deferred_draw_) {
-    deferred_draw_ = false;
-    ScheduleDraw();
-  }
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/onscreen_display_client.h b/cc/surfaces/onscreen_display_client.h
deleted file mode 100644
index edf76c4..0000000
--- a/cc/surfaces/onscreen_display_client.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_ONSCREEN_DISPLAY_CLIENT_H_
-#define CC_SURFACES_ONSCREEN_DISPLAY_CLIENT_H_
-
-#include "cc/surfaces/display_client.h"
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-class ContextProvider;
-class SurfaceManager;
-class SurfaceDisplayOutputSurface;
-
-// This class provides a DisplayClient implementation for drawing directly to an
-// onscreen context.
-class CC_SURFACES_EXPORT OnscreenDisplayClient
-    : NON_EXPORTED_BASE(DisplayClient) {
- public:
-  OnscreenDisplayClient(
-      scoped_ptr<OutputSurface> output_surface,
-      SurfaceManager* manager,
-      SharedBitmapManager* bitmap_manager,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      const RendererSettings& settings,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-  ~OnscreenDisplayClient() override;
-
-  bool Initialize();
-  Display* display() { return display_.get(); }
-  void set_surface_output_surface(SurfaceDisplayOutputSurface* surface) {
-    surface_display_output_surface_ = surface;
-  }
-
-  // DisplayClient implementation.
-  void DisplayDamaged() override;
-  void DidSwapBuffers() override;
-  void DidSwapBuffersComplete() override;
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval) override;
-  void OutputSurfaceLost() override;
-
-  bool output_surface_lost() { return output_surface_lost_; }
-
- private:
-  void ScheduleDraw();
-  void Draw();
-
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<Display> display_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  SurfaceDisplayOutputSurface* surface_display_output_surface_;
-  bool scheduled_draw_;
-  bool output_surface_lost_;
-  // True if a draw should be scheduled, but it's hit the limit on max frames
-  // pending.
-  bool deferred_draw_;
-  int pending_frames_;
-
-  base::WeakPtrFactory<OnscreenDisplayClient> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(OnscreenDisplayClient);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_ONSCREEN_DISPLAY_CLIENT_H_
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc
deleted file mode 100644
index 065aa38..0000000
--- a/cc/surfaces/surface.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface.h"
-
-#include <algorithm>
-
-#include "cc/output/compositor_frame.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
-
-namespace cc {
-
-// The frame index starts at 2 so that empty frames will be treated as
-// completely damaged the first time they're drawn from.
-static const int kFrameIndexStart = 2;
-
-Surface::Surface(SurfaceId id, SurfaceFactory* factory)
-    : surface_id_(id),
-      factory_(factory->AsWeakPtr()),
-      frame_index_(kFrameIndexStart) {
-}
-
-Surface::~Surface() {
-  ClearCopyRequests();
-  if (current_frame_ && factory_) {
-    ReturnedResourceArray current_resources;
-    TransferableResource::ReturnResources(
-        current_frame_->delegated_frame_data->resource_list,
-        &current_resources);
-    factory_->UnrefResources(current_resources);
-  }
-  if (!draw_callback_.is_null())
-    draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED);
-}
-
-void Surface::QueueFrame(scoped_ptr<CompositorFrame> frame,
-                         const DrawCallback& callback) {
-  DCHECK(factory_);
-  ClearCopyRequests();
-  TakeLatencyInfo(&frame->metadata.latency_info);
-  scoped_ptr<CompositorFrame> previous_frame = current_frame_.Pass();
-  current_frame_ = frame.Pass();
-  factory_->ReceiveFromChild(
-      current_frame_->delegated_frame_data->resource_list);
-  // Empty frames shouldn't be drawn and shouldn't contribute damage, so don't
-  // increment frame index for them.
-  if (!current_frame_ ||
-      !current_frame_->delegated_frame_data->render_pass_list.empty())
-    ++frame_index_;
-
-  if (previous_frame) {
-    ReturnedResourceArray previous_resources;
-    TransferableResource::ReturnResources(
-        previous_frame->delegated_frame_data->resource_list,
-        &previous_resources);
-    factory_->UnrefResources(previous_resources);
-  }
-  if (!draw_callback_.is_null())
-    draw_callback_.Run(SurfaceDrawStatus::DRAW_SKIPPED);
-  draw_callback_ = callback;
-  factory_->manager()->DidSatisfySequences(
-      SurfaceIdAllocator::NamespaceForId(surface_id_),
-      &current_frame_->metadata.satisfies_sequences);
-}
-
-void Surface::RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request) {
-  if (current_frame_ &&
-      !current_frame_->delegated_frame_data->render_pass_list.empty())
-    current_frame_->delegated_frame_data->render_pass_list.back()
-        ->copy_requests.push_back(copy_request.Pass());
-  else
-    copy_request->SendEmptyResult();
-}
-
-void Surface::TakeCopyOutputRequests(
-    std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests) {
-  DCHECK(copy_requests->empty());
-  if (current_frame_) {
-    for (const auto& render_pass :
-         current_frame_->delegated_frame_data->render_pass_list) {
-      while (!render_pass->copy_requests.empty()) {
-        scoped_ptr<CopyOutputRequest> request =
-            render_pass->copy_requests.take_back();
-        render_pass->copy_requests.pop_back();
-        copy_requests->insert(
-            std::make_pair(render_pass->id, request.release()));
-      }
-    }
-  }
-}
-
-const CompositorFrame* Surface::GetEligibleFrame() {
-  return current_frame_.get();
-}
-
-void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) {
-  if (!current_frame_)
-    return;
-  if (latency_info->empty()) {
-    current_frame_->metadata.latency_info.swap(*latency_info);
-    return;
-  }
-  std::copy(current_frame_->metadata.latency_info.begin(),
-            current_frame_->metadata.latency_info.end(),
-            std::back_inserter(*latency_info));
-  current_frame_->metadata.latency_info.clear();
-}
-
-void Surface::RunDrawCallbacks(SurfaceDrawStatus drawn) {
-  if (!draw_callback_.is_null()) {
-    DrawCallback callback = draw_callback_;
-    draw_callback_ = DrawCallback();
-    callback.Run(drawn);
-  }
-}
-
-void Surface::AddDestructionDependency(SurfaceSequence sequence) {
-  destruction_dependencies_.push_back(sequence);
-}
-
-void Surface::SatisfyDestructionDependencies(
-    base::hash_set<SurfaceSequence>* sequences) {
-  destruction_dependencies_.erase(
-      std::remove_if(
-          destruction_dependencies_.begin(), destruction_dependencies_.end(),
-          [sequences](SurfaceSequence seq) { return !!sequences->erase(seq); }),
-      destruction_dependencies_.end());
-}
-
-void Surface::ClearCopyRequests() {
-  if (current_frame_) {
-    for (const auto& render_pass :
-         current_frame_->delegated_frame_data->render_pass_list) {
-      for (const auto& copy_request : render_pass->copy_requests)
-        copy_request->SendEmptyResult();
-    }
-  }
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h
deleted file mode 100644
index 8e6d7a4..0000000
--- a/cc/surfaces/surface.h
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_H_
-#define CC_SURFACES_SURFACE_H_
-
-#include <map>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/quads/render_pass_id.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surface_sequence.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace ui {
-struct LatencyInfo;
-}
-
-namespace cc {
-class CompositorFrame;
-class CopyOutputRequest;
-class SurfaceManager;
-class SurfaceFactory;
-class SurfaceResourceHolder;
-
-class CC_SURFACES_EXPORT Surface {
- public:
-  using DrawCallback = SurfaceFactory::DrawCallback;
-
-  Surface(SurfaceId id, SurfaceFactory* factory);
-  ~Surface();
-
-  SurfaceId surface_id() const { return surface_id_; }
-
-  void QueueFrame(scoped_ptr<CompositorFrame> frame,
-                  const DrawCallback& draw_callback);
-  void RequestCopyOfOutput(scoped_ptr<CopyOutputRequest> copy_request);
-  // Adds each CopyOutputRequest in the current frame to copy_requests. The
-  // caller takes ownership of them.
-  void TakeCopyOutputRequests(
-      std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests);
-  // Returns the most recent frame that is eligible to be rendered.
-  const CompositorFrame* GetEligibleFrame();
-
-  // Returns a number that increments by 1 every time a new frame is enqueued.
-  int frame_index() const { return frame_index_; }
-
-  void TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info);
-  void RunDrawCallbacks(SurfaceDrawStatus drawn);
-
-  base::WeakPtr<SurfaceFactory> factory() { return factory_; }
-
-  // Add a SurfaceSequence that must be satisfied before the Surface is
-  // destroyed.
-  void AddDestructionDependency(SurfaceSequence sequence);
-
-  // Satisfy all destruction dependencies that are contained in sequences, and
-  // remove them from sequences.
-  void SatisfyDestructionDependencies(
-      base::hash_set<SurfaceSequence>* sequences);
-  size_t GetDestructionDependencyCount() const {
-    return destruction_dependencies_.size();
-  }
-
- private:
-  void ClearCopyRequests();
-
-  SurfaceId surface_id_;
-  base::WeakPtr<SurfaceFactory> factory_;
-  // TODO(jamesr): Support multiple frames in flight.
-  scoped_ptr<CompositorFrame> current_frame_;
-  int frame_index_;
-  std::vector<SurfaceSequence> destruction_dependencies_;
-
-  DrawCallback draw_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(Surface);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_H_
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
deleted file mode 100644
index 1cab3ab..0000000
--- a/cc/surfaces/surface_aggregator.cc
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_aggregator.h"
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/containers/hash_tables.h"
-#include "base/logging.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/math_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_manager.h"
-
-namespace cc {
-namespace {
-
-void MoveMatchingRequests(
-    RenderPassId id,
-    std::multimap<RenderPassId, CopyOutputRequest*>* copy_requests,
-    ScopedPtrVector<CopyOutputRequest>* output_requests) {
-  auto request_range = copy_requests->equal_range(id);
-  for (auto it = request_range.first; it != request_range.second; ++it) {
-    DCHECK(it->second);
-    output_requests->push_back(scoped_ptr<CopyOutputRequest>(it->second));
-    it->second = nullptr;
-  }
-  copy_requests->erase(request_range.first, request_range.second);
-}
-
-}  // namespace
-
-SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
-                                     ResourceProvider* provider)
-    : manager_(manager), provider_(provider), next_render_pass_id_(1) {
-  DCHECK(manager_);
-}
-
-SurfaceAggregator::~SurfaceAggregator() {}
-
-// Create a clip rect for an aggregated quad from the original clip rect and
-// the clip rect from the surface it's on.
-SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect(
-    const ClipData& surface_clip,
-    const ClipData& quad_clip,
-    const gfx::Transform& content_to_target_transform) {
-  ClipData out_clip;
-  if (surface_clip.is_clipped)
-    out_clip = surface_clip;
-
-  if (quad_clip.is_clipped) {
-    // TODO(jamesr): This only works if content_to_target_transform maps integer
-    // rects to integer rects.
-    gfx::Rect final_clip = MathUtil::MapEnclosingClippedRect(
-        content_to_target_transform, quad_clip.rect);
-    if (out_clip.is_clipped)
-      out_clip.rect.Intersect(final_clip);
-    else
-      out_clip.rect = final_clip;
-    out_clip.is_clipped = true;
-  }
-
-  return out_clip;
-}
-
-class SurfaceAggregator::RenderPassIdAllocator {
- public:
-  explicit RenderPassIdAllocator(int* next_index) : next_index_(next_index) {}
-  ~RenderPassIdAllocator() {}
-
-  void AddKnownPass(RenderPassId id) {
-    if (id_to_index_map_.find(id) != id_to_index_map_.end())
-      return;
-    id_to_index_map_[id] = (*next_index_)++;
-  }
-
-  RenderPassId Remap(RenderPassId id) {
-    DCHECK(id_to_index_map_.find(id) != id_to_index_map_.end());
-    return RenderPassId(1, id_to_index_map_[id]);
-  }
-
- private:
-  base::hash_map<RenderPassId, int> id_to_index_map_;
-  int* next_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(RenderPassIdAllocator);
-};
-
-static void UnrefHelper(base::WeakPtr<SurfaceFactory> surface_factory,
-                        const ReturnedResourceArray& resources,
-                        BlockingTaskRunner* main_thread_task_runner) {
-  if (surface_factory)
-    surface_factory->UnrefResources(resources);
-}
-
-RenderPassId SurfaceAggregator::RemapPassId(RenderPassId surface_local_pass_id,
-                                            SurfaceId surface_id) {
-  RenderPassIdAllocator* allocator = render_pass_allocator_map_.get(surface_id);
-  if (!allocator) {
-    allocator = new RenderPassIdAllocator(&next_render_pass_id_);
-    render_pass_allocator_map_.set(surface_id, make_scoped_ptr(allocator));
-  }
-  allocator->AddKnownPass(surface_local_pass_id);
-  return allocator->Remap(surface_local_pass_id);
-}
-
-int SurfaceAggregator::ChildIdForSurface(Surface* surface) {
-  SurfaceToResourceChildIdMap::iterator it =
-      surface_id_to_resource_child_id_.find(surface->surface_id());
-  if (it == surface_id_to_resource_child_id_.end()) {
-    int child_id =
-        provider_->CreateChild(base::Bind(&UnrefHelper, surface->factory()));
-    surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
-    return child_id;
-  } else {
-    return it->second;
-  }
-}
-
-static ResourceProvider::ResourceId ResourceRemapHelper(
-    bool* invalid_frame,
-    const ResourceProvider::ResourceIdMap& child_to_parent_map,
-    ResourceProvider::ResourceIdArray* resources_in_frame,
-    ResourceProvider::ResourceId id) {
-  ResourceProvider::ResourceIdMap::const_iterator it =
-      child_to_parent_map.find(id);
-  if (it == child_to_parent_map.end()) {
-    *invalid_frame = true;
-    return 0;
-  }
-
-  DCHECK_EQ(it->first, id);
-  ResourceProvider::ResourceId remapped_id = it->second;
-  resources_in_frame->push_back(id);
-  return remapped_id;
-}
-
-bool SurfaceAggregator::TakeResources(Surface* surface,
-                                      const DelegatedFrameData* frame_data,
-                                      RenderPassList* render_pass_list) {
-  RenderPass::CopyAll(frame_data->render_pass_list, render_pass_list);
-  if (!provider_)  // TODO(jamesr): hack for unit tests that don't set up rp
-    return false;
-
-  int child_id = ChildIdForSurface(surface);
-  if (surface->factory())
-    surface->factory()->RefResources(frame_data->resource_list);
-  provider_->ReceiveFromChild(child_id, frame_data->resource_list);
-
-  typedef ResourceProvider::ResourceIdArray IdArray;
-  IdArray referenced_resources;
-
-  bool invalid_frame = false;
-  DrawQuad::ResourceIteratorCallback remap =
-      base::Bind(&ResourceRemapHelper,
-                 &invalid_frame,
-                 provider_->GetChildToParentMap(child_id),
-                 &referenced_resources);
-  for (const auto& render_pass : *render_pass_list) {
-    for (const auto& quad : render_pass->quad_list)
-      quad->IterateResources(remap);
-  }
-
-  if (!invalid_frame)
-    provider_->DeclareUsedResourcesFromChild(child_id, referenced_resources);
-
-  return invalid_frame;
-}
-
-gfx::Rect SurfaceAggregator::DamageRectForSurface(const Surface* surface,
-                                                  const RenderPass& source,
-                                                  const gfx::Rect& full_rect) {
-  int previous_index = previous_contained_surfaces_[surface->surface_id()];
-  if (previous_index == surface->frame_index())
-    return gfx::Rect();
-  else if (previous_index == surface->frame_index() - 1)
-    return source.damage_rect;
-  return full_rect;
-}
-
-void SurfaceAggregator::HandleSurfaceQuad(
-    const SurfaceDrawQuad* surface_quad,
-    const gfx::Transform& content_to_target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_pass) {
-  SurfaceId surface_id = surface_quad->surface_id;
-  // If this surface's id is already in our referenced set then it creates
-  // a cycle in the graph and should be dropped.
-  if (referenced_surfaces_.count(surface_id))
-    return;
-  Surface* surface = manager_->GetSurfaceForId(surface_id);
-  if (!surface) {
-    contained_surfaces_[surface_id] = 0;
-    return;
-  }
-  contained_surfaces_[surface_id] = surface->frame_index();
-  const CompositorFrame* frame = surface->GetEligibleFrame();
-  if (!frame)
-    return;
-  const DelegatedFrameData* frame_data = frame->delegated_frame_data.get();
-  if (!frame_data)
-    return;
-
-  std::multimap<RenderPassId, CopyOutputRequest*> copy_requests;
-  surface->TakeCopyOutputRequests(&copy_requests);
-
-  RenderPassList render_pass_list;
-  bool invalid_frame = TakeResources(surface, frame_data, &render_pass_list);
-  if (invalid_frame) {
-    for (auto& request : copy_requests) {
-      request.second->SendEmptyResult();
-      delete request.second;
-    }
-    return;
-  }
-
-  SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
-
-  bool merge_pass = surface_quad->opacity() == 1.f && copy_requests.empty();
-
-  gfx::Rect surface_damage = DamageRectForSurface(
-      surface, *render_pass_list.back(), surface_quad->visible_rect);
-  const RenderPassList& referenced_passes = render_pass_list;
-  size_t passes_to_copy =
-      merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
-  for (size_t j = 0; j < passes_to_copy; ++j) {
-    const RenderPass& source = *referenced_passes[j];
-
-    size_t sqs_size = source.shared_quad_state_list.size();
-    size_t dq_size = source.quad_list.size();
-    scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size));
-
-    RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
-
-    copy_pass->SetAll(remapped_pass_id, source.output_rect, gfx::Rect(),
-                      source.transform_to_root_target,
-                      source.has_transparent_background);
-
-    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
-
-    // Contributing passes aggregated in to the pass list need to take the
-    // transform of the surface quad into account to update their transform to
-    // the root surface.
-    copy_pass->transform_to_root_target.ConcatTransform(
-        surface_quad->quadTransform());
-    copy_pass->transform_to_root_target.ConcatTransform(
-        content_to_target_transform);
-    copy_pass->transform_to_root_target.ConcatTransform(
-        dest_pass->transform_to_root_target);
-
-    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
-                    gfx::Transform(), ClipData(), copy_pass.get(), surface_id);
-
-    if (j == referenced_passes.size() - 1)
-      surface_damage = gfx::UnionRects(surface_damage, copy_pass->damage_rect);
-
-    dest_pass_list_->push_back(copy_pass.Pass());
-  }
-
-  const RenderPass& last_pass = *render_pass_list.back();
-  if (merge_pass) {
-    // TODO(jamesr): Clean up last pass special casing.
-    const QuadList& quads = last_pass.quad_list;
-
-    gfx::Transform surface_transform = surface_quad->quadTransform();
-    surface_transform.ConcatTransform(content_to_target_transform);
-
-    // Intersect the transformed visible rect and the clip rect to create a
-    // smaller cliprect for the quad.
-    ClipData surface_quad_clip_rect(
-        true, MathUtil::MapEnclosingClippedRect(surface_quad->quadTransform(),
-                                                surface_quad->visible_rect));
-    if (surface_quad->isClipped())
-      surface_quad_clip_rect.rect.Intersect(surface_quad->clipRect());
-
-    ClipData quads_clip = CalculateClipRect(clip_rect, surface_quad_clip_rect,
-                                            content_to_target_transform);
-
-    CopyQuadsToPass(quads, last_pass.shared_quad_state_list, surface_transform,
-                    quads_clip, dest_pass, surface_id);
-  } else {
-    RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
-
-    CopySharedQuadState(surface_quad->shared_quad_state,
-                        content_to_target_transform, clip_rect, dest_pass);
-
-    SharedQuadState* shared_quad_state =
-        dest_pass->shared_quad_state_list.back();
-    RenderPassDrawQuad* quad =
-        dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-    quad->SetNew(shared_quad_state,
-                 surface_quad->rect,
-                 surface_quad->visible_rect,
-                 remapped_pass_id,
-                 0,
-                 gfx::Vector2dF(),
-                 gfx::Size(),
-                 FilterOperations(),
-                 gfx::Vector2dF(),
-                 FilterOperations());
-  }
-  dest_pass->damage_rect =
-      gfx::UnionRects(dest_pass->damage_rect,
-                      MathUtil::MapEnclosingClippedRect(
-                          surface_quad->quadTransform(), surface_damage));
-
-  referenced_surfaces_.erase(it);
-}
-
-void SurfaceAggregator::CopySharedQuadState(
-    const SharedQuadState* source_sqs,
-    const gfx::Transform& content_to_target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_render_pass) {
-  SharedQuadState* copy_shared_quad_state =
-      dest_render_pass->CreateAndAppendSharedQuadState();
-  copy_shared_quad_state->CopyFrom(source_sqs);
-  // content_to_target_transform contains any transformation that may exist
-  // between the context that these quads are being copied from (i.e. the
-  // surface's draw transform when aggregated from within a surface) to the
-  // target space of the pass. This will be identity except when copying the
-  // root draw pass from a surface into a pass when the surface draw quad's
-  // transform is not identity.
-  copy_shared_quad_state->content_to_target_transform.ConcatTransform(
-      content_to_target_transform);
-
-  ClipData new_clip_rect = CalculateClipRect(
-      clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect),
-      content_to_target_transform);
-  copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped;
-  copy_shared_quad_state->clip_rect = new_clip_rect.rect;
-}
-
-void SurfaceAggregator::CopyQuadsToPass(
-    const QuadList& source_quad_list,
-    const SharedQuadStateList& source_shared_quad_state_list,
-    const gfx::Transform& content_to_target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_pass,
-    SurfaceId surface_id) {
-  const SharedQuadState* last_copied_source_shared_quad_state = NULL;
-
-  SharedQuadStateList::ConstIterator sqs_iter =
-      source_shared_quad_state_list.begin();
-  for (const auto& quad : source_quad_list) {
-    while (quad->shared_quad_state != *sqs_iter) {
-      ++sqs_iter;
-      DCHECK(sqs_iter != source_shared_quad_state_list.end());
-    }
-    DCHECK_EQ(quad->shared_quad_state, *sqs_iter);
-
-    if (quad->material == DrawQuad::SURFACE_CONTENT) {
-      const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
-      HandleSurfaceQuad(surface_quad, content_to_target_transform, clip_rect,
-                        dest_pass);
-    } else {
-      if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
-        CopySharedQuadState(quad->shared_quad_state,
-                            content_to_target_transform, clip_rect, dest_pass);
-        last_copied_source_shared_quad_state = quad->shared_quad_state;
-      }
-      if (quad->material == DrawQuad::RENDER_PASS) {
-        const RenderPassDrawQuad* pass_quad =
-            RenderPassDrawQuad::MaterialCast(quad);
-        RenderPassId original_pass_id = pass_quad->render_pass_id;
-        RenderPassId remapped_pass_id =
-            RemapPassId(original_pass_id, surface_id);
-
-        gfx::Rect pass_damage;
-        for (const auto* pass : *dest_pass_list_) {
-          if (pass->id == remapped_pass_id) {
-            pass_damage = pass->damage_rect;
-            break;
-          }
-        }
-
-        DrawQuad* rpdq = dest_pass->CopyFromAndAppendRenderPassDrawQuad(
-            pass_quad, dest_pass->shared_quad_state_list.back(),
-            remapped_pass_id);
-        dest_pass->damage_rect = gfx::UnionRects(
-            dest_pass->damage_rect, MathUtil::MapEnclosingClippedRect(
-                                        rpdq->quadTransform(), pass_damage));
-      } else {
-        dest_pass->CopyFromAndAppendDrawQuad(
-            quad, dest_pass->shared_quad_state_list.back());
-      }
-    }
-  }
-}
-
-void SurfaceAggregator::CopyPasses(const DelegatedFrameData* frame_data,
-                                   Surface* surface) {
-  RenderPassList source_pass_list;
-
-  // The root surface is allowed to have copy output requests, so grab them
-  // off its render passes.
-  std::multimap<RenderPassId, CopyOutputRequest*> copy_requests;
-  surface->TakeCopyOutputRequests(&copy_requests);
-
-  bool invalid_frame = TakeResources(surface, frame_data, &source_pass_list);
-  DCHECK(!invalid_frame);
-
-  for (size_t i = 0; i < source_pass_list.size(); ++i) {
-    const RenderPass& source = *source_pass_list[i];
-
-    size_t sqs_size = source.shared_quad_state_list.size();
-    size_t dq_size = source.quad_list.size();
-    scoped_ptr<RenderPass> copy_pass(RenderPass::Create(sqs_size, dq_size));
-
-    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
-
-    RenderPassId remapped_pass_id =
-        RemapPassId(source.id, surface->surface_id());
-
-    gfx::Rect damage_rect =
-        (i < source_pass_list.size() - 1)
-            ? gfx::Rect()
-            : DamageRectForSurface(surface, source, source.output_rect);
-    copy_pass->SetAll(remapped_pass_id, source.output_rect, damage_rect,
-                      source.transform_to_root_target,
-                      source.has_transparent_background);
-
-    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
-                    gfx::Transform(), ClipData(), copy_pass.get(),
-                    surface->surface_id());
-
-    dest_pass_list_->push_back(copy_pass.Pass());
-  }
-}
-
-void SurfaceAggregator::RemoveUnreferencedChildren() {
-  for (const auto& surface : previous_contained_surfaces_) {
-    if (!contained_surfaces_.count(surface.first)) {
-      SurfaceToResourceChildIdMap::iterator it =
-          surface_id_to_resource_child_id_.find(surface.first);
-      if (it != surface_id_to_resource_child_id_.end()) {
-        provider_->DestroyChild(it->second);
-        surface_id_to_resource_child_id_.erase(it);
-      }
-
-      Surface* surface_ptr = manager_->GetSurfaceForId(surface.first);
-      if (surface_ptr)
-        surface_ptr->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
-    }
-  }
-}
-
-scoped_ptr<CompositorFrame> SurfaceAggregator::Aggregate(SurfaceId surface_id) {
-  Surface* surface = manager_->GetSurfaceForId(surface_id);
-  DCHECK(surface);
-  contained_surfaces_[surface_id] = surface->frame_index();
-  const CompositorFrame* root_surface_frame = surface->GetEligibleFrame();
-  if (!root_surface_frame)
-    return nullptr;
-  TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate");
-
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->delegated_frame_data = make_scoped_ptr(new DelegatedFrameData);
-
-  DCHECK(root_surface_frame->delegated_frame_data);
-
-  SurfaceSet::iterator it = referenced_surfaces_.insert(surface_id).first;
-
-  dest_resource_list_ = &frame->delegated_frame_data->resource_list;
-  dest_pass_list_ = &frame->delegated_frame_data->render_pass_list;
-
-  CopyPasses(root_surface_frame->delegated_frame_data.get(), surface);
-
-  referenced_surfaces_.erase(it);
-  DCHECK(referenced_surfaces_.empty());
-
-  if (dest_pass_list_->empty())
-    return nullptr;
-
-  dest_pass_list_ = NULL;
-  RemoveUnreferencedChildren();
-  contained_surfaces_.swap(previous_contained_surfaces_);
-  contained_surfaces_.clear();
-
-  for (SurfaceIndexMap::iterator it = previous_contained_surfaces_.begin();
-       it != previous_contained_surfaces_.end();
-       ++it) {
-    Surface* surface = manager_->GetSurfaceForId(it->first);
-    if (surface)
-      surface->TakeLatencyInfo(&frame->metadata.latency_info);
-  }
-
-  // TODO(jamesr): Aggregate all resource references into the returned frame's
-  // resource list.
-
-  return frame.Pass();
-}
-
-void SurfaceAggregator::ReleaseResources(SurfaceId surface_id) {
-  SurfaceToResourceChildIdMap::iterator it =
-      surface_id_to_resource_child_id_.find(surface_id);
-  if (it != surface_id_to_resource_child_id_.end()) {
-    provider_->DestroyChild(it->second);
-    surface_id_to_resource_child_id_.erase(it);
-  }
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
deleted file mode 100644
index 1c4f431..0000000
--- a/cc/surfaces/surface_aggregator.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_AGGREGATOR_H_
-#define CC_SURFACES_SURFACE_AGGREGATOR_H_
-
-#include <set>
-
-#include "base/containers/hash_tables.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/quads/render_pass.h"
-#include "cc/resources/transferable_resource.h"
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-
-class CompositorFrame;
-class DelegatedFrameData;
-class ResourceProvider;
-class Surface;
-class SurfaceDrawQuad;
-class SurfaceManager;
-
-class CC_SURFACES_EXPORT SurfaceAggregator {
- public:
-  typedef base::hash_map<SurfaceId, int> SurfaceIndexMap;
-
-  SurfaceAggregator(SurfaceManager* manager, ResourceProvider* provider);
-  ~SurfaceAggregator();
-
-  scoped_ptr<CompositorFrame> Aggregate(SurfaceId surface_id);
-  void ReleaseResources(SurfaceId surface_id);
-  SurfaceIndexMap& previous_contained_surfaces() {
-    return previous_contained_surfaces_;
-  }
-
- private:
-  struct ClipData {
-    ClipData() : is_clipped(false) {}
-    ClipData(bool is_clipped, const gfx::Rect& rect)
-        : is_clipped(is_clipped), rect(rect) {}
-
-    bool is_clipped;
-    gfx::Rect rect;
-  };
-
-  ClipData CalculateClipRect(const ClipData& surface_clip,
-                             const ClipData& quad_clip,
-                             const gfx::Transform& content_to_target_transform);
-
-  RenderPassId RemapPassId(RenderPassId surface_local_pass_id,
-                           SurfaceId surface_id);
-
-  void HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
-                         const gfx::Transform& content_to_target_transform,
-                         const ClipData& clip_rect,
-                         RenderPass* dest_pass);
-  void CopySharedQuadState(const SharedQuadState* source_sqs,
-                           const gfx::Transform& content_to_target_transform,
-                           const ClipData& clip_rect,
-                           RenderPass* dest_render_pass);
-  void CopyQuadsToPass(const QuadList& source_quad_list,
-                       const SharedQuadStateList& source_shared_quad_state_list,
-                       const gfx::Transform& content_to_target_transform,
-                       const ClipData& clip_rect,
-                       RenderPass* dest_pass,
-                       SurfaceId surface_id);
-  void CopyPasses(const DelegatedFrameData* frame_data, Surface* surface);
-
-  // Remove Surfaces that were referenced before but aren't currently
-  // referenced from the ResourceProvider.
-  void RemoveUnreferencedChildren();
-
-  bool TakeResources(Surface* surface,
-                     const DelegatedFrameData* frame_data,
-                     RenderPassList* render_pass_list);
-  int ChildIdForSurface(Surface* surface);
-  gfx::Rect DamageRectForSurface(const Surface* surface,
-                                 const RenderPass& source,
-                                 const gfx::Rect& full_rect);
-
-  SurfaceManager* manager_;
-  ResourceProvider* provider_;
-
-  class RenderPassIdAllocator;
-  typedef base::ScopedPtrHashMap<SurfaceId, scoped_ptr<RenderPassIdAllocator>>
-      RenderPassIdAllocatorMap;
-  RenderPassIdAllocatorMap render_pass_allocator_map_;
-  int next_render_pass_id_;
-
-  typedef base::hash_map<SurfaceId, int> SurfaceToResourceChildIdMap;
-  SurfaceToResourceChildIdMap surface_id_to_resource_child_id_;
-
-  // The following state is only valid for the duration of one Aggregate call
-  // and is only stored on the class to avoid having to pass through every
-  // function call.
-
-  // This is the set of surfaces referenced in the aggregation so far, used to
-  // detect cycles.
-  typedef std::set<SurfaceId> SurfaceSet;
-  SurfaceSet referenced_surfaces_;
-
-  // For each Surface used in the last aggregation, gives the frame_index at
-  // that time.
-  SurfaceIndexMap previous_contained_surfaces_;
-  SurfaceIndexMap contained_surfaces_;
-
-  // This is the pass list for the aggregated frame.
-  RenderPassList* dest_pass_list_;
-
-  // Resource list for the aggregated frame.
-  TransferableResourceArray* dest_resource_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceAggregator);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_AGGREGATOR_H_
diff --git a/cc/surfaces/surface_aggregator_test_helpers.cc b/cc/surfaces/surface_aggregator_test_helpers.cc
deleted file mode 100644
index b21b37e..0000000
--- a/cc/surfaces/surface_aggregator_test_helpers.cc
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_aggregator_test_helpers.h"
-
-#include "base/format_macros.h"
-#include "base/strings/stringprintf.h"
-#include "cc/layers/append_quads_data.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/surface.h"
-#include "cc/test/render_pass_test_common.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkXfermode.h"
-
-namespace cc {
-namespace test {
-
-void AddTestSurfaceQuad(TestRenderPass* pass,
-                        const gfx::Size& surface_size,
-                        float opacity,
-                        SurfaceId surface_id) {
-  gfx::Transform content_to_target_transform;
-  gfx::Size content_bounds = surface_size;
-  gfx::Rect visible_content_rect = gfx::Rect(surface_size);
-  gfx::Rect clip_rect = gfx::Rect(surface_size);
-  bool is_clipped = false;
-  SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-
-  SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->SetAll(content_to_target_transform,
-                            content_bounds,
-                            visible_content_rect,
-                            clip_rect,
-                            is_clipped,
-                            opacity,
-                            blend_mode,
-                            0);
-
-  SurfaceDrawQuad* surface_quad =
-      pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  gfx::Rect quad_rect = gfx::Rect(surface_size);
-  surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                       gfx::Rect(surface_size),
-                       gfx::Rect(surface_size),
-                       surface_id);
-}
-void AddTestRenderPassQuad(TestRenderPass* pass, RenderPassId render_pass_id) {
-  gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5);
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       output_rect.size(),
-                       output_rect,
-                       output_rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-  RenderPassDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  quad->SetNew(shared_state,
-               output_rect,
-               output_rect,
-               render_pass_id,
-               0,
-               gfx::Vector2dF(),
-               gfx::Size(),
-               FilterOperations(),
-               gfx::Vector2dF(),
-               FilterOperations());
-}
-
-void AddQuadInPass(TestRenderPass* pass, Quad desc) {
-  switch (desc.material) {
-    case DrawQuad::SOLID_COLOR:
-      AddQuad(pass, gfx::Rect(0, 0, 5, 5), desc.color);
-      break;
-    case DrawQuad::SURFACE_CONTENT:
-      AddTestSurfaceQuad(pass, gfx::Size(5, 5), desc.opacity, desc.surface_id);
-      break;
-    case DrawQuad::RENDER_PASS:
-      AddTestRenderPassQuad(pass, desc.render_pass_id);
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-void AddPasses(RenderPassList* pass_list,
-               const gfx::Rect& output_rect,
-               Pass* passes,
-               size_t pass_count) {
-  gfx::Transform root_transform;
-  for (size_t i = 0; i < pass_count; ++i) {
-    Pass pass = passes[i];
-    TestRenderPass* test_pass =
-        AddRenderPass(pass_list, pass.id, output_rect, root_transform);
-    for (size_t j = 0; j < pass.quad_count; ++j) {
-      AddQuadInPass(test_pass, pass.quads[j]);
-    }
-  }
-}
-
-void TestQuadMatchesExpectations(Quad expected_quad, const DrawQuad* quad) {
-  switch (expected_quad.material) {
-    case DrawQuad::SOLID_COLOR: {
-      ASSERT_EQ(DrawQuad::SOLID_COLOR, quad->material);
-
-      const SolidColorDrawQuad* solid_color_quad =
-          SolidColorDrawQuad::MaterialCast(quad);
-
-      EXPECT_EQ(expected_quad.color, solid_color_quad->color);
-      break;
-    }
-    case DrawQuad::RENDER_PASS: {
-      ASSERT_EQ(DrawQuad::RENDER_PASS, quad->material);
-
-      const RenderPassDrawQuad* render_pass_quad =
-          RenderPassDrawQuad::MaterialCast(quad);
-
-      EXPECT_EQ(expected_quad.render_pass_id, render_pass_quad->render_pass_id);
-      break;
-    }
-    default:
-      NOTREACHED();
-      break;
-  }
-}
-
-void TestPassMatchesExpectations(Pass expected_pass, const RenderPass* pass) {
-  ASSERT_EQ(expected_pass.quad_count, pass->quad_list.size());
-  for (auto iter = pass->quad_list.cbegin(); iter != pass->quad_list.cend();
-       ++iter) {
-    SCOPED_TRACE(base::StringPrintf("Quad number %" PRIuS, iter.index()));
-    TestQuadMatchesExpectations(expected_pass.quads[iter.index()], *iter);
-  }
-}
-
-void TestPassesMatchExpectations(Pass* expected_passes,
-                                 size_t expected_pass_count,
-                                 const RenderPassList* passes) {
-  ASSERT_EQ(expected_pass_count, passes->size());
-
-  for (size_t i = 0; i < passes->size(); ++i) {
-    SCOPED_TRACE(base::StringPrintf("Pass number %" PRIuS, i));
-    RenderPass* pass = passes->at(i);
-    TestPassMatchesExpectations(expected_passes[i], pass);
-  }
-}
-
-}  // namespace test
-}  // namespace cc
diff --git a/cc/surfaces/surface_aggregator_test_helpers.h b/cc/surfaces/surface_aggregator_test_helpers.h
deleted file mode 100644
index 05c8344..0000000
--- a/cc/surfaces/surface_aggregator_test_helpers.h
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_AGGREGATOR_TEST_HELPERS_H_
-#define CC_SURFACES_SURFACE_AGGREGATOR_TEST_HELPERS_H_
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass_id.h"
-#include "cc/surfaces/surface_id.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class RenderPass;
-class Surface;
-class TestRenderPass;
-
-typedef ScopedPtrVector<RenderPass> RenderPassList;
-
-namespace test {
-
-struct Quad {
-  static Quad SolidColorQuad(SkColor color) {
-    Quad quad;
-    quad.material = DrawQuad::SOLID_COLOR;
-    quad.color = color;
-    return quad;
-  }
-
-  static Quad SurfaceQuad(SurfaceId surface_id, float opacity) {
-    Quad quad;
-    quad.material = DrawQuad::SURFACE_CONTENT;
-    quad.opacity = opacity;
-    quad.surface_id = surface_id;
-    return quad;
-  }
-
-  static Quad RenderPassQuad(RenderPassId id) {
-    Quad quad;
-    quad.material = DrawQuad::RENDER_PASS;
-    quad.render_pass_id = id;
-    return quad;
-  }
-
-  DrawQuad::Material material;
-  // Set when material==DrawQuad::SURFACE_CONTENT.
-  SurfaceId surface_id;
-  float opacity;
-  // Set when material==DrawQuad::SOLID_COLOR.
-  SkColor color;
-  // Set when material==DrawQuad::RENDER_PASS.
-  RenderPassId render_pass_id;
-
- private:
-  Quad()
-      : material(DrawQuad::INVALID),
-        opacity(1.f),
-        color(SK_ColorWHITE),
-        render_pass_id(-1, -1) {}
-};
-
-struct Pass {
-  Pass(Quad* quads, size_t quad_count, RenderPassId id)
-      : quads(quads), quad_count(quad_count), id(id) {}
-  Pass(Quad* quads, size_t quad_count)
-      : quads(quads), quad_count(quad_count), id(1, 1) {}
-
-  Quad* quads;
-  size_t quad_count;
-  RenderPassId id;
-};
-
-void AddSurfaceQuad(TestRenderPass* pass,
-                    const gfx::Size& surface_size,
-                    int surface_id);
-
-void AddQuadInPass(TestRenderPass* pass, Quad desc);
-
-void AddPasses(RenderPassList* pass_list,
-               const gfx::Rect& output_rect,
-               Pass* passes,
-               size_t pass_count);
-
-void TestQuadMatchesExpectations(Quad expected_quad, const DrawQuad* quad);
-
-void TestPassMatchesExpectations(Pass expected_pass, const RenderPass* pass);
-
-void TestPassesMatchExpectations(Pass* expected_passes,
-                                 size_t expected_pass_count,
-                                 const RenderPassList* passes);
-
-}  // namespace test
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_AGGREGATOR_TEST_HELPERS_H_
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
deleted file mode 100644
index 72aa3f1..0000000
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ /dev/null
@@ -1,1430 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/compositor_frame.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/resources/shared_bitmap_manager.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_aggregator_test_helpers.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_factory_client.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/render_pass_test_common.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-namespace {
-
-SurfaceId InvalidSurfaceId() {
-  static SurfaceId invalid;
-  invalid.id = static_cast<uint64_t>(-1);
-  return invalid;
-}
-
-gfx::Size SurfaceSize() {
-  static gfx::Size size(5, 5);
-  return size;
-}
-
-class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
- public:
-  void ReturnResources(const ReturnedResourceArray& resources) override {}
-};
-
-class SurfaceAggregatorTest : public testing::Test {
- public:
-  SurfaceAggregatorTest()
-      : factory_(&manager_, &empty_client_), aggregator_(&manager_, NULL) {}
-
- protected:
-  SurfaceManager manager_;
-  EmptySurfaceFactoryClient empty_client_;
-  SurfaceFactory factory_;
-  SurfaceAggregator aggregator_;
-};
-
-TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) {
-  SurfaceId one_id(7);
-  factory_.Create(one_id);
-  scoped_ptr<CompositorFrame> frame = aggregator_.Aggregate(one_id);
-  EXPECT_FALSE(frame);
-  factory_.Destroy(one_id);
-}
-
-class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
- public:
-  SurfaceAggregatorValidSurfaceTest() : allocator_(1u), child_allocator_(2u) {}
-
-  void SetUp() override {
-    SurfaceAggregatorTest::SetUp();
-    root_surface_id_ = allocator_.GenerateId();
-    factory_.Create(root_surface_id_);
-  }
-
-  void TearDown() override {
-    factory_.Destroy(root_surface_id_);
-    SurfaceAggregatorTest::TearDown();
-  }
-
-  void AggregateAndVerify(test::Pass* expected_passes,
-                          size_t expected_pass_count,
-                          SurfaceId* surface_ids,
-                          size_t expected_surface_count) {
-    scoped_ptr<CompositorFrame> aggregated_frame =
-        aggregator_.Aggregate(root_surface_id_);
-
-    ASSERT_TRUE(aggregated_frame);
-    ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-    DelegatedFrameData* frame_data =
-        aggregated_frame->delegated_frame_data.get();
-
-    TestPassesMatchExpectations(
-        expected_passes, expected_pass_count, &frame_data->render_pass_list);
-
-    // Ensure no duplicate pass ids output.
-    std::set<RenderPassId> used_passes;
-    for (auto* pass : frame_data->render_pass_list) {
-      EXPECT_TRUE(used_passes.insert(pass->id).second);
-    }
-
-    EXPECT_EQ(expected_surface_count,
-              aggregator_.previous_contained_surfaces().size());
-    for (size_t i = 0; i < expected_surface_count; i++) {
-      EXPECT_TRUE(
-          aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-          aggregator_.previous_contained_surfaces().end());
-    }
-  }
-
-  void SubmitFrame(test::Pass* passes,
-                   size_t pass_count,
-                   SurfaceId surface_id) {
-    RenderPassList pass_list;
-    AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count);
-
-    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-    pass_list.swap(frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-    frame->delegated_frame_data = frame_data.Pass();
-
-    factory_.SubmitFrame(surface_id, frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  void QueuePassAsFrame(scoped_ptr<RenderPass> pass, SurfaceId surface_id) {
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(surface_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
- protected:
-  SurfaceId root_surface_id_;
-  SurfaceIdAllocator allocator_;
-  SurfaceIdAllocator child_allocator_;
-};
-
-// Tests that a very simple frame containing only two solid color quads makes it
-// through the aggregator correctly.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
-  test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorRED),
-                        test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  SurfaceId ids[] = {root_surface_id_};
-  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
-  SurfaceId embedded_surface_id = allocator_.GenerateId();
-  factory_.Create(embedded_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
-
-  test::Quad quads[] = {test::Quad::SurfaceQuad(embedded_surface_id, .5f)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  RenderPassList& render_pass_list(frame_data->render_pass_list);
-  ASSERT_EQ(2u, render_pass_list.size());
-  SharedQuadStateList& shared_quad_state_list(
-      render_pass_list[0]->shared_quad_state_list);
-  ASSERT_EQ(2u, shared_quad_state_list.size());
-  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(0)->opacity);
-  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(1)->opacity);
-
-  SharedQuadStateList& shared_quad_state_list2(
-      render_pass_list[1]->shared_quad_state_list);
-  ASSERT_EQ(1u, shared_quad_state_list2.size());
-  EXPECT_EQ(.5f, shared_quad_state_list2.ElementAt(0)->opacity);
-
-  factory_.Destroy(embedded_surface_id);
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
-  test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
-                            test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
-                           {test::Quad::SolidColorQuad(SK_ColorGRAY),
-                            test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
-  test::Pass passes[] = {
-      test::Pass(quads[0], arraysize(quads[0]), RenderPassId(1, 1)),
-      test::Pass(quads[1], arraysize(quads[1]), RenderPassId(1, 2))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  SurfaceId ids[] = {root_surface_id_};
-  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
-}
-
-// This tests very simple embedding. root_surface has a frame containing a few
-// solid color quads and a surface quad referencing embedded_surface.
-// embedded_surface has a frame containing only a solid color quad. The solid
-// color quad should be aggregated into the final frame.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
-  SurfaceId embedded_surface_id = allocator_.GenerateId();
-  factory_.Create(embedded_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
-
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                             test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
-                             test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitFrame(root_passes, arraysize(root_passes), root_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  SurfaceId ids[] = {root_surface_id_, embedded_surface_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-
-  factory_.Destroy(embedded_surface_id);
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
-  SurfaceId embedded_surface_id = allocator_.GenerateId();
-  factory_.Create(embedded_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
-  scoped_ptr<CopyOutputRequest> copy_request(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request_ptr = copy_request.get();
-  factory_.RequestCopyOfSurface(embedded_surface_id, copy_request.Pass());
-
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                             test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
-                             test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitFrame(root_passes, arraysize(root_passes), root_surface_id_);
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  test::Quad expected_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorWHITE),
-      test::Quad::RenderPassQuad(frame_data->render_pass_list[0]->id),
-      test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads)),
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  TestPassesMatchExpectations(expected_passes,
-                              arraysize(expected_passes),
-                              &frame_data->render_pass_list);
-  ASSERT_EQ(2u, frame_data->render_pass_list.size());
-  ASSERT_EQ(1u, frame_data->render_pass_list[0]->copy_requests.size());
-  DCHECK_EQ(copy_request_ptr,
-            frame_data->render_pass_list[0]->copy_requests[0]);
-
-  SurfaceId surface_ids[] = {root_surface_id_, embedded_surface_id};
-  EXPECT_EQ(arraysize(surface_ids),
-            aggregator_.previous_contained_surfaces().size());
-  for (size_t i = 0; i < arraysize(surface_ids); i++) {
-    EXPECT_TRUE(
-        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-        aggregator_.previous_contained_surfaces().end());
-  }
-
-  factory_.Destroy(embedded_surface_id);
-}
-
-// Root surface may contain copy requests.
-TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
-  SurfaceId embedded_surface_id = allocator_.GenerateId();
-  factory_.Create(embedded_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
-  scoped_ptr<CopyOutputRequest> copy_request(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request_ptr = copy_request.get();
-  scoped_ptr<CopyOutputRequest> copy_request2(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request2_ptr = copy_request2.get();
-
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                             test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
-                             test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Quad root_quads2[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
-  test::Pass root_passes[] = {
-      test::Pass(root_quads, arraysize(root_quads), RenderPassId(1, 1)),
-      test::Pass(root_quads2, arraysize(root_quads2), RenderPassId(1, 2))};
-  {
-    RenderPassList pass_list;
-    AddPasses(&pass_list,
-              gfx::Rect(SurfaceSize()),
-              root_passes,
-              arraysize(root_passes));
-    pass_list[0]->copy_requests.push_back(copy_request.Pass());
-    pass_list[1]->copy_requests.push_back(copy_request2.Pass());
-
-    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-    pass_list.swap(frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-    frame->delegated_frame_data = frame_data.Pass();
-
-    factory_.SubmitFrame(root_surface_id_, frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads)),
-      test::Pass(root_quads2, arraysize(root_quads2))};
-  TestPassesMatchExpectations(expected_passes,
-                              arraysize(expected_passes),
-                              &frame_data->render_pass_list);
-  ASSERT_EQ(2u, frame_data->render_pass_list.size());
-  ASSERT_EQ(1u, frame_data->render_pass_list[0]->copy_requests.size());
-  DCHECK_EQ(copy_request_ptr,
-            frame_data->render_pass_list[0]->copy_requests[0]);
-  ASSERT_EQ(1u, frame_data->render_pass_list[1]->copy_requests.size());
-  DCHECK_EQ(copy_request2_ptr,
-            frame_data->render_pass_list[1]->copy_requests[0]);
-
-  SurfaceId surface_ids[] = {root_surface_id_, embedded_surface_id};
-  EXPECT_EQ(arraysize(surface_ids),
-            aggregator_.previous_contained_surfaces().size());
-  for (size_t i = 0; i < arraysize(surface_ids); i++) {
-    EXPECT_TRUE(
-        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-        aggregator_.previous_contained_surfaces().end());
-  }
-
-  // Ensure copy requests have been removed from root surface.
-  const CompositorFrame* original_frame =
-      manager_.GetSurfaceForId(root_surface_id_)->GetEligibleFrame();
-  RenderPassList& original_pass_list =
-      original_frame->delegated_frame_data->render_pass_list;
-  ASSERT_EQ(2u, original_pass_list.size());
-  DCHECK(original_pass_list[0]->copy_requests.empty());
-  DCHECK(original_pass_list[1]->copy_requests.empty());
-
-  factory_.Destroy(embedded_surface_id);
-}
-
-// This tests referencing a surface that has multiple render passes.
-TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
-  SurfaceId embedded_surface_id = child_allocator_.GenerateId();
-  factory_.Create(embedded_surface_id);
-
-  RenderPassId pass_ids[] = {RenderPassId(1, 1), RenderPassId(1, 2),
-                             RenderPassId(1, 3)};
-
-  test::Quad embedded_quads[][2] = {
-      {test::Quad::SolidColorQuad(1), test::Quad::SolidColorQuad(2)},
-      {test::Quad::SolidColorQuad(3), test::Quad::RenderPassQuad(pass_ids[0])},
-      {test::Quad::SolidColorQuad(4), test::Quad::RenderPassQuad(pass_ids[1])}};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads[0], arraysize(embedded_quads[0]), pass_ids[0]),
-      test::Pass(embedded_quads[1], arraysize(embedded_quads[1]), pass_ids[1]),
-      test::Pass(embedded_quads[2], arraysize(embedded_quads[2]), pass_ids[2])};
-
-  SubmitFrame(embedded_passes, arraysize(embedded_passes), embedded_surface_id);
-
-  test::Quad root_quads[][2] = {
-      {test::Quad::SolidColorQuad(5), test::Quad::SolidColorQuad(6)},
-      {test::Quad::SurfaceQuad(embedded_surface_id, 1.f),
-       test::Quad::RenderPassQuad(pass_ids[0])},
-      {test::Quad::SolidColorQuad(7), test::Quad::RenderPassQuad(pass_ids[1])}};
-  test::Pass root_passes[] = {
-      test::Pass(root_quads[0], arraysize(root_quads[0]), pass_ids[0]),
-      test::Pass(root_quads[1], arraysize(root_quads[1]), pass_ids[1]),
-      test::Pass(root_quads[2], arraysize(root_quads[2]), pass_ids[2])};
-
-  SubmitFrame(root_passes, arraysize(root_passes), root_surface_id_);
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-  ASSERT_EQ(5u, aggregated_pass_list.size());
-  RenderPassId actual_pass_ids[] = {
-      aggregated_pass_list[0]->id, aggregated_pass_list[1]->id,
-      aggregated_pass_list[2]->id, aggregated_pass_list[3]->id,
-      aggregated_pass_list[4]->id};
-  for (size_t i = 0; i < 5; ++i) {
-    for (size_t j = 0; j < i; ++j) {
-      EXPECT_NE(actual_pass_ids[i], actual_pass_ids[j]);
-    }
-  }
-
-  {
-    SCOPED_TRACE("First pass");
-    // The first pass will just be the first pass from the root surfaces quad
-    // with no render pass quads to remap.
-    TestPassMatchesExpectations(root_passes[0], aggregated_pass_list[0]);
-  }
-
-  {
-    SCOPED_TRACE("Second pass");
-    // The next two passes will be from the embedded surface since we have to
-    // draw those passes before they are referenced from the render pass draw
-    // quad embedded into the root surface's second pass.
-    // First, there's the first embedded pass which doesn't reference anything
-    // else.
-    TestPassMatchesExpectations(embedded_passes[0], aggregated_pass_list[1]);
-  }
-
-  {
-    SCOPED_TRACE("Third pass");
-    const QuadList& third_pass_quad_list = aggregated_pass_list[2]->quad_list;
-    ASSERT_EQ(2u, third_pass_quad_list.size());
-    TestQuadMatchesExpectations(embedded_quads[1][0],
-                                third_pass_quad_list.ElementAt(0));
-
-    // This render pass pass quad will reference the first pass from the
-    // embedded surface, which is the second pass in the aggregated frame.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              third_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* third_pass_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(third_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[1],
-              third_pass_render_pass_draw_quad->render_pass_id);
-  }
-
-  {
-    SCOPED_TRACE("Fourth pass");
-    // The fourth pass will have aggregated quads from the root surface's second
-    // pass and the embedded surface's first pass.
-    const QuadList& fourth_pass_quad_list = aggregated_pass_list[3]->quad_list;
-    ASSERT_EQ(3u, fourth_pass_quad_list.size());
-
-    // The first quad will be the yellow quad from the embedded surface's last
-    // pass.
-    TestQuadMatchesExpectations(embedded_quads[2][0],
-                                fourth_pass_quad_list.ElementAt(0));
-
-    // The next quad will be a render pass quad referencing the second pass from
-    // the embedded surface, which is the third pass in the aggregated frame.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fourth_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* fourth_pass_first_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[2],
-              fourth_pass_first_render_pass_draw_quad->render_pass_id);
-
-    // The last quad will be a render pass quad referencing the first pass from
-    // the root surface, which is the first pass overall.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fourth_pass_quad_list.ElementAt(2)->material);
-    const RenderPassDrawQuad* fourth_pass_second_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.ElementAt(2));
-    EXPECT_EQ(actual_pass_ids[0],
-              fourth_pass_second_render_pass_draw_quad->render_pass_id);
-  }
-
-  {
-    SCOPED_TRACE("Fifth pass");
-    const QuadList& fifth_pass_quad_list = aggregated_pass_list[4]->quad_list;
-    ASSERT_EQ(2u, fifth_pass_quad_list.size());
-
-    TestQuadMatchesExpectations(root_quads[2][0],
-                                fifth_pass_quad_list.ElementAt(0));
-
-    // The last quad in the last pass will reference the second pass from the
-    // root surface, which after aggregating is the fourth pass in the overall
-    // list.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fifth_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* fifth_pass_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fifth_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[3],
-              fifth_pass_render_pass_draw_quad->render_pass_id);
-  }
-  factory_.Destroy(embedded_surface_id);
-}
-
-// Tests an invalid surface reference in a frame. The surface quad should just
-// be dropped.
-TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
-  test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                        test::Quad::SurfaceQuad(InvalidSurfaceId(), 1.f),
-                        test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  SurfaceId ids[] = {root_surface_id_, InvalidSurfaceId()};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests a reference to a valid surface with no submitted frame. This quad
-// should also just be dropped.
-TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
-  SurfaceId surface_with_no_frame_id = allocator_.GenerateId();
-  factory_.Create(surface_with_no_frame_id);
-  test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                        test::Quad::SurfaceQuad(surface_with_no_frame_id, 1.f),
-                        test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  SurfaceId ids[] = {root_surface_id_, surface_with_no_frame_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-  factory_.Destroy(surface_with_no_frame_id);
-}
-
-// Tests a surface quad referencing itself, generating a trivial cycle.
-// The quad creating the cycle should be dropped from the final frame.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
-  test::Quad quads[] = {test::Quad::SurfaceQuad(root_surface_id_, 1.f),
-                        test::Quad::SolidColorQuad(SK_ColorYELLOW)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitFrame(passes, arraysize(passes), root_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorYELLOW)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  SurfaceId ids[] = {root_surface_id_};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests a more complex cycle with one intermediate surface.
-TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
-  SurfaceId child_surface_id = allocator_.GenerateId();
-  factory_.Create(child_surface_id);
-
-  test::Quad parent_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
-                               test::Quad::SurfaceQuad(child_surface_id, 1.f),
-                               test::Quad::SolidColorQuad(SK_ColorCYAN)};
-  test::Pass parent_passes[] = {
-      test::Pass(parent_quads, arraysize(parent_quads))};
-
-  SubmitFrame(parent_passes, arraysize(parent_passes), root_surface_id_);
-
-  test::Quad child_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                              test::Quad::SurfaceQuad(root_surface_id_, 1.f),
-                              test::Quad::SolidColorQuad(SK_ColorMAGENTA)};
-  test::Pass child_passes[] = {test::Pass(child_quads, arraysize(child_quads))};
-
-  SubmitFrame(child_passes, arraysize(child_passes), child_surface_id);
-
-  // The child surface's reference to the root_surface_ will be dropped, so
-  // we'll end up with:
-  //   SK_ColorBLUE from the parent
-  //   SK_ColorGREEN from the child
-  //   SK_ColorMAGENTA from the child
-  //   SK_ColorCYAN from the parent
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorMAGENTA),
-                                 test::Quad::SolidColorQuad(SK_ColorCYAN)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  SurfaceId ids[] = {root_surface_id_, child_surface_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-  factory_.Destroy(child_surface_id);
-}
-
-// Tests that we map render pass IDs from different surfaces into a unified
-// namespace and update RenderPassDrawQuad's id references to match.
-TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
-  SurfaceId child_surface_id = allocator_.GenerateId();
-  factory_.Create(child_surface_id);
-
-  RenderPassId child_pass_id[] = {RenderPassId(1, 1), RenderPassId(1, 2)};
-  test::Quad child_quad[][1] = {{test::Quad::SolidColorQuad(SK_ColorGREEN)},
-                                {test::Quad::RenderPassQuad(child_pass_id[0])}};
-  test::Pass surface_passes[] = {
-      test::Pass(child_quad[0], arraysize(child_quad[0]), child_pass_id[0]),
-      test::Pass(child_quad[1], arraysize(child_quad[1]), child_pass_id[1])};
-
-  SubmitFrame(surface_passes, arraysize(surface_passes), child_surface_id);
-
-  // Pass IDs from the parent surface may collide with ones from the child.
-  RenderPassId parent_pass_id[] = {RenderPassId(2, 1), RenderPassId(1, 2)};
-  test::Quad parent_quad[][1] = {
-      {test::Quad::SurfaceQuad(child_surface_id, 1.f)},
-      {test::Quad::RenderPassQuad(parent_pass_id[0])}};
-  test::Pass parent_passes[] = {
-      test::Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]),
-      test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])};
-
-  SubmitFrame(parent_passes, arraysize(parent_passes), root_surface_id_);
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-  ASSERT_EQ(3u, aggregated_pass_list.size());
-  RenderPassId actual_pass_ids[] = {aggregated_pass_list[0]->id,
-                                    aggregated_pass_list[1]->id,
-                                    aggregated_pass_list[2]->id};
-  // Make sure the aggregated frame's pass IDs are all unique.
-  for (size_t i = 0; i < 3; ++i) {
-    for (size_t j = 0; j < i; ++j) {
-      EXPECT_NE(actual_pass_ids[j], actual_pass_ids[i]) << "pass ids " << i
-                                                        << " and " << j;
-    }
-  }
-
-  // Make sure the render pass quads reference the remapped pass IDs.
-  DrawQuad* render_pass_quads[] = {aggregated_pass_list[1]->quad_list.front(),
-                                   aggregated_pass_list[2]->quad_list.front()};
-  ASSERT_EQ(render_pass_quads[0]->material, DrawQuad::RENDER_PASS);
-  EXPECT_EQ(
-      actual_pass_ids[0],
-      RenderPassDrawQuad::MaterialCast(render_pass_quads[0])->render_pass_id);
-
-  ASSERT_EQ(render_pass_quads[1]->material, DrawQuad::RENDER_PASS);
-  EXPECT_EQ(
-      actual_pass_ids[1],
-      RenderPassDrawQuad::MaterialCast(render_pass_quads[1])->render_pass_id);
-  factory_.Destroy(child_surface_id);
-}
-
-void AddSolidColorQuadWithBlendMode(const gfx::Size& size,
-                                    RenderPass* pass,
-                                    const SkXfermode::Mode blend_mode) {
-  const gfx::Transform content_to_target_transform;
-  const gfx::Size content_bounds(size);
-  const gfx::Rect visible_content_rect(size);
-  const gfx::Rect clip_rect(size);
-
-  bool is_clipped = false;
-  float opacity = 1.f;
-
-  bool force_anti_aliasing_off = false;
-  SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-  sqs->SetAll(content_to_target_transform,
-              content_bounds,
-              visible_content_rect,
-              clip_rect,
-              is_clipped,
-              opacity,
-              blend_mode,
-              0);
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(pass->shared_quad_state_list.back(),
-                     visible_content_rect,
-                     visible_content_rect,
-                     SK_ColorGREEN,
-                     force_anti_aliasing_off);
-}
-
-// This tests that we update shared quad state pointers correctly within
-// aggregated passes.  The shared quad state list on the aggregated pass will
-// include the shared quad states from each pass in one list so the quads will
-// end up pointed to shared quad state objects at different offsets. This test
-// uses the blend_mode value stored on the shared quad state to track the shared
-// quad state, but anything saved on the shared quad state would work.
-//
-// This test has 4 surfaces in the following structure:
-// root_surface -> quad with kClear_Mode,
-//                 [child_one_surface],
-//                 quad with kDstOver_Mode,
-//                 [child_two_surface],
-//                 quad with kDstIn_Mode
-// child_one_surface -> quad with kSrc_Mode,
-//                      [grandchild_surface],
-//                      quad with kSrcOver_Mode
-// child_two_surface -> quad with kSrcIn_Mode
-// grandchild_surface -> quad with kDst_Mode
-//
-// Resulting in the following aggregated pass:
-//  quad_root_0       - blend_mode kClear_Mode
-//  quad_child_one_0  - blend_mode kSrc_Mode
-//  quad_grandchild_0 - blend_mode kDst_Mode
-//  quad_child_one_1  - blend_mode kSrcOver_Mode
-//  quad_root_1       - blend_mode kDstOver_Mode
-//  quad_child_two_0  - blend_mode kSrcIn_Mode
-//  quad_root_2       - blend_mode kDstIn_Mode
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
-  const SkXfermode::Mode blend_modes[] = {SkXfermode::kClear_Mode,    // 0
-                                          SkXfermode::kSrc_Mode,      // 1
-                                          SkXfermode::kDst_Mode,      // 2
-                                          SkXfermode::kSrcOver_Mode,  // 3
-                                          SkXfermode::kDstOver_Mode,  // 4
-                                          SkXfermode::kSrcIn_Mode,    // 5
-                                          SkXfermode::kDstIn_Mode,    // 6
-  };
-
-  RenderPassId pass_id(1, 1);
-  SurfaceId grandchild_surface_id = allocator_.GenerateId();
-  factory_.Create(grandchild_surface_id);
-  scoped_ptr<RenderPass> grandchild_pass = RenderPass::Create();
-  gfx::Rect output_rect(SurfaceSize());
-  gfx::Rect damage_rect(SurfaceSize());
-  gfx::Transform transform_to_root_target;
-  grandchild_pass->SetNew(
-      pass_id, output_rect, damage_rect, transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), grandchild_pass.get(), blend_modes[2]);
-  QueuePassAsFrame(grandchild_pass.Pass(), grandchild_surface_id);
-
-  SurfaceId child_one_surface_id = allocator_.GenerateId();
-  factory_.Create(child_one_surface_id);
-
-  scoped_ptr<RenderPass> child_one_pass = RenderPass::Create();
-  child_one_pass->SetNew(
-      pass_id, output_rect, damage_rect, transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_one_pass.get(), blend_modes[1]);
-  SurfaceDrawQuad* grandchild_surface_quad =
-      child_one_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  grandchild_surface_quad->SetNew(child_one_pass->shared_quad_state_list.back(),
-                                  gfx::Rect(SurfaceSize()),
-                                  gfx::Rect(SurfaceSize()),
-                                  grandchild_surface_id);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_one_pass.get(), blend_modes[3]);
-  QueuePassAsFrame(child_one_pass.Pass(), child_one_surface_id);
-
-  SurfaceId child_two_surface_id = allocator_.GenerateId();
-  factory_.Create(child_two_surface_id);
-
-  scoped_ptr<RenderPass> child_two_pass = RenderPass::Create();
-  child_two_pass->SetNew(
-      pass_id, output_rect, damage_rect, transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_two_pass.get(), blend_modes[5]);
-  QueuePassAsFrame(child_two_pass.Pass(), child_two_surface_id);
-
-  scoped_ptr<RenderPass> root_pass = RenderPass::Create();
-  root_pass->SetNew(
-      pass_id, output_rect, damage_rect, transform_to_root_target);
-
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[0]);
-  SurfaceDrawQuad* child_one_surface_quad =
-      root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_one_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()),
-                                 child_one_surface_id);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[4]);
-  SurfaceDrawQuad* child_two_surface_quad =
-      root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_two_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()),
-                                 child_two_surface_id);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[6]);
-
-  QueuePassAsFrame(root_pass.Pass(), root_surface_id_);
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-  ASSERT_EQ(1u, aggregated_pass_list.size());
-
-  const QuadList& aggregated_quad_list = aggregated_pass_list[0]->quad_list;
-
-  ASSERT_EQ(7u, aggregated_quad_list.size());
-
-  for (auto iter = aggregated_quad_list.cbegin();
-       iter != aggregated_quad_list.cend();
-       ++iter) {
-    EXPECT_EQ(blend_modes[iter.index()], iter->shared_quad_state->blend_mode)
-        << iter.index();
-  }
-  factory_.Destroy(child_one_surface_id);
-  factory_.Destroy(child_two_surface_id);
-  factory_.Destroy(grandchild_surface_id);
-}
-
-// This tests that when aggregating a frame with multiple render passes that we
-// map the transforms for the root pass but do not modify the transform on child
-// passes.
-//
-// The root surface has one pass with a surface quad transformed by +10 in the y
-// direction.
-//
-// The middle surface has one pass with a surface quad scaled by 2 in the x
-// and 3 in the y directions.
-//
-// The child surface has two passes. The first pass has a quad with a transform
-// of +5 in the x direction. The second pass has a reference to the first pass'
-// pass id and a transform of +8 in the x direction.
-//
-// After aggregation, the child surface's root pass quad should have all
-// transforms concatenated for a total transform of +23 x, +10 y. The
-// contributing render pass' transform in the aggregate frame should not be
-// affected.
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
-  // Innermost child surface.
-  SurfaceId child_surface_id = allocator_.GenerateId();
-  {
-    factory_.Create(child_surface_id);
-    RenderPassId child_pass_id[] = {RenderPassId(1, 1), RenderPassId(1, 2)};
-    test::Quad child_quads[][1] = {
-        {test::Quad::SolidColorQuad(SK_ColorGREEN)},
-        {test::Quad::RenderPassQuad(child_pass_id[0])},
-    };
-    test::Pass child_passes[] = {
-        test::Pass(child_quads[0], arraysize(child_quads[0]), child_pass_id[0]),
-        test::Pass(child_quads[1], arraysize(child_quads[1]),
-                   child_pass_id[1])};
-
-    RenderPassList child_pass_list;
-    AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
-              arraysize(child_passes));
-
-    RenderPass* child_nonroot_pass = child_pass_list.at(0u);
-    child_nonroot_pass->transform_to_root_target.Translate(8, 0);
-    SharedQuadState* child_nonroot_pass_sqs =
-        child_nonroot_pass->shared_quad_state_list.front();
-    child_nonroot_pass_sqs->content_to_target_transform.Translate(5, 0);
-
-    RenderPass* child_root_pass = child_pass_list.at(1u);
-    SharedQuadState* child_root_pass_sqs =
-        child_root_pass->shared_quad_state_list.front();
-    child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
-    child_root_pass_sqs->is_clipped = true;
-    child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5);
-
-    scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData);
-    child_pass_list.swap(child_frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = child_frame_data.Pass();
-
-    factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  // Middle child surface.
-  SurfaceId middle_surface_id = allocator_.GenerateId();
-  {
-    factory_.Create(middle_surface_id);
-    test::Quad middle_quads[] = {
-        test::Quad::SurfaceQuad(child_surface_id, 1.f)};
-    test::Pass middle_passes[] = {
-        test::Pass(middle_quads, arraysize(middle_quads)),
-    };
-
-    RenderPassList middle_pass_list;
-    AddPasses(&middle_pass_list, gfx::Rect(SurfaceSize()), middle_passes,
-              arraysize(middle_passes));
-
-    RenderPass* middle_root_pass = middle_pass_list.at(0u);
-    middle_root_pass->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(0, 1, 100, 7);
-    SharedQuadState* middle_root_pass_sqs =
-        middle_root_pass->shared_quad_state_list.front();
-    middle_root_pass_sqs->content_to_target_transform.Scale(2, 3);
-
-    scoped_ptr<DelegatedFrameData> middle_frame_data(new DelegatedFrameData);
-    middle_pass_list.swap(middle_frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> middle_frame(new CompositorFrame);
-    middle_frame->delegated_frame_data = middle_frame_data.Pass();
-
-    factory_.SubmitFrame(middle_surface_id, middle_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  // Root surface.
-  test::Quad secondary_quads[] = {
-      test::Quad::SolidColorQuad(1),
-      test::Quad::SurfaceQuad(middle_surface_id, 1.f)};
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(1)};
-  test::Pass root_passes[] = {
-      test::Pass(secondary_quads, arraysize(secondary_quads)),
-      test::Pass(root_quads, arraysize(root_quads))};
-
-  RenderPassList root_pass_list;
-  AddPasses(&root_pass_list,
-            gfx::Rect(SurfaceSize()),
-            root_passes,
-            arraysize(root_passes));
-
-  root_pass_list.at(0)
-      ->shared_quad_state_list.front()
-      ->content_to_target_transform.Translate(0, 7);
-  root_pass_list.at(0)
-      ->shared_quad_state_list.ElementAt(1)
-      ->content_to_target_transform.Translate(0, 10);
-  root_pass_list.at(0)->quad_list.ElementAt(1)->visible_rect =
-      gfx::Rect(0, 0, 8, 100);
-
-  root_pass_list[0]->transform_to_root_target.Translate(10, 5);
-
-  scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
-  root_pass_list.swap(root_frame_data->render_pass_list);
-
-  scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-  root_frame->delegated_frame_data = root_frame_data.Pass();
-
-  factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-  ASSERT_EQ(3u, aggregated_pass_list.size());
-
-  ASSERT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
-
-  // The first pass should have one shared quad state for the one solid color
-  // quad.
-  EXPECT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
-  // The second pass should have just two shared quad states. We'll
-  // verify the properties through the quads.
-  EXPECT_EQ(2u, aggregated_pass_list[1]->shared_quad_state_list.size());
-
-  EXPECT_EQ(1u, aggregated_pass_list[2]->shared_quad_state_list.size());
-
-  SharedQuadState* aggregated_first_pass_sqs =
-      aggregated_pass_list[0]->shared_quad_state_list.front();
-
-  // The first pass's transform should be unaffected by the embedding and still
-  // be a translation by +5 in the x direction.
-  gfx::Transform expected_aggregated_first_pass_sqs_transform;
-  expected_aggregated_first_pass_sqs_transform.Translate(5, 0);
-  EXPECT_EQ(expected_aggregated_first_pass_sqs_transform.ToString(),
-            aggregated_first_pass_sqs->content_to_target_transform.ToString());
-
-  // The first pass's transform to the root target should include the aggregated
-  // transform, including the transform from the child pass to the root.
-  gfx::Transform expected_first_pass_transform_to_root_target;
-  expected_first_pass_transform_to_root_target.Translate(10, 5);
-  expected_first_pass_transform_to_root_target.Translate(0, 10);
-  expected_first_pass_transform_to_root_target.Scale(2, 3);
-  expected_first_pass_transform_to_root_target.Translate(8, 0);
-  EXPECT_EQ(expected_first_pass_transform_to_root_target.ToString(),
-            aggregated_pass_list[0]->transform_to_root_target.ToString());
-
-  ASSERT_EQ(2u, aggregated_pass_list[1]->quad_list.size());
-
-  gfx::Transform expected_root_pass_quad_transforms[2];
-  // The first quad in the root pass is the solid color quad from the original
-  // root surface. Its transform should be unaffected by the aggregation and
-  // still be +7 in the y direction.
-  expected_root_pass_quad_transforms[0].Translate(0, 7);
-  // The second quad in the root pass is aggregated from the child surface so
-  // its transform should be the combination of its original translation
-  // (0, 10), the middle surface draw quad's scale of (2, 3), and the
-  // child surface draw quad's translation (8, 0).
-  expected_root_pass_quad_transforms[1].Translate(0, 10);
-  expected_root_pass_quad_transforms[1].Scale(2, 3);
-  expected_root_pass_quad_transforms[1].Translate(8, 0);
-
-  for (auto iter = aggregated_pass_list[1]->quad_list.cbegin();
-       iter != aggregated_pass_list[1]->quad_list.cend();
-       ++iter) {
-    EXPECT_EQ(expected_root_pass_quad_transforms[iter.index()].ToString(),
-              iter->quadTransform().ToString())
-        << iter.index();
-  }
-
-  EXPECT_TRUE(
-      aggregated_pass_list[1]->shared_quad_state_list.ElementAt(1)->is_clipped);
-
-  // The second quad in the root pass is aggregated from the child, so its
-  // clip rect must be transformed by the child's translation/scale and
-  // clipped be the visible_rects for both children.
-  EXPECT_EQ(gfx::Rect(0, 13, 8, 12).ToString(),
-            aggregated_pass_list[1]
-                ->shared_quad_state_list.ElementAt(1)
-                ->clip_rect.ToString());
-
-  factory_.Destroy(middle_surface_id);
-  factory_.Destroy(child_surface_id);
-}
-
-// Tests that damage rects are aggregated correctly when surfaces change.
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
-  SurfaceId child_surface_id = allocator_.GenerateId();
-  factory_.Create(child_surface_id);
-  RenderPassId child_pass_id = RenderPassId(1, 1);
-  test::Quad child_quads[] = {test::Quad::RenderPassQuad(child_pass_id)};
-  test::Pass child_passes[] = {
-      test::Pass(child_quads, arraysize(child_quads), child_pass_id)};
-
-  RenderPassList child_pass_list;
-  AddPasses(&child_pass_list,
-            gfx::Rect(SurfaceSize()),
-            child_passes,
-            arraysize(child_passes));
-
-  RenderPass* child_root_pass = child_pass_list.at(0u);
-  SharedQuadState* child_root_pass_sqs =
-      child_root_pass->shared_quad_state_list.front();
-  child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
-
-  scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData);
-  child_pass_list.swap(child_frame_data->render_pass_list);
-
-  scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-  child_frame->delegated_frame_data = child_frame_data.Pass();
-
-  factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-
-  RenderPassId pass_id(5, 10);
-  test::Quad first_quads[] = {test::Quad::SurfaceQuad(child_surface_id, 1.f)};
-  test::Quad root_quads[] = {test::Quad::RenderPassQuad(pass_id)};
-
-  test::Pass root_passes[] = {
-      test::Pass(first_quads, arraysize(first_quads), pass_id),
-      test::Pass(root_quads, arraysize(root_quads))};
-
-  RenderPassList root_pass_list;
-  AddPasses(&root_pass_list,
-            gfx::Rect(SurfaceSize()),
-            root_passes,
-            arraysize(root_passes));
-
-  root_pass_list.at(0)
-      ->shared_quad_state_list.front()
-      ->content_to_target_transform.Translate(0, 10);
-  root_pass_list.at(0)->damage_rect = gfx::Rect(5, 5, 10, 10);
-  root_pass_list.at(1)->damage_rect = gfx::Rect(5, 5, 100, 100);
-
-  scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
-  root_pass_list.swap(root_frame_data->render_pass_list);
-
-  scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-  root_frame->delegated_frame_data = root_frame_data.Pass();
-
-  factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator_.Aggregate(root_surface_id_);
-
-  ASSERT_TRUE(aggregated_frame);
-  ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-  DelegatedFrameData* frame_data = aggregated_frame->delegated_frame_data.get();
-
-  const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-  ASSERT_EQ(2u, aggregated_pass_list.size());
-
-  // Damage rect for first aggregation should contain entire root surface.
-  EXPECT_TRUE(
-      aggregated_pass_list[1]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
-
-  {
-    AddPasses(&child_pass_list,
-              gfx::Rect(SurfaceSize()),
-              child_passes,
-              arraysize(child_passes));
-
-    RenderPass* child_root_pass = child_pass_list.at(0u);
-    SharedQuadState* child_root_pass_sqs =
-        child_root_pass->shared_quad_state_list.front();
-    child_root_pass_sqs->content_to_target_transform.Translate(8, 0);
-    child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10);
-
-    scoped_ptr<DelegatedFrameData> child_frame_data(new DelegatedFrameData);
-    child_pass_list.swap(child_frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = child_frame_data.Pass();
-
-    factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-
-    scoped_ptr<CompositorFrame> aggregated_frame =
-        aggregator_.Aggregate(root_surface_id_);
-
-    ASSERT_TRUE(aggregated_frame);
-    ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-    DelegatedFrameData* frame_data =
-        aggregated_frame->delegated_frame_data.get();
-
-    const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    // Outer surface didn't change, so transformed inner damage rect should be
-    // used.
-    EXPECT_EQ(gfx::Rect(10, 20, 10, 10).ToString(),
-              aggregated_pass_list[1]->damage_rect.ToString());
-  }
-
-  {
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list,
-              gfx::Rect(SurfaceSize()),
-              root_passes,
-              arraysize(root_passes));
-
-    root_pass_list.at(0)
-        ->shared_quad_state_list.front()
-        ->content_to_target_transform.Translate(0, 10);
-    root_pass_list.at(0)->damage_rect = gfx::Rect(0, 0, 1, 1);
-
-    scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
-    root_pass_list.swap(root_frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-    root_frame->delegated_frame_data = root_frame_data.Pass();
-
-    factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  {
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list,
-              gfx::Rect(SurfaceSize()),
-              root_passes,
-              arraysize(root_passes));
-
-    root_pass_list.at(0)
-        ->shared_quad_state_list.front()
-        ->content_to_target_transform.Translate(0, 10);
-    root_pass_list.at(0)->damage_rect = gfx::Rect(1, 1, 1, 1);
-
-    scoped_ptr<DelegatedFrameData> root_frame_data(new DelegatedFrameData);
-    root_pass_list.swap(root_frame_data->render_pass_list);
-
-    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-    root_frame->delegated_frame_data = root_frame_data.Pass();
-
-    factory_.SubmitFrame(root_surface_id_, root_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-
-    scoped_ptr<CompositorFrame> aggregated_frame =
-        aggregator_.Aggregate(root_surface_id_);
-
-    ASSERT_TRUE(aggregated_frame);
-    ASSERT_TRUE(aggregated_frame->delegated_frame_data);
-
-    DelegatedFrameData* frame_data =
-        aggregated_frame->delegated_frame_data.get();
-
-    const RenderPassList& aggregated_pass_list = frame_data->render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    // The root surface was enqueued without being aggregated once, so it should
-    // be treated as completely damaged.
-    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains(
-        gfx::Rect(SurfaceSize())));
-  }
-
-  factory_.Destroy(child_surface_id);
-}
-
-class SurfaceAggregatorWithResourcesTest : public testing::Test {
- public:
-  void SetUp() override {
-    output_surface_ = FakeOutputSurface::CreateSoftware(
-        make_scoped_ptr(new SoftwareOutputDevice));
-    output_surface_->BindToClient(&output_surface_client_);
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-
-    resource_provider_ = ResourceProvider::Create(output_surface_.get(),
-                                                  shared_bitmap_manager_.get(),
-                                                  NULL,
-                                                  NULL,
-                                                  0,
-                                                  false,
-                                                  1);
-
-    aggregator_.reset(
-        new SurfaceAggregator(&manager_, resource_provider_.get()));
-  }
-
- protected:
-  SurfaceManager manager_;
-  FakeOutputSurfaceClient output_surface_client_;
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<SurfaceAggregator> aggregator_;
-};
-
-class ResourceTrackingSurfaceFactoryClient : public SurfaceFactoryClient {
- public:
-  ResourceTrackingSurfaceFactoryClient() {}
-  ~ResourceTrackingSurfaceFactoryClient() override {}
-
-  void ReturnResources(const ReturnedResourceArray& resources) override {
-    returned_resources_ = resources;
-  }
-
-  ReturnedResourceArray returned_resources() const {
-    return returned_resources_;
-  }
-
- private:
-  ReturnedResourceArray returned_resources_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceTrackingSurfaceFactoryClient);
-};
-
-void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids,
-                              size_t num_resource_ids,
-                              SurfaceFactory* factory,
-                              SurfaceId surface_id) {
-  scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  pass->id = RenderPassId(1, 1);
-  SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-  for (size_t i = 0u; i < num_resource_ids; ++i) {
-    TransferableResource resource;
-    resource.id = resource_ids[i];
-    resource.is_software = true;
-    frame_data->resource_list.push_back(resource);
-    TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-    const gfx::Rect rect;
-    const gfx::Rect opaque_rect;
-    const gfx::Rect visible_rect;
-    bool needs_blending = false;
-    bool premultiplied_alpha = false;
-    const gfx::PointF uv_top_left;
-    const gfx::PointF uv_bottom_right;
-    SkColor background_color = SK_ColorGREEN;
-    const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
-    bool flipped = false;
-    bool nearest_neighbor = false;
-    quad->SetAll(sqs,
-                 rect,
-                 opaque_rect,
-                 visible_rect,
-                 needs_blending,
-                 resource_ids[i],
-                 premultiplied_alpha,
-                 uv_top_left,
-                 uv_bottom_right,
-                 background_color,
-                 vertex_opacity,
-                 flipped,
-                 nearest_neighbor);
-
-    quad->shared_quad_state = sqs;
-  }
-  frame_data->render_pass_list.push_back(pass.Pass());
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->delegated_frame_data = frame_data.Pass();
-  factory->SubmitFrame(surface_id, frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
-  ResourceTrackingSurfaceFactoryClient client;
-  SurfaceFactory factory(&manager_, &client);
-  SurfaceId surface_id(7u);
-  factory.Create(surface_id);
-
-  ResourceProvider::ResourceId ids[] = {11, 12, 13};
-  SubmitFrameWithResources(ids, arraysize(ids), &factory, surface_id);
-
-  scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  SubmitFrameWithResources(NULL, 0u, &factory, surface_id);
-
-  frame = aggregator_->Aggregate(surface_id);
-
-  ASSERT_EQ(3u, client.returned_resources().size());
-  ResourceProvider::ResourceId returned_ids[3];
-  for (size_t i = 0; i < 3; ++i) {
-    returned_ids[i] = client.returned_resources()[i].id;
-  }
-  EXPECT_THAT(returned_ids,
-              testing::WhenSorted(testing::ElementsAreArray(ids)));
-  factory.Destroy(surface_id);
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) {
-  ResourceTrackingSurfaceFactoryClient client;
-  SurfaceFactory factory(&manager_, &client);
-  SurfaceId surface_id(7u);
-  factory.Create(surface_id);
-
-  scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  pass->id = RenderPassId(1, 1);
-  TransferableResource resource;
-  resource.id = 11;
-  // ResourceProvider is software but resource is not, so it should be
-  // ignored.
-  resource.is_software = false;
-  frame_data->resource_list.push_back(resource);
-  frame_data->render_pass_list.push_back(pass.Pass());
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->delegated_frame_data = frame_data.Pass();
-  factory.SubmitFrame(surface_id, frame.Pass(), SurfaceFactory::DrawCallback());
-
-  scoped_ptr<CompositorFrame> returned_frame =
-      aggregator_->Aggregate(surface_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  SubmitFrameWithResources(NULL, 0u, &factory, surface_id);
-  ASSERT_EQ(1u, client.returned_resources().size());
-  EXPECT_EQ(11u, client.returned_resources()[0].id);
-
-  factory.Destroy(surface_id);
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) {
-  ResourceTrackingSurfaceFactoryClient client;
-  SurfaceFactory factory(&manager_, &client);
-  SurfaceId surface_id(7u);
-  factory.Create(surface_id);
-  SurfaceId surface_id2(8u);
-  factory.Create(surface_id2);
-
-  ResourceProvider::ResourceId ids[] = {11, 12, 13};
-  SubmitFrameWithResources(ids, arraysize(ids), &factory, surface_id);
-  ResourceProvider::ResourceId ids2[] = {14, 15, 16};
-  SubmitFrameWithResources(ids2, arraysize(ids2), &factory, surface_id2);
-
-  scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(surface_id);
-
-  SubmitFrameWithResources(NULL, 0, &factory, surface_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  frame = aggregator_->Aggregate(surface_id2);
-
-  // surface_id wasn't referenced, so its resources should be returned.
-  ASSERT_EQ(3u, client.returned_resources().size());
-  ResourceProvider::ResourceId returned_ids[3];
-  for (size_t i = 0; i < 3; ++i) {
-    returned_ids[i] = client.returned_resources()[i].id;
-  }
-  EXPECT_THAT(returned_ids,
-              testing::WhenSorted(testing::ElementsAreArray(ids)));
-  EXPECT_EQ(3u, resource_provider_->num_resources());
-  factory.Destroy(surface_id);
-  factory.Destroy(surface_id2);
-}
-
-}  // namespace
-}  // namespace cc
-
diff --git a/cc/surfaces/surface_damage_observer.h b/cc/surfaces/surface_damage_observer.h
deleted file mode 100644
index 62ee012..0000000
--- a/cc/surfaces/surface_damage_observer.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
-#define CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
-
-#include "cc/surfaces/surface_id.h"
-
-namespace cc {
-
-class SurfaceDamageObserver {
- public:
-  // Runs when a Surface is damaged. *changed should be set to true if this
-  // causes a Display to be damaged.
-  virtual void OnSurfaceDamaged(SurfaceId surface_id, bool* changed) = 0;
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_
diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc
deleted file mode 100644
index 0493724..0000000
--- a/cc/surfaces/surface_display_output_surface.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_display_output_surface.h"
-
-#include "base/bind.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/onscreen_display_client.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_manager.h"
-
-namespace cc {
-
-SurfaceDisplayOutputSurface::SurfaceDisplayOutputSurface(
-    SurfaceManager* surface_manager,
-    SurfaceIdAllocator* allocator,
-    const scoped_refptr<ContextProvider>& context_provider)
-    : OutputSurface(context_provider),
-      display_client_(NULL),
-      surface_manager_(surface_manager),
-      factory_(surface_manager, this),
-      allocator_(allocator) {
-  capabilities_.delegated_rendering = true;
-  capabilities_.max_frames_pending = 1;
-  capabilities_.adjust_deadline_for_parent = true;
-  capabilities_.can_force_reclaim_resources = true;
-}
-
-SurfaceDisplayOutputSurface::~SurfaceDisplayOutputSurface() {
-  client_ = NULL;
-  if (!surface_id_.is_null()) {
-    factory_.Destroy(surface_id_);
-  }
-}
-
-void SurfaceDisplayOutputSurface::ReceivedVSyncParameters(
-    base::TimeTicks timebase,
-    base::TimeDelta interval) {
-  CommitVSyncParameters(timebase, interval);
-}
-
-void SurfaceDisplayOutputSurface::SwapBuffers(CompositorFrame* frame) {
-  gfx::Size frame_size =
-      frame->delegated_frame_data->render_pass_list.back()->output_rect.size();
-  if (frame_size.IsEmpty() || frame_size != display_size_) {
-    if (!surface_id_.is_null()) {
-      factory_.Destroy(surface_id_);
-    }
-    surface_id_ = allocator_->GenerateId();
-    factory_.Create(surface_id_);
-    display_size_ = frame_size;
-  }
-  display_client_->display()->SetSurfaceId(surface_id_,
-                                           frame->metadata.device_scale_factor);
-
-  scoped_ptr<CompositorFrame> frame_copy(new CompositorFrame());
-  frame->AssignTo(frame_copy.get());
-  factory_.SubmitFrame(
-      surface_id_, frame_copy.Pass(),
-      base::Bind(&SurfaceDisplayOutputSurface::SwapBuffersComplete,
-                 base::Unretained(this)));
-
-  client_->DidSwapBuffers();
-}
-
-bool SurfaceDisplayOutputSurface::BindToClient(OutputSurfaceClient* client) {
-  DCHECK(client);
-  DCHECK(display_client_);
-  client_ = client;
-  // Avoid initializing GL context here, as this should be sharing the
-  // Display's context.
-  return display_client_->Initialize();
-}
-
-void SurfaceDisplayOutputSurface::ForceReclaimResources() {
-  if (!surface_id_.is_null()) {
-    scoped_ptr<CompositorFrame> empty_frame(new CompositorFrame());
-    empty_frame->delegated_frame_data.reset(new DelegatedFrameData);
-    factory_.SubmitFrame(surface_id_, empty_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-}
-
-void SurfaceDisplayOutputSurface::ReturnResources(
-    const ReturnedResourceArray& resources) {
-  CompositorFrameAck ack;
-  ack.resources = resources;
-  if (client_)
-    client_->ReclaimResources(&ack);
-}
-
-void SurfaceDisplayOutputSurface::SwapBuffersComplete(SurfaceDrawStatus drawn) {
-  if (client_ && !display_client_->output_surface_lost())
-    client_->DidSwapBuffersComplete();
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_display_output_surface.h b/cc/surfaces/surface_display_output_surface.h
deleted file mode 100644
index 99afda6..0000000
--- a/cc/surfaces/surface_display_output_surface.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_DISPLAY_OUTPUT_SURFACE_H_
-#define CC_SURFACES_SURFACE_DISPLAY_OUTPUT_SURFACE_H_
-
-#include "cc/output/output_surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_factory_client.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-class Display;
-class OnscreenDisplayClient;
-class SurfaceManager;
-
-// This class is maps a compositor OutputSurface to the surface system's Display
-// concept, allowing a compositor client to submit frames for a native root
-// window or physical display.
-class CC_SURFACES_EXPORT SurfaceDisplayOutputSurface
-    : public OutputSurface,
-      public SurfaceFactoryClient {
- public:
-  // The underlying Display and SurfaceManager must outlive this class.
-  SurfaceDisplayOutputSurface(
-      SurfaceManager* surface_manager,
-      SurfaceIdAllocator* allocator,
-      const scoped_refptr<ContextProvider>& context_provider);
-  ~SurfaceDisplayOutputSurface() override;
-
-  void set_display_client(OnscreenDisplayClient* display_client) {
-    display_client_ = display_client;
-  }
-  SurfaceFactory* factory() { return &factory_; }
-  void ReceivedVSyncParameters(base::TimeTicks timebase,
-                               base::TimeDelta interval);
-
-  // OutputSurface implementation.
-  void SwapBuffers(CompositorFrame* frame) override;
-  bool BindToClient(OutputSurfaceClient* client) override;
-  void ForceReclaimResources() override;
-
-  // SurfaceFactoryClient implementation.
-  void ReturnResources(const ReturnedResourceArray& resources) override;
-
- private:
-  void SwapBuffersComplete(SurfaceDrawStatus drawn);
-
-  OnscreenDisplayClient* display_client_;
-  SurfaceManager* surface_manager_;
-  SurfaceFactory factory_;
-  gfx::Size display_size_;
-  SurfaceId surface_id_;
-  SurfaceIdAllocator* allocator_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceDisplayOutputSurface);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_DISPLAY_OUTPUT_SURFACE_H_
diff --git a/cc/surfaces/surface_factory.cc b/cc/surfaces/surface_factory.cc
deleted file mode 100644
index aead4f6..0000000
--- a/cc/surfaces/surface_factory.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_factory.h"
-
-#include "cc/output/compositor_frame.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_manager.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-SurfaceFactory::SurfaceFactory(SurfaceManager* manager,
-                               SurfaceFactoryClient* client)
-    : manager_(manager), client_(client), holder_(client) {
-}
-
-SurfaceFactory::~SurfaceFactory() {
-  if (!surface_map_.empty()) {
-    LOG(ERROR) << "SurfaceFactory has " << surface_map_.size()
-               << " entries in map on destruction.";
-  }
-  DestroyAll();
-}
-
-void SurfaceFactory::DestroyAll() {
-  for (auto it = surface_map_.begin(); it != surface_map_.end(); ++it)
-    manager_->Destroy(surface_map_.take(it));
-  surface_map_.clear();
-}
-
-void SurfaceFactory::Create(SurfaceId surface_id) {
-  scoped_ptr<Surface> surface(new Surface(surface_id, this));
-  manager_->RegisterSurface(surface.get());
-  DCHECK(!surface_map_.count(surface_id));
-  surface_map_.add(surface_id, surface.Pass());
-}
-
-void SurfaceFactory::Destroy(SurfaceId surface_id) {
-  OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
-  DCHECK(it != surface_map_.end());
-  DCHECK(it->second->factory().get() == this);
-  manager_->Destroy(surface_map_.take_and_erase(it));
-}
-
-void SurfaceFactory::SubmitFrame(SurfaceId surface_id,
-                                 scoped_ptr<CompositorFrame> frame,
-                                 const DrawCallback& callback) {
-  OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
-  DCHECK(it != surface_map_.end());
-  DCHECK(it->second->factory().get() == this);
-  it->second->QueueFrame(frame.Pass(), callback);
-  if (!manager_->SurfaceModified(surface_id))
-    it->second->RunDrawCallbacks(SurfaceDrawStatus::DRAW_SKIPPED);
-}
-
-void SurfaceFactory::RequestCopyOfSurface(
-    SurfaceId surface_id,
-    scoped_ptr<CopyOutputRequest> copy_request) {
-  OwningSurfaceMap::iterator it = surface_map_.find(surface_id);
-  if (it == surface_map_.end()) {
-    copy_request->SendEmptyResult();
-    return;
-  }
-  DCHECK(it->second->factory().get() == this);
-  it->second->RequestCopyOfOutput(copy_request.Pass());
-  manager_->SurfaceModified(surface_id);
-}
-
-void SurfaceFactory::ReceiveFromChild(
-    const TransferableResourceArray& resources) {
-  holder_.ReceiveFromChild(resources);
-}
-
-void SurfaceFactory::RefResources(const TransferableResourceArray& resources) {
-  holder_.RefResources(resources);
-}
-
-void SurfaceFactory::UnrefResources(const ReturnedResourceArray& resources) {
-  holder_.UnrefResources(resources);
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_factory.h b/cc/surfaces/surface_factory.h
deleted file mode 100644
index afc0b81..0000000
--- a/cc/surfaces/surface_factory.h
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_FACTORY_H_
-#define CC_SURFACES_SURFACE_FACTORY_H_
-
-#include <set>
-
-#include "base/callback_forward.h"
-#include "base/containers/scoped_ptr_hash_map.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surface_resource_holder.h"
-#include "cc/surfaces/surface_sequence.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace gfx {
-class Size;
-}
-
-namespace cc {
-class CompositorFrame;
-class CopyOutputRequest;
-class Surface;
-class SurfaceFactoryClient;
-class SurfaceManager;
-
-enum class SurfaceDrawStatus { DRAW_SKIPPED, DRAWN };
-
-// A SurfaceFactory is used to create surfaces that may share resources and
-// receive returned resources for frames submitted to those surfaces. Resources
-// submitted to frames created by a particular factory will be returned to that
-// factory's client when they are no longer being used. This is the only class
-// most users of surfaces will need to directly interact with.
-class CC_SURFACES_EXPORT SurfaceFactory
-    : public base::SupportsWeakPtr<SurfaceFactory> {
- public:
-  using DrawCallback = base::Callback<void(SurfaceDrawStatus)>;
-
-  SurfaceFactory(SurfaceManager* manager, SurfaceFactoryClient* client);
-  ~SurfaceFactory();
-
-  void Create(SurfaceId surface_id);
-  void Destroy(SurfaceId surface_id);
-  void DestroyAll();
-  // A frame can only be submitted to a surface created by this factory,
-  // although the frame may reference surfaces created by other factories.
-  // The callback is called the first time this frame is used to draw, or if
-  // the frame is discarded.
-  void SubmitFrame(SurfaceId surface_id,
-                   scoped_ptr<CompositorFrame> frame,
-                   const DrawCallback& callback);
-  void RequestCopyOfSurface(SurfaceId surface_id,
-                            scoped_ptr<CopyOutputRequest> copy_request);
-
-  SurfaceFactoryClient* client() { return client_; }
-
-  void ReceiveFromChild(const TransferableResourceArray& resources);
-  void RefResources(const TransferableResourceArray& resources);
-  void UnrefResources(const ReturnedResourceArray& resources);
-
-  SurfaceManager* manager() { return manager_; }
-
- private:
-  SurfaceManager* manager_;
-  SurfaceFactoryClient* client_;
-  SurfaceResourceHolder holder_;
-
-  typedef base::ScopedPtrHashMap<SurfaceId, scoped_ptr<Surface>> OwningSurfaceMap;
-  OwningSurfaceMap surface_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceFactory);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_FACTORY_H_
diff --git a/cc/surfaces/surface_factory_client.h b/cc/surfaces/surface_factory_client.h
deleted file mode 100644
index 9866b27..0000000
--- a/cc/surfaces/surface_factory_client.h
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_FACTORY_CLIENT_H_
-#define CC_SURFACES_SURFACE_FACTORY_CLIENT_H_
-
-#include "cc/resources/returned_resource.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-
-class CC_SURFACES_EXPORT SurfaceFactoryClient {
- public:
-  virtual ~SurfaceFactoryClient() {}
-
-  virtual void ReturnResources(const ReturnedResourceArray& resources) = 0;
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_FACTORY_CLIENT_H_
diff --git a/cc/surfaces/surface_factory_unittest.cc b/cc/surfaces/surface_factory_unittest.cc
deleted file mode 100644
index b9c6bf5..0000000
--- a/cc/surfaces/surface_factory_unittest.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2014 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.
-
-#include "base/bind.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/delegated_frame_data.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_factory_client.h"
-#include "cc/surfaces/surface_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-namespace {
-
-class TestSurfaceFactoryClient : public SurfaceFactoryClient {
- public:
-  TestSurfaceFactoryClient() {}
-  ~TestSurfaceFactoryClient() override {}
-
-  void ReturnResources(const ReturnedResourceArray& resources) override {
-    returned_resources_.insert(
-        returned_resources_.end(), resources.begin(), resources.end());
-  }
-
-  const ReturnedResourceArray& returned_resources() const {
-    return returned_resources_;
-  }
-
-  void clear_returned_resources() { returned_resources_.clear(); }
-
- private:
-  ReturnedResourceArray returned_resources_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestSurfaceFactoryClient);
-};
-
-class SurfaceFactoryTest : public testing::Test {
- public:
-  SurfaceFactoryTest() : factory_(&manager_, &client_), surface_id_(3) {
-    factory_.Create(surface_id_);
-  }
-
-  ~SurfaceFactoryTest() override {
-    if (!surface_id_.is_null())
-      factory_.Destroy(surface_id_);
-  }
-
-  void SubmitFrameWithResources(ResourceProvider::ResourceId* resource_ids,
-                                size_t num_resource_ids) {
-    scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-    for (size_t i = 0u; i < num_resource_ids; ++i) {
-      TransferableResource resource;
-      resource.id = resource_ids[i];
-      resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-      frame_data->resource_list.push_back(resource);
-    }
-    scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-    frame->delegated_frame_data = frame_data.Pass();
-    factory_.SubmitFrame(surface_id_, frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  void UnrefResources(ResourceProvider::ResourceId* ids_to_unref,
-                      int* counts_to_unref,
-                      size_t num_ids_to_unref) {
-    ReturnedResourceArray unref_array;
-    for (size_t i = 0; i < num_ids_to_unref; ++i) {
-      ReturnedResource resource;
-      resource.id = ids_to_unref[i];
-      resource.count = counts_to_unref[i];
-      unref_array.push_back(resource);
-    }
-    factory_.UnrefResources(unref_array);
-  }
-
-  void CheckReturnedResourcesMatchExpected(
-      ResourceProvider::ResourceId* expected_returned_ids,
-      int* expected_returned_counts,
-      size_t expected_resources) {
-    const ReturnedResourceArray& actual_resources =
-        client_.returned_resources();
-    ASSERT_EQ(expected_resources, actual_resources.size());
-    for (size_t i = 0; i < expected_resources; ++i) {
-      ReturnedResource resource = actual_resources[i];
-      EXPECT_EQ(expected_returned_ids[i], resource.id);
-      EXPECT_EQ(expected_returned_counts[i], resource.count);
-    }
-    client_.clear_returned_resources();
-  }
-
-  void RefCurrentFrameResources() {
-    Surface* surface = manager_.GetSurfaceForId(surface_id_);
-    factory_.RefResources(
-        surface->GetEligibleFrame()->delegated_frame_data->resource_list);
-  }
-
- protected:
-  SurfaceManager manager_;
-  TestSurfaceFactoryClient client_;
-  SurfaceFactory factory_;
-  SurfaceId surface_id_;
-};
-
-// Tests submitting a frame with resources followed by one with no resources
-// with no resource provider action in between.
-TEST_F(SurfaceFactoryTest, ResourceLifetimeSimple) {
-  ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, client_.returned_resources().size());
-  client_.clear_returned_resources();
-
-  // The second frame references no resources and thus should make all resources
-  // available to be returned.
-  SubmitFrameWithResources(NULL, 0);
-
-  ResourceProvider::ResourceId expected_returned_ids[] = {1, 2, 3};
-  int expected_returned_counts[] = {1, 1, 1};
-  CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                      expected_returned_counts,
-                                      arraysize(expected_returned_counts));
-}
-
-// Tests submitting a frame with resources followed by one with no resources
-// with the resource provider holding everything alive.
-TEST_F(SurfaceFactoryTest, ResourceLifetimeSimpleWithProviderHoldingAlive) {
-  ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, client_.returned_resources().size());
-  client_.clear_returned_resources();
-
-  // Hold on to everything.
-  RefCurrentFrameResources();
-
-  // The second frame references no resources and thus should make all resources
-  // available to be returned as soon as the resource provider releases them.
-  SubmitFrameWithResources(NULL, 0);
-
-  EXPECT_EQ(0u, client_.returned_resources().size());
-  client_.clear_returned_resources();
-
-  int release_counts[] = {1, 1, 1};
-  UnrefResources(first_frame_ids, release_counts, arraysize(first_frame_ids));
-
-  ResourceProvider::ResourceId expected_returned_ids[] = {1, 2, 3};
-  int expected_returned_counts[] = {1, 1, 1};
-  CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                      expected_returned_counts,
-                                      arraysize(expected_returned_counts));
-}
-
-// Tests referencing a resource, unref'ing it to zero, then using it again
-// before returning it to the client.
-TEST_F(SurfaceFactoryTest, ResourceReusedBeforeReturn) {
-  ResourceProvider::ResourceId first_frame_ids[] = {7};
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // This removes all references to resource id 7.
-  SubmitFrameWithResources(NULL, 0);
-
-  // This references id 7 again.
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // This removes it again.
-  SubmitFrameWithResources(NULL, 0);
-
-  // Now it should be returned.
-  // We don't care how many entries are in the returned array for 7, so long as
-  // the total returned count matches the submitted count.
-  const ReturnedResourceArray& returned = client_.returned_resources();
-  size_t return_count = 0;
-  for (size_t i = 0; i < returned.size(); ++i) {
-    EXPECT_EQ(7u, returned[i].id);
-    return_count += returned[i].count;
-  }
-  EXPECT_EQ(2u, return_count);
-}
-
-// Tests having resources referenced multiple times, as if referenced by
-// multiple providers.
-TEST_F(SurfaceFactoryTest, ResourceRefMultipleTimes) {
-  ResourceProvider::ResourceId first_frame_ids[] = {3, 4};
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // Ref resources from the first frame twice.
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-
-  ResourceProvider::ResourceId second_frame_ids[] = {4, 5};
-  SubmitFrameWithResources(second_frame_ids, arraysize(second_frame_ids));
-
-  // Ref resources from the second frame 3 times.
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-
-  // Submit a frame with no resources to remove all current frame refs from
-  // submitted resources.
-  SubmitFrameWithResources(NULL, 0);
-
-  EXPECT_EQ(0u, client_.returned_resources().size());
-  client_.clear_returned_resources();
-
-  // Expected current refs:
-  //  3 -> 2
-  //  4 -> 2 + 3 = 5
-  //  5 -> 3
-  {
-    SCOPED_TRACE("unref all 3");
-    ResourceProvider::ResourceId ids_to_unref[] = {3, 4, 5};
-    int counts[] = {1, 1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-
-    EXPECT_EQ(0u, client_.returned_resources().size());
-    client_.clear_returned_resources();
-
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-
-    ResourceProvider::ResourceId expected_returned_ids[] = {3};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-
-  // Expected refs remaining:
-  //  4 -> 3
-  //  5 -> 1
-  {
-    SCOPED_TRACE("unref 4 and 5");
-    ResourceProvider::ResourceId ids_to_unref[] = {4, 5};
-    int counts[] = {1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-
-    ResourceProvider::ResourceId expected_returned_ids[] = {5};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-
-  // Now, just 2 refs remaining on resource 4. Unref both at once and make sure
-  // the returned count is correct.
-  {
-    SCOPED_TRACE("unref only 4");
-    ResourceProvider::ResourceId ids_to_unref[] = {4};
-    int counts[] = {2};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-
-    ResourceProvider::ResourceId expected_returned_ids[] = {4};
-    int expected_returned_counts[] = {2};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-}
-
-TEST_F(SurfaceFactoryTest, ResourceLifetime) {
-  ResourceProvider::ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitFrameWithResources(first_frame_ids, arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, client_.returned_resources().size());
-  client_.clear_returned_resources();
-
-  // The second frame references some of the same resources, but some different
-  // ones. We expect to receive back resource 1 with a count of 1 since it was
-  // only referenced by the first frame.
-  ResourceProvider::ResourceId second_frame_ids[] = {2, 3, 4};
-  SubmitFrameWithResources(second_frame_ids, arraysize(second_frame_ids));
-
-  {
-    SCOPED_TRACE("second frame");
-    ResourceProvider::ResourceId expected_returned_ids[] = {1};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-
-  // The third frame references a disjoint set of resources, so we expect to
-  // receive back all resources from the first and second frames. Resource IDs 2
-  // and 3 will have counts of 2, since they were used in both frames, and
-  // resource ID 4 will have a count of 1.
-  ResourceProvider::ResourceId third_frame_ids[] = {10, 11, 12, 13};
-  SubmitFrameWithResources(third_frame_ids, arraysize(third_frame_ids));
-
-  {
-    SCOPED_TRACE("third frame");
-    ResourceProvider::ResourceId expected_returned_ids[] = {2, 3, 4};
-    int expected_returned_counts[] = {2, 2, 1};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-
-  // Simulate a ResourceProvider taking a ref on all of the resources.
-  RefCurrentFrameResources();
-
-  ResourceProvider::ResourceId fourth_frame_ids[] = {12, 13};
-  SubmitFrameWithResources(fourth_frame_ids, arraysize(fourth_frame_ids));
-
-  EXPECT_EQ(0u, client_.returned_resources().size());
-
-  RefCurrentFrameResources();
-
-  // All resources are still being used by the external reference, so none can
-  // be returned to the client.
-  EXPECT_EQ(0u, client_.returned_resources().size());
-
-  // Release resources associated with the first RefCurrentFrameResources() call
-  // first.
-  {
-    ResourceProvider::ResourceId ids_to_unref[] = {10, 11, 12, 13};
-    int counts[] = {1, 1, 1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-  }
-
-  {
-    SCOPED_TRACE("fourth frame, first unref");
-    ResourceProvider::ResourceId expected_returned_ids[] = {10, 11};
-    int expected_returned_counts[] = {1, 1};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-
-  {
-    ResourceProvider::ResourceId ids_to_unref[] = {12, 13};
-    int counts[] = {1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-  }
-
-  // Resources 12 and 13 are still in use by the current frame, so they
-  // shouldn't be available to be returned.
-  EXPECT_EQ(0u, client_.returned_resources().size());
-
-  // If we submit an empty frame, however, they should become available.
-  SubmitFrameWithResources(NULL, 0u);
-
-  {
-    SCOPED_TRACE("fourth frame, second unref");
-    ResourceProvider::ResourceId expected_returned_ids[] = {12, 13};
-    int expected_returned_counts[] = {2, 2};
-    CheckReturnedResourcesMatchExpected(expected_returned_ids,
-                                        expected_returned_counts,
-                                        arraysize(expected_returned_counts));
-  }
-}
-
-TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) {
-  SurfaceId surface_id(6);
-  factory_.Create(surface_id);
-  Surface* surface = manager_.GetSurfaceForId(surface_id);
-  ASSERT_NE(nullptr, surface);
-  EXPECT_EQ(2, surface->frame_index());
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->delegated_frame_data.reset(new DelegatedFrameData);
-
-  factory_.SubmitFrame(surface_id, frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-  EXPECT_EQ(2, surface->frame_index());
-  factory_.Destroy(surface_id);
-}
-
-void DrawCallback(uint32* execute_count,
-                  SurfaceDrawStatus* result,
-                  SurfaceDrawStatus drawn) {
-  *execute_count += 1;
-  *result = drawn;
-}
-
-// Tests doing a DestroyAll before shutting down the factory;
-TEST_F(SurfaceFactoryTest, DestroyAll) {
-  SurfaceId id(7);
-  factory_.Create(id);
-
-  scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-  TransferableResource resource;
-  resource.id = 1;
-  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-  frame_data->resource_list.push_back(resource);
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->delegated_frame_data = frame_data.Pass();
-  uint32 execute_count = 0;
-  SurfaceDrawStatus drawn = SurfaceDrawStatus::DRAW_SKIPPED;
-
-  factory_.SubmitFrame(id, frame.Pass(),
-                       base::Bind(&DrawCallback, &execute_count, &drawn));
-
-  surface_id_ = SurfaceId();
-  factory_.DestroyAll();
-  EXPECT_EQ(1u, execute_count);
-  EXPECT_EQ(SurfaceDrawStatus::DRAW_SKIPPED, drawn);
-}
-
-TEST_F(SurfaceFactoryTest, DestroySequence) {
-  SurfaceId id2(5);
-  factory_.Create(id2);
-
-  // Check that waiting before the sequence is satisfied works.
-  manager_.GetSurfaceForId(id2)
-      ->AddDestructionDependency(SurfaceSequence(0, 4));
-  factory_.Destroy(id2);
-
-  scoped_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData);
-  scoped_ptr<CompositorFrame> frame(new CompositorFrame);
-  frame->metadata.satisfies_sequences.push_back(6);
-  frame->metadata.satisfies_sequences.push_back(4);
-  frame->delegated_frame_data = frame_data.Pass();
-  DCHECK(manager_.GetSurfaceForId(id2));
-  factory_.SubmitFrame(surface_id_, frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-  DCHECK(!manager_.GetSurfaceForId(id2));
-
-  // Check that waiting after the sequence is satisfied works.
-  factory_.Create(id2);
-  DCHECK(manager_.GetSurfaceForId(id2));
-  manager_.GetSurfaceForId(id2)
-      ->AddDestructionDependency(SurfaceSequence(0, 6));
-  factory_.Destroy(id2);
-  DCHECK(!manager_.GetSurfaceForId(id2));
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/surface_id.h b/cc/surfaces/surface_id.h
deleted file mode 100644
index 070265a..0000000
--- a/cc/surfaces/surface_id.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_ID_H_
-#define CC_SURFACES_SURFACE_ID_H_
-
-#include "base/containers/hash_tables.h"
-
-namespace cc {
-
-struct SurfaceId {
-  SurfaceId() : id(0) {}
-  explicit SurfaceId(uint64_t id) : id(id) {}
-
-  bool is_null() const { return id == 0; }
-
-  uint64_t id;
-};
-
-inline bool operator==(const SurfaceId& a, const SurfaceId& b) {
-  return a.id == b.id;
-}
-
-inline bool operator!=(const SurfaceId& a, const SurfaceId& b) {
-  return !(a == b);
-}
-
-inline bool operator<(const SurfaceId& a, const SurfaceId& b) {
-  return a.id < b.id;
-}
-
-}  // namespace cc
-
-namespace BASE_HASH_NAMESPACE {
-template <>
-struct hash<cc::SurfaceId> {
-  size_t operator()(cc::SurfaceId key) const {
-    return hash<uint64_t>()(key.id);
-  }
-};
-}  // namespace BASE_HASH_NAMESPACE
-
-#endif  // CC_SURFACES_SURFACE_ID_H_
diff --git a/cc/surfaces/surface_id_allocator.cc b/cc/surfaces/surface_id_allocator.cc
deleted file mode 100644
index af9e91b..0000000
--- a/cc/surfaces/surface_id_allocator.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_id_allocator.h"
-
-namespace cc {
-
-SurfaceIdAllocator::SurfaceIdAllocator(uint32_t id_namespace)
-    : id_namespace_(id_namespace), next_id_(1u) {
-}
-
-SurfaceId SurfaceIdAllocator::GenerateId() {
-  SurfaceId id(static_cast<uint64_t>(id_namespace_) << 32 | next_id_);
-  next_id_++;
-  return id;
-}
-
-// static
-uint32_t SurfaceIdAllocator::NamespaceForId(SurfaceId id) {
-  return id.id >> 32;
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_id_allocator.h b/cc/surfaces/surface_id_allocator.h
deleted file mode 100644
index 96a241f..0000000
--- a/cc/surfaces/surface_id_allocator.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_ID_ALLOCATOR_H_
-#define CC_SURFACES_SURFACE_ID_ALLOCATOR_H_
-
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-
-// This is a helper class for generating surface IDs within a specified
-// namespace.  This is not threadsafe, to use from multiple threads wrap this
-// class in a mutex.
-class CC_SURFACES_EXPORT SurfaceIdAllocator {
- public:
-  explicit SurfaceIdAllocator(uint32_t id_namespace);
-
-  SurfaceId GenerateId();
-
-  static uint32_t NamespaceForId(SurfaceId id);
-
-  uint32_t id_namespace() const { return id_namespace_; }
-
- private:
-  const uint32_t id_namespace_;
-  uint32_t next_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceIdAllocator);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_ID_ALLOCATOR_H_
diff --git a/cc/surfaces/surface_manager.cc b/cc/surfaces/surface_manager.cc
deleted file mode 100644
index 117d82a..0000000
--- a/cc/surfaces/surface_manager.cc
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_manager.h"
-
-#include "base/logging.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_id_allocator.h"
-
-namespace cc {
-
-SurfaceManager::SurfaceManager() {
-  thread_checker_.DetachFromThread();
-}
-
-SurfaceManager::~SurfaceManager() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (SurfaceDestroyList::iterator it = surfaces_to_destroy_.begin();
-       it != surfaces_to_destroy_.end();
-       ++it) {
-    DeregisterSurface((*it)->surface_id());
-    delete *it;
-  }
-}
-
-void SurfaceManager::RegisterSurface(Surface* surface) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  DCHECK(surface);
-  DCHECK(!surface_map_.count(surface->surface_id()));
-  surface_map_[surface->surface_id()] = surface;
-}
-
-void SurfaceManager::DeregisterSurface(SurfaceId surface_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  SurfaceMap::iterator it = surface_map_.find(surface_id);
-  DCHECK(it != surface_map_.end());
-  surface_map_.erase(it);
-}
-
-void SurfaceManager::Destroy(scoped_ptr<Surface> surface) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  surfaces_to_destroy_.push_back(surface.release());
-  SearchForSatisfaction();
-}
-
-void SurfaceManager::DidSatisfySequences(uint32_t id_namespace,
-                                         std::vector<uint32_t>* sequence) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  for (std::vector<uint32_t>::iterator it = sequence->begin();
-       it != sequence->end();
-       ++it) {
-    satisfied_sequences_.insert(SurfaceSequence(id_namespace, *it));
-  }
-  sequence->clear();
-  SearchForSatisfaction();
-}
-
-void SurfaceManager::SearchForSatisfaction() {
-  for (SurfaceDestroyList::iterator dest_it = surfaces_to_destroy_.begin();
-       dest_it != surfaces_to_destroy_.end();) {
-    (*dest_it)->SatisfyDestructionDependencies(&satisfied_sequences_);
-    if (!(*dest_it)->GetDestructionDependencyCount()) {
-      scoped_ptr<Surface> surf(*dest_it);
-      DeregisterSurface(surf->surface_id());
-      dest_it = surfaces_to_destroy_.erase(dest_it);
-    } else {
-      ++dest_it;
-    }
-  }
-}
-
-Surface* SurfaceManager::GetSurfaceForId(SurfaceId surface_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  SurfaceMap::iterator it = surface_map_.find(surface_id);
-  if (it == surface_map_.end())
-    return NULL;
-  return it->second;
-}
-
-bool SurfaceManager::SurfaceModified(SurfaceId surface_id) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  bool changed = false;
-  FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_,
-                    OnSurfaceDamaged(surface_id, &changed));
-  return changed;
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_manager.h b/cc/surfaces/surface_manager.h
deleted file mode 100644
index e5d6081..0000000
--- a/cc/surfaces/surface_manager.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_MANAGER_H_
-#define CC_SURFACES_SURFACE_MANAGER_H_
-
-#include <list>
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/observer_list.h"
-#include "base/threading/thread_checker.h"
-#include "cc/surfaces/surface_damage_observer.h"
-#include "cc/surfaces/surface_id.h"
-#include "cc/surfaces/surface_sequence.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-class CompositorFrame;
-class Surface;
-
-class CC_SURFACES_EXPORT SurfaceManager {
- public:
-  SurfaceManager();
-  ~SurfaceManager();
-
-  void RegisterSurface(Surface* surface);
-  void DeregisterSurface(SurfaceId surface_id);
-
-  // Destroy the Surface once a set of sequence numbers has been satisfied.
-  void Destroy(scoped_ptr<Surface> surface);
-
-  Surface* GetSurfaceForId(SurfaceId surface_id);
-
-  void AddObserver(SurfaceDamageObserver* obs) {
-    observer_list_.AddObserver(obs);
-  }
-
-  void RemoveObserver(SurfaceDamageObserver* obs) {
-    observer_list_.RemoveObserver(obs);
-  }
-
-  bool SurfaceModified(SurfaceId surface_id);
-
-  // A frame for a surface satisfies a set of sequence numbers in a particular
-  // id namespace.
-  void DidSatisfySequences(uint32_t id_namespace,
-                           std::vector<uint32_t>* sequence);
-
- private:
-  void SearchForSatisfaction();
-
-  typedef base::hash_map<SurfaceId, Surface*> SurfaceMap;
-  SurfaceMap surface_map_;
-  base::ObserverList<SurfaceDamageObserver> observer_list_;
-  base::ThreadChecker thread_checker_;
-
-  // List of surfaces to be destroyed, along with what sequences they're still
-  // waiting on.
-  typedef std::list<Surface*> SurfaceDestroyList;
-  SurfaceDestroyList surfaces_to_destroy_;
-
-  // Set of SurfaceSequences that have been satisfied by a frame but not yet
-  // waited on.
-  base::hash_set<SurfaceSequence> satisfied_sequences_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceManager);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_MANAGER_H_
diff --git a/cc/surfaces/surface_resource_holder.cc b/cc/surfaces/surface_resource_holder.cc
deleted file mode 100644
index 50d31a5..0000000
--- a/cc/surfaces/surface_resource_holder.cc
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface_resource_holder.h"
-
-#include "cc/surfaces/surface_factory_client.h"
-
-namespace cc {
-
-SurfaceResourceHolder::SurfaceResourceHolder(SurfaceFactoryClient* client)
-    : client_(client) {
-}
-
-SurfaceResourceHolder::~SurfaceResourceHolder() {
-}
-
-SurfaceResourceHolder::ResourceRefs::ResourceRefs()
-    : refs_received_from_child(0), refs_holding_resource_alive(0) {
-}
-
-void SurfaceResourceHolder::ReceiveFromChild(
-    const TransferableResourceArray& resources) {
-  for (TransferableResourceArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    ResourceRefs& ref = resource_id_use_count_map_[it->id];
-    ref.refs_holding_resource_alive++;
-    ref.refs_received_from_child++;
-  }
-}
-
-void SurfaceResourceHolder::RefResources(
-    const TransferableResourceArray& resources) {
-  for (TransferableResourceArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    ResourceIdCountMap::iterator count_it =
-        resource_id_use_count_map_.find(it->id);
-    DCHECK(count_it != resource_id_use_count_map_.end());
-    count_it->second.refs_holding_resource_alive++;
-  }
-}
-
-void SurfaceResourceHolder::UnrefResources(
-    const ReturnedResourceArray& resources) {
-  ReturnedResourceArray resources_available_to_return;
-
-  for (ReturnedResourceArray::const_iterator it = resources.begin();
-       it != resources.end();
-       ++it) {
-    ResourceProvider::ResourceId id = it->id;
-    ResourceIdCountMap::iterator count_it = resource_id_use_count_map_.find(id);
-    if (count_it == resource_id_use_count_map_.end())
-      continue;
-    ResourceRefs& ref = count_it->second;
-    ref.refs_holding_resource_alive -= it->count;
-    if (ref.refs_holding_resource_alive == 0) {
-      ReturnedResource returned = *it;
-      returned.count = ref.refs_received_from_child;
-      resources_available_to_return.push_back(returned);
-      resource_id_use_count_map_.erase(count_it);
-    }
-  }
-
-  client_->ReturnResources(resources_available_to_return);
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_resource_holder.h b/cc/surfaces/surface_resource_holder.h
deleted file mode 100644
index 20c9f29..0000000
--- a/cc/surfaces/surface_resource_holder.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_RESOURCE_HOLDER_H_
-#define CC_SURFACES_SURFACE_RESOURCE_HOLDER_H_
-
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-class SurfaceFactoryClient;
-
-// A SurfaceResourceHolder manages the lifetime of resources submitted by a
-// particular SurfaceFactory. Each resource is held by the service until
-// it is no longer referenced by any pending frames or by any
-// resource providers.
-class CC_SURFACES_EXPORT SurfaceResourceHolder {
- public:
-  explicit SurfaceResourceHolder(SurfaceFactoryClient* client);
-  ~SurfaceResourceHolder();
-
-  void ReceiveFromChild(const TransferableResourceArray& resources);
-  void RefResources(const TransferableResourceArray& resources);
-  void UnrefResources(const ReturnedResourceArray& resources);
-
- private:
-  SurfaceFactoryClient* client_;
-
-  struct ResourceRefs {
-    ResourceRefs();
-
-    int refs_received_from_child;
-    int refs_holding_resource_alive;
-  };
-  // Keeps track of the number of users currently in flight for each resource
-  // ID we've received from the client. When this counter hits zero for a
-  // particular resource, that ID is available to return to the client.
-  typedef base::hash_map<ResourceProvider::ResourceId, ResourceRefs>
-      ResourceIdCountMap;
-  ResourceIdCountMap resource_id_use_count_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceResourceHolder);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_RESOURCE_HOLDER_H_
diff --git a/cc/surfaces/surface_sequence.h b/cc/surfaces/surface_sequence.h
deleted file mode 100644
index 72f4bc9..0000000
--- a/cc/surfaces/surface_sequence.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACE_SEQUENCE_H_
-#define CC_SURFACES_SURFACE_SEQUENCE_H_
-
-#include "base/containers/hash_tables.h"
-
-namespace cc {
-
-// A per-surface-namespace sequence number that's used to coordinate
-// dependencies between frames. A sequence number may be satisfied once, and
-// may be depended on once.
-struct SurfaceSequence {
-  SurfaceSequence() : id_namespace(0u), sequence(0u) {}
-  SurfaceSequence(uint32_t id_namespace, uint32_t sequence)
-      : id_namespace(id_namespace), sequence(sequence) {}
-  bool is_null() const { return id_namespace == 0u && sequence == 0u; }
-
-  uint32_t id_namespace;
-  uint32_t sequence;
-};
-
-inline bool operator==(const SurfaceSequence& a, const SurfaceSequence& b) {
-  return a.id_namespace == b.id_namespace && a.sequence == b.sequence;
-}
-
-inline bool operator!=(const SurfaceSequence& a, const SurfaceSequence& b) {
-  return !(a == b);
-}
-
-inline bool operator<(const SurfaceSequence& a, const SurfaceSequence& b) {
-  if (a.id_namespace != b.id_namespace)
-    return a.id_namespace < b.id_namespace;
-  return a.sequence < b.sequence;
-}
-
-}  // namespace cc
-
-namespace BASE_HASH_NAMESPACE {
-template <>
-struct hash<cc::SurfaceSequence> {
-  size_t operator()(cc::SurfaceSequence key) const {
-    return base::HashPair(key.id_namespace, key.sequence);
-  }
-};
-}  // namespace BASE_HASH_NAMESPACE
-
-#endif  // CC_SURFACES_SURFACE_SEQUENCE_H_
diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc
deleted file mode 100644
index 7f2de36..0000000
--- a/cc/surfaces/surface_unittest.cc
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-namespace {
-
-TEST(SurfaceTest, SurfaceLifetime) {
-  SurfaceManager manager;
-  SurfaceFactory factory(&manager, NULL);
-
-  SurfaceId surface_id(6);
-  {
-    factory.Create(surface_id);
-    EXPECT_TRUE(!!manager.GetSurfaceForId(surface_id));
-    factory.Destroy(surface_id);
-  }
-
-  EXPECT_EQ(NULL, manager.GetSurfaceForId(surface_id));
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/surfaces_export.h b/cc/surfaces/surfaces_export.h
deleted file mode 100644
index f849333..0000000
--- a/cc/surfaces/surfaces_export.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_SURFACES_SURFACES_EXPORT_H_
-#define CC_SURFACES_SURFACES_EXPORT_H_
-
-#if defined(COMPONENT_BUILD)
-#if defined(WIN32)
-
-#if defined(CC_SURFACES_IMPLEMENTATION)
-#define CC_SURFACES_EXPORT __declspec(dllexport)
-#else
-#define CC_SURFACES_EXPORT __declspec(dllimport)
-#endif  // defined(CC_SURFACES_IMPLEMENTATION)
-
-#else  // defined(WIN32)
-#if defined(CC_SURFACES_IMPLEMENTATION)
-#define CC_SURFACES_EXPORT __attribute__((visibility("default")))
-#else
-#define CC_SURFACES_EXPORT
-#endif
-#endif
-
-#else  // defined(COMPONENT_BUILD)
-#define CC_SURFACES_EXPORT
-#endif
-
-#endif  // CC_SURFACES_SURFACES_EXPORT_H_
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc
deleted file mode 100644
index 528684b..0000000
--- a/cc/surfaces/surfaces_pixeltest.cc
+++ /dev/null
@@ -1,340 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_factory.h"
-#include "cc/surfaces/surface_factory_client.h"
-#include "cc/surfaces/surface_id_allocator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/pixel_comparator.h"
-#include "cc/test/pixel_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if !defined(OS_ANDROID)
-
-namespace cc {
-namespace {
-
-class EmptySurfaceFactoryClient : public SurfaceFactoryClient {
- public:
-  void ReturnResources(const ReturnedResourceArray& resources) override {}
-};
-
-class SurfacesPixelTest : public RendererPixelTest<GLRenderer> {
- public:
-  SurfacesPixelTest() : allocator_(1u), factory_(&manager_, &client_) {}
-
- protected:
-  SurfaceManager manager_;
-  SurfaceIdAllocator allocator_;
-  EmptySurfaceFactoryClient client_;
-  SurfaceFactory factory_;
-};
-
-SharedQuadState* CreateAndAppendTestSharedQuadState(
-    RenderPass* render_pass,
-    const gfx::Transform& transform,
-    const gfx::Size& size) {
-  const gfx::Size content_bounds = size;
-  const gfx::Rect visible_content_rect = gfx::Rect(size);
-  const gfx::Rect clip_rect = gfx::Rect(size);
-  bool is_clipped = false;
-  float opacity = 1.f;
-  const SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
-  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(transform,
-                       content_bounds,
-                       visible_content_rect,
-                       clip_rect,
-                       is_clipped,
-                       opacity,
-                       blend_mode,
-                       0);
-  return shared_state;
-}
-
-// Draws a very simple frame with no surface references.
-TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
-  gfx::Rect rect(device_viewport_size_);
-  RenderPassId id(1, 1);
-  scoped_ptr<RenderPass> pass = RenderPass::Create();
-  pass->SetNew(id, rect, rect, gfx::Transform());
-
-  CreateAndAppendTestSharedQuadState(
-      pass.get(), gfx::Transform(), device_viewport_size_);
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  bool force_anti_aliasing_off = false;
-  color_quad->SetNew(pass->shared_quad_state_list.back(),
-                     rect,
-                     rect,
-                     SK_ColorGREEN,
-                     force_anti_aliasing_off);
-
-  scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-  delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-  scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-  root_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-  SurfaceId root_surface_id = allocator_.GenerateId();
-  factory_.Create(root_surface_id);
-  factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
-                       SurfaceFactory::DrawCallback());
-
-  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator.Aggregate(root_surface_id);
-  factory_.Destroy(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list =
-      &aggregated_frame->delegated_frame_data->render_pass_list;
-  EXPECT_TRUE(RunPixelTest(pass_list,
-                           base::FilePath(FILE_PATH_LITERAL("green.png")),
-                           pixel_comparator));
-}
-
-// Draws a frame with simple surface embedding.
-TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
-  gfx::Size child_size(200, 100);
-  SurfaceId child_surface_id = allocator_.GenerateId();
-  SurfaceId root_surface_id = allocator_.GenerateId();
-  factory_.Create(child_surface_id);
-  factory_.Create(root_surface_id);
-  {
-    gfx::Rect rect(device_viewport_size_);
-    RenderPassId id(1, 1);
-    scoped_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), device_viewport_size_);
-
-    SurfaceDrawQuad* surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                         gfx::Rect(child_size),
-                         gfx::Rect(child_size),
-                         child_surface_id);
-
-    SolidColorDrawQuad* color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    color_quad->SetNew(pass->shared_quad_state_list.back(),
-                       rect,
-                       rect,
-                       SK_ColorYELLOW,
-                       force_anti_aliasing_off);
-
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-    root_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    RenderPassId id(1, 1);
-    scoped_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    color_quad->SetNew(pass->shared_quad_state_list.back(),
-                       rect,
-                       rect,
-                       SK_ColorBLUE,
-                       force_anti_aliasing_off);
-
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(child_surface_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator.Aggregate(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list =
-      &aggregated_frame->delegated_frame_data->render_pass_list;
-  EXPECT_TRUE(RunPixelTest(pass_list,
-                           base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
-                           pixel_comparator));
-  factory_.Destroy(root_surface_id);
-  factory_.Destroy(child_surface_id);
-}
-
-// Tests a surface quad that has a non-identity transform into its pass.
-TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
-  gfx::Size child_size(100, 200);
-  gfx::Size quad_size(100, 100);
-  // Structure:
-  // root (200x200) -> left_child (100x200 @ 0x0,
-  //                   right_child (100x200 @ 0x100)
-  //   left_child -> top_green_quad (100x100 @ 0x0),
-  //                 bottom_blue_quad (100x100 @ 0x100)
-  //   right_child -> top_blue_quad (100x100 @ 0x0),
-  //                  bottom_green_quad (100x100 @ 0x100)
-  SurfaceId left_child_id = allocator_.GenerateId();
-  SurfaceId right_child_id = allocator_.GenerateId();
-  SurfaceId root_surface_id = allocator_.GenerateId();
-  factory_.Create(left_child_id);
-  factory_.Create(right_child_id);
-  factory_.Create(root_surface_id);
-
-  {
-    gfx::Rect rect(device_viewport_size_);
-    RenderPassId id(1, 1);
-    scoped_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    gfx::Transform surface_transform;
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), surface_transform, device_viewport_size_);
-
-    SurfaceDrawQuad* left_surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(child_size),
-                              gfx::Rect(child_size),
-                              left_child_id);
-
-    surface_transform.Translate(100, 0);
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), surface_transform, device_viewport_size_);
-
-    SurfaceDrawQuad* right_surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                               gfx::Rect(child_size),
-                               gfx::Rect(child_size),
-                               right_child_id);
-
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> root_frame(new CompositorFrame);
-    root_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(root_surface_id, root_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    RenderPassId id(1, 1);
-    scoped_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* top_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                           gfx::Rect(quad_size),
-                           gfx::Rect(quad_size),
-                           SK_ColorGREEN,
-                           force_anti_aliasing_off);
-
-    SolidColorDrawQuad* bottom_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(0, 100, 100, 100),
-                              gfx::Rect(0, 100, 100, 100),
-                              SK_ColorBLUE,
-                              force_anti_aliasing_off);
-
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(left_child_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    RenderPassId id(1, 1);
-    scoped_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* top_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                           gfx::Rect(quad_size),
-                           gfx::Rect(quad_size),
-                           SK_ColorBLUE,
-                           force_anti_aliasing_off);
-
-    SolidColorDrawQuad* bottom_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(0, 100, 100, 100),
-                              gfx::Rect(0, 100, 100, 100),
-                              SK_ColorGREEN,
-                              force_anti_aliasing_off);
-
-    scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
-    delegated_frame_data->render_pass_list.push_back(pass.Pass());
-
-    scoped_ptr<CompositorFrame> child_frame(new CompositorFrame);
-    child_frame->delegated_frame_data = delegated_frame_data.Pass();
-
-    factory_.SubmitFrame(right_child_id, child_frame.Pass(),
-                         SurfaceFactory::DrawCallback());
-  }
-
-  SurfaceAggregator aggregator(&manager_, resource_provider_.get());
-  scoped_ptr<CompositorFrame> aggregated_frame =
-      aggregator.Aggregate(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list =
-      &aggregated_frame->delegated_frame_data->render_pass_list;
-  EXPECT_TRUE(RunPixelTest(
-      pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      pixel_comparator));
-
-  factory_.Destroy(root_surface_id);
-  factory_.Destroy(left_child_id);
-  factory_.Destroy(right_child_id);
-}
-
-}  // namespace
-}  // namespace cc
-
-#endif  // !defined(OS_ANDROID)
diff --git a/cc/test/DEPS b/cc/test/DEPS
deleted file mode 100644
index 87f889e..0000000
--- a/cc/test/DEPS
+++ /dev/null
@@ -1,9 +0,0 @@
-include_rules = [
-  "+gpu/command_buffer/client/gl_in_process_context.h",
-  "+gpu/command_buffer/client/gles2_implementation.h",
-  "+gpu/command_buffer/client/gles2_interface_stub.h",
-  "+gpu/command_buffer/client/gles2_lib.h",
-  "+gpu/command_buffer/common/gles2_cmd_utils.h",
-  "+gpu/command_buffer/service/image_factory.h",
-  "+gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h",
-]
diff --git a/cc/test/begin_frame_args_test.cc b/cc/test/begin_frame_args_test.cc
deleted file mode 100644
index 7b29748..0000000
--- a/cc/test/begin_frame_args_test.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/begin_frame_args_test.h"
-
-#include "base/time/time.h"
-#include "cc/output/begin_frame_args.h"
-#include "ui/gfx/frame_time.h"
-
-namespace cc {
-
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location) {
-  return CreateBeginFrameArgsForTesting(location, gfx::FrameTime::Now());
-}
-
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    base::TimeTicks frame_time) {
-  return BeginFrameArgs::Create(
-      location, frame_time,
-      frame_time + (BeginFrameArgs::DefaultInterval() / 2),
-      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
-}
-
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    int64 frame_time,
-    int64 deadline,
-    int64 interval) {
-  return BeginFrameArgs::Create(
-      location, base::TimeTicks::FromInternalValue(frame_time),
-      base::TimeTicks::FromInternalValue(deadline),
-      base::TimeDelta::FromInternalValue(interval), BeginFrameArgs::NORMAL);
-}
-
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    int64 frame_time,
-    int64 deadline,
-    int64 interval,
-    BeginFrameArgs::BeginFrameArgsType type) {
-  return BeginFrameArgs::Create(
-      location, base::TimeTicks::FromInternalValue(frame_time),
-      base::TimeTicks::FromInternalValue(deadline),
-      base::TimeDelta::FromInternalValue(interval), type);
-}
-
-BeginFrameArgs CreateExpiredBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location) {
-  base::TimeTicks now = gfx::FrameTime::Now();
-  return BeginFrameArgs::Create(
-      location, now, now - BeginFrameArgs::DefaultInterval(),
-      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
-}
-
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    scoped_refptr<TestNowSource> now_src) {
-  base::TimeTicks now = now_src->Now();
-  return BeginFrameArgs::Create(
-      location, now, now + (BeginFrameArgs::DefaultInterval() / 2),
-      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
-}
-
-BeginFrameArgs CreateExpiredBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    scoped_refptr<TestNowSource> now_src) {
-  base::TimeTicks now = now_src->Now();
-  return BeginFrameArgs::Create(
-      location, now, now - BeginFrameArgs::DefaultInterval(),
-      BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
-}
-
-bool operator==(const BeginFrameArgs& lhs, const BeginFrameArgs& rhs) {
-  return (lhs.type == rhs.type) && (lhs.frame_time == rhs.frame_time) &&
-         (lhs.deadline == rhs.deadline) && (lhs.interval == rhs.interval);
-}
-
-::std::ostream& operator<<(::std::ostream& os, const BeginFrameArgs& args) {
-  PrintTo(args, &os);
-  return os;
-}
-
-void PrintTo(const BeginFrameArgs& args, ::std::ostream* os) {
-  *os << "BeginFrameArgs(" << BeginFrameArgs::TypeToString(args.type) << ", "
-      << args.frame_time.ToInternalValue() << ", "
-      << args.deadline.ToInternalValue() << ", "
-      << args.interval.InMicroseconds() << "us)";
-}
-
-}  // namespace cc
diff --git a/cc/test/begin_frame_args_test.h b/cc/test/begin_frame_args_test.h
deleted file mode 100644
index 73aaf02..0000000
--- a/cc/test/begin_frame_args_test.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_BEGIN_FRAME_ARGS_TEST_H_
-#define CC_TEST_BEGIN_FRAME_ARGS_TEST_H_
-
-#include <iosfwd>
-
-#include "base/time/time.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/test/test_now_source.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-// Functions for quickly creating BeginFrameArgs
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location);
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    base::TimeTicks frame_time);
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    int64 frame_time,
-    int64 deadline,
-    int64 interval);
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    int64 frame_time,
-    int64 deadline,
-    int64 interval,
-    BeginFrameArgs::BeginFrameArgsType type);
-BeginFrameArgs CreateExpiredBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location);
-
-// Creates a BeginFrameArgs using the fake Now value stored on the
-// OrderSimpleTaskRunner.
-BeginFrameArgs CreateBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    scoped_refptr<TestNowSource> now_src);
-BeginFrameArgs CreateExpiredBeginFrameArgsForTesting(
-    BeginFrameArgs::CreationLocation location,
-    scoped_refptr<TestNowSource> now_src);
-
-// gtest helpers -- these *must* be in the same namespace as the types they
-// operate on.
-
-// Allow "EXPECT_EQ(args1, args2);"
-// We don't define operator!= because EXPECT_NE(args1, args2) isn't all that
-// sensible.
-bool operator==(const BeginFrameArgs& lhs, const BeginFrameArgs& rhs);
-
-// Allow gtest to pretty print begin frame args.
-::std::ostream& operator<<(::std::ostream& os, const BeginFrameArgs& args);
-void PrintTo(const BeginFrameArgs& args, ::std::ostream* os);
-
-}  // namespace cc
-
-#endif  // CC_TEST_BEGIN_FRAME_ARGS_TEST_H_
diff --git a/cc/test/cc_test_suite.cc b/cc/test/cc_test_suite.cc
deleted file mode 100644
index f48f10a..0000000
--- a/cc/test/cc_test_suite.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "cc/test/cc_test_suite.h"
-
-#include "base/message_loop/message_loop.h"
-#include "base/threading/thread_id_name_manager.h"
-#include "cc/test/paths.h"
-#include "ui/gl/gl_surface.h"
-
-namespace cc {
-
-CCTestSuite::CCTestSuite(int argc, char** argv)
-    : base::TestSuite(argc, argv) {}
-
-CCTestSuite::~CCTestSuite() {}
-
-void CCTestSuite::Initialize() {
-  base::TestSuite::Initialize();
-  gfx::GLSurface::InitializeOneOffForTests();
-  CCPaths::RegisterPathProvider();
-
-  message_loop_.reset(new base::MessageLoop);
-
-  base::ThreadIdNameManager::GetInstance()->SetName(
-      base::PlatformThread::CurrentId(),
-      "Main");
-}
-
-void CCTestSuite::Shutdown() {
-  message_loop_ = nullptr;
-
-  base::TestSuite::Shutdown();
-}
-
-}  // namespace cc
diff --git a/cc/test/cc_test_suite.h b/cc/test/cc_test_suite.h
deleted file mode 100644
index d2ad2b8..0000000
--- a/cc/test/cc_test_suite.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CC_TEST_CC_TEST_SUITE_H_
-#define CC_TEST_CC_TEST_SUITE_H_
-
-#include "base/macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/test/test_suite.h"
-
-namespace base {
-class MessageLoop;
-}
-
-namespace cc {
-
-class CCTestSuite : public base::TestSuite {
- public:
-  CCTestSuite(int argc, char** argv);
-  ~CCTestSuite() override;
-
- protected:
-  // Overridden from base::TestSuite:
-  void Initialize() override;
-  void Shutdown() override;
-
- private:
-  scoped_ptr<base::MessageLoop> message_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(CCTestSuite);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_CC_TEST_SUITE_H_
diff --git a/cc/test/failure_output_surface.cc b/cc/test/failure_output_surface.cc
deleted file mode 100644
index c0d5fdb..0000000
--- a/cc/test/failure_output_surface.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/failure_output_surface.h"
-
-namespace cc {
-
-FailureOutputSurface::FailureOutputSurface(bool is_delegating)
-    : FakeOutputSurface(static_cast<ContextProvider*>(nullptr), is_delegating) {
-}
-
-bool FailureOutputSurface::BindToClient(OutputSurfaceClient* client) {
-  // This will force this output surface to not initialize in LTHI
-  // and eventually get back to LTH::DidFailToInitializeOutputSurface;
-  return false;
-}
-
-}  // namespace cc
diff --git a/cc/test/failure_output_surface.h b/cc/test/failure_output_surface.h
deleted file mode 100644
index 4878ea5..0000000
--- a/cc/test/failure_output_surface.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_FAILURE_OUTPUT_SURFACE_H_
-#define CC_TEST_FAILURE_OUTPUT_SURFACE_H_
-
-#include "cc/test/fake_output_surface.h"
-
-namespace cc {
-
-class FailureOutputSurface : public FakeOutputSurface {
- public:
-  explicit FailureOutputSurface(bool is_delegating);
-
-  bool BindToClient(OutputSurfaceClient* client) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FailureOutputSurface);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAILURE_OUTPUT_SURFACE_H_
diff --git a/cc/test/fake_external_begin_frame_source.cc b/cc/test/fake_external_begin_frame_source.cc
deleted file mode 100644
index c1885c1..0000000
--- a/cc/test/fake_external_begin_frame_source.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/fake_external_begin_frame_source.h"
-
-#include "base/location.h"
-#include "base/message_loop/message_loop.h"
-#include "base/time/time.h"
-#include "cc/test/begin_frame_args_test.h"
-
-namespace cc {
-
-FakeExternalBeginFrameSource::FakeExternalBeginFrameSource(double refresh_rate)
-    : milliseconds_per_frame_(1000.0 / refresh_rate),
-      is_ready_(false),
-      weak_ptr_factory_(this) {
-  DetachFromThread();
-}
-
-FakeExternalBeginFrameSource::~FakeExternalBeginFrameSource() {
-  DCHECK(CalledOnValidThread());
-}
-
-void FakeExternalBeginFrameSource::SetClientReady() {
-  DCHECK(CalledOnValidThread());
-  is_ready_ = true;
-}
-
-void FakeExternalBeginFrameSource::OnNeedsBeginFramesChange(
-    bool needs_begin_frames) {
-  DCHECK(CalledOnValidThread());
-  if (needs_begin_frames) {
-    PostTestOnBeginFrame();
-  }
-}
-
-void FakeExternalBeginFrameSource::TestOnBeginFrame() {
-  DCHECK(CalledOnValidThread());
-  CallOnBeginFrame(CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE));
-
-  if (NeedsBeginFrames()) {
-    PostTestOnBeginFrame();
-  }
-}
-
-void FakeExternalBeginFrameSource::PostTestOnBeginFrame() {
-  base::MessageLoop::current()->PostDelayedTask(
-      FROM_HERE, base::Bind(&FakeExternalBeginFrameSource::TestOnBeginFrame,
-                            weak_ptr_factory_.GetWeakPtr()),
-      base::TimeDelta::FromMilliseconds(milliseconds_per_frame_));
-}
-
-}  // namespace cc
diff --git a/cc/test/fake_external_begin_frame_source.h b/cc/test/fake_external_begin_frame_source.h
deleted file mode 100644
index d5b14e7..0000000
--- a/cc/test/fake_external_begin_frame_source.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_FAKE_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-#define CC_TEST_FAKE_EXTERNAL_BEGIN_FRAME_SOURCE_H_
-
-#include "base/memory/weak_ptr.h"
-#include "cc/scheduler/begin_frame_source.h"
-
-namespace cc {
-
-class FakeExternalBeginFrameSource
-    : public BeginFrameSourceMixIn,
-      public NON_EXPORTED_BASE(base::NonThreadSafe) {
- public:
-  explicit FakeExternalBeginFrameSource(double refresh_rate);
-  ~FakeExternalBeginFrameSource() override;
-
-  bool is_ready() const { return is_ready_; }
-
-  // BeginFrameSource implementation.
-  void SetClientReady() override;
-
-  // BeginFrameSourceMixIn overrides.
-  void OnNeedsBeginFramesChange(bool needs_begin_frames) override;
-
-  void TestOnBeginFrame();
-  void PostTestOnBeginFrame();
-
- private:
-  double milliseconds_per_frame_;
-  bool is_ready_;
-  base::WeakPtrFactory<FakeExternalBeginFrameSource> weak_ptr_factory_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAKE_EXTERNAL_BEGIN_FRAME_SOURCE_H_
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc
deleted file mode 100644
index 052a87c..0000000
--- a/cc/test/fake_output_surface.cc
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/fake_output_surface.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "cc/output/compositor_frame_ack.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-FakeOutputSurface::FakeOutputSurface(
-    scoped_refptr<ContextProvider> context_provider,
-    scoped_refptr<ContextProvider> worker_context_provider,
-    bool delegated_rendering)
-    : OutputSurface(context_provider, worker_context_provider),
-      client_(NULL),
-      num_sent_frames_(0),
-      has_external_stencil_test_(false),
-      framebuffer_(0) {
-  if (delegated_rendering) {
-    capabilities_.delegated_rendering = true;
-    capabilities_.max_frames_pending = 1;
-  }
-}
-
-FakeOutputSurface::FakeOutputSurface(
-    scoped_refptr<ContextProvider> context_provider,
-    bool delegated_rendering)
-    : OutputSurface(context_provider),
-      client_(NULL),
-      num_sent_frames_(0),
-      has_external_stencil_test_(false),
-      framebuffer_(0) {
-  if (delegated_rendering) {
-    capabilities_.delegated_rendering = true;
-    capabilities_.max_frames_pending = 1;
-  }
-}
-
-FakeOutputSurface::FakeOutputSurface(
-    scoped_ptr<SoftwareOutputDevice> software_device,
-    bool delegated_rendering)
-    : OutputSurface(software_device.Pass()),
-      client_(NULL),
-      num_sent_frames_(0),
-      has_external_stencil_test_(false),
-      framebuffer_(0) {
-  if (delegated_rendering) {
-    capabilities_.delegated_rendering = true;
-    capabilities_.max_frames_pending = 1;
-  }
-}
-
-FakeOutputSurface::FakeOutputSurface(
-    scoped_refptr<ContextProvider> context_provider,
-    scoped_ptr<SoftwareOutputDevice> software_device,
-    bool delegated_rendering)
-    : OutputSurface(context_provider, software_device.Pass()),
-      client_(NULL),
-      num_sent_frames_(0),
-      has_external_stencil_test_(false),
-      framebuffer_(0) {
-  if (delegated_rendering) {
-    capabilities_.delegated_rendering = true;
-    capabilities_.max_frames_pending = 1;
-  }
-}
-
-FakeOutputSurface::~FakeOutputSurface() {}
-
-void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) {
-  if (frame->software_frame_data || frame->delegated_frame_data ||
-      !context_provider()) {
-    frame->AssignTo(&last_sent_frame_);
-
-    if (last_sent_frame_.delegated_frame_data) {
-      resources_held_by_parent_.insert(
-          resources_held_by_parent_.end(),
-          last_sent_frame_.delegated_frame_data->resource_list.begin(),
-          last_sent_frame_.delegated_frame_data->resource_list.end());
-    }
-
-    ++num_sent_frames_;
-  } else {
-    last_swap_rect_ = frame->gl_frame_data->sub_buffer_rect;
-    frame->AssignTo(&last_sent_frame_);
-    ++num_sent_frames_;
-  }
-  PostSwapBuffersComplete();
-  client_->DidSwapBuffers();
-}
-
-void FakeOutputSurface::BindFramebuffer() {
-  if (framebuffer_)
-    context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER,
-                                                    framebuffer_);
-  else
-    OutputSurface::BindFramebuffer();
-}
-
-bool FakeOutputSurface::BindToClient(OutputSurfaceClient* client) {
-  if (OutputSurface::BindToClient(client)) {
-    client_ = client;
-    return true;
-  } else {
-    return false;
-  }
-}
-
-void FakeOutputSurface::SetTreeActivationCallback(
-    const base::Closure& callback) {
-  DCHECK(client_);
-  client_->SetTreeActivationCallback(callback);
-}
-
-void FakeOutputSurface::ReturnResource(unsigned id, CompositorFrameAck* ack) {
-  TransferableResourceArray::iterator it;
-  for (it = resources_held_by_parent_.begin();
-       it != resources_held_by_parent_.end();
-       ++it) {
-    if (it->id == id)
-      break;
-  }
-  DCHECK(it != resources_held_by_parent_.end());
-  ack->resources.push_back(it->ToReturnedResource());
-  resources_held_by_parent_.erase(it);
-}
-
-bool FakeOutputSurface::HasExternalStencilTest() const {
-  return has_external_stencil_test_;
-}
-
-}  // namespace cc
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
deleted file mode 100644
index b42024d..0000000
--- a/cc/test/fake_output_surface.h
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_TEST_FAKE_OUTPUT_SURFACE_H_
-#define CC_TEST_FAKE_OUTPUT_SURFACE_H_
-
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/time/time.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/software_output_device.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-
-namespace cc {
-
-class FakeOutputSurface : public OutputSurface {
- public:
-  ~FakeOutputSurface() override;
-
-  static scoped_ptr<FakeOutputSurface> Create3d() {
-    return make_scoped_ptr(new FakeOutputSurface(
-        TestContextProvider::Create(), TestContextProvider::Create(), false));
-  }
-
-  static scoped_ptr<FakeOutputSurface> Create3d(
-      scoped_refptr<ContextProvider> context_provider) {
-    return make_scoped_ptr(new FakeOutputSurface(context_provider, false));
-  }
-
-  static scoped_ptr<FakeOutputSurface> Create3d(
-      scoped_refptr<ContextProvider> context_provider,
-      scoped_refptr<ContextProvider> worker_context_provider) {
-    return make_scoped_ptr(new FakeOutputSurface(
-        context_provider, worker_context_provider, false));
-  }
-
-  static scoped_ptr<FakeOutputSurface> Create3d(
-      scoped_ptr<TestWebGraphicsContext3D> context) {
-    return make_scoped_ptr(new FakeOutputSurface(
-        TestContextProvider::Create(context.Pass()), false));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateSoftware(
-      scoped_ptr<SoftwareOutputDevice> software_device) {
-    return make_scoped_ptr(new FakeOutputSurface(software_device.Pass(),
-                                                 false));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateDelegating3d() {
-    return make_scoped_ptr(new FakeOutputSurface(
-        TestContextProvider::Create(), TestContextProvider::Create(), true));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateDelegating3d(
-      scoped_refptr<TestContextProvider> context_provider) {
-    return make_scoped_ptr(new FakeOutputSurface(context_provider, true));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateDelegating3d(
-      scoped_ptr<TestWebGraphicsContext3D> context) {
-    return make_scoped_ptr(new FakeOutputSurface(
-        TestContextProvider::Create(context.Pass()), true));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateDelegatingSoftware(
-      scoped_ptr<SoftwareOutputDevice> software_device) {
-    return make_scoped_ptr(
-        new FakeOutputSurface(software_device.Pass(), true));
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateDeferredGL(
-      scoped_ptr<SoftwareOutputDevice> software_device,
-      bool delegated_rendering) {
-    scoped_ptr<FakeOutputSurface> result(
-        new FakeOutputSurface(software_device.Pass(), delegated_rendering));
-    result->capabilities_.deferred_gl_initialization = true;
-    return result.Pass();
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateAlwaysDrawAndSwap3d() {
-    scoped_ptr<FakeOutputSurface> surface(Create3d());
-    surface->capabilities_.draw_and_swap_full_viewport_every_frame = true;
-    return surface.Pass();
-  }
-
-  static scoped_ptr<FakeOutputSurface> CreateOffscreen(
-      scoped_ptr<TestWebGraphicsContext3D> context) {
-    scoped_ptr<FakeOutputSurface> surface(new FakeOutputSurface(
-        TestContextProvider::Create(context.Pass()), false));
-    surface->capabilities_.uses_default_gl_framebuffer = false;
-    return surface.Pass();
-  }
-
-  CompositorFrame& last_sent_frame() { return last_sent_frame_; }
-  size_t num_sent_frames() { return num_sent_frames_; }
-
-  void SwapBuffers(CompositorFrame* frame) override;
-
-  bool BindToClient(OutputSurfaceClient* client) override;
-
-  void set_framebuffer(unsigned framebuffer) { framebuffer_ = framebuffer; }
-  void BindFramebuffer() override;
-
-  using OutputSurface::ReleaseGL;
-  using OutputSurface::InitializeAndSetContext3d;
-
-  void SetTreeActivationCallback(const base::Closure& callback);
-
-  const TransferableResourceArray& resources_held_by_parent() {
-    return resources_held_by_parent_;
-  }
-
-  void ReturnResource(unsigned id, CompositorFrameAck* ack);
-
-  bool HasExternalStencilTest() const override;
-
-  void set_has_external_stencil_test(bool has_test) {
-    has_external_stencil_test_ = has_test;
-  }
-
-  gfx::Rect last_swap_rect() const {
-    return last_swap_rect_;
-  }
-
- protected:
-  FakeOutputSurface(
-      scoped_refptr<ContextProvider> context_provider,
-      bool delegated_rendering);
-
-  FakeOutputSurface(scoped_refptr<ContextProvider> context_provider,
-                    scoped_refptr<ContextProvider> worker_context_provider,
-                    bool delegated_rendering);
-
-  FakeOutputSurface(scoped_ptr<SoftwareOutputDevice> software_device,
-                    bool delegated_rendering);
-
-  FakeOutputSurface(
-      scoped_refptr<ContextProvider> context_provider,
-      scoped_ptr<SoftwareOutputDevice> software_device,
-      bool delegated_rendering);
-
-  OutputSurfaceClient* client_;
-  CompositorFrame last_sent_frame_;
-  size_t num_sent_frames_;
-  bool has_external_stencil_test_;
-  unsigned framebuffer_;
-  TransferableResourceArray resources_held_by_parent_;
-  gfx::Rect last_swap_rect_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAKE_OUTPUT_SURFACE_H_
diff --git a/cc/test/fake_output_surface_client.cc b/cc/test/fake_output_surface_client.cc
deleted file mode 100644
index 073a29f..0000000
--- a/cc/test/fake_output_surface_client.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/output/output_surface.h"
-#include "cc/test/fake_output_surface_client.h"
-
-namespace cc {
-
-void FakeOutputSurfaceClient::DeferredInitialize() {
-  deferred_initialize_called_ = true;
-}
-
-void FakeOutputSurfaceClient::ReleaseGL() {
-  if (output_surface_)
-    output_surface_->ReleaseContextProvider();
-}
-
-void FakeOutputSurfaceClient::DidSwapBuffers() {
-  swap_count_++;
-}
-
-void FakeOutputSurfaceClient::DidLoseOutputSurface() {
-  did_lose_output_surface_called_ = true;
-}
-
-void FakeOutputSurfaceClient::SetMemoryPolicy(
-    const ManagedMemoryPolicy& policy) {
-  memory_policy_ = policy;
-}
-
-}  // namespace cc
diff --git a/cc/test/fake_output_surface_client.h b/cc/test/fake_output_surface_client.h
deleted file mode 100644
index 310842d..0000000
--- a/cc/test/fake_output_surface_client.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_FAKE_OUTPUT_SURFACE_CLIENT_H_
-#define CC_TEST_FAKE_OUTPUT_SURFACE_CLIENT_H_
-
-#include "cc/output/managed_memory_policy.h"
-#include "cc/output/output_surface_client.h"
-
-namespace cc {
-
-class OutputSurface;
-
-class FakeOutputSurfaceClient : public OutputSurfaceClient {
- public:
-  FakeOutputSurfaceClient()
-      : output_surface_(NULL),
-        swap_count_(0),
-        deferred_initialize_called_(false),
-        did_lose_output_surface_called_(false),
-        memory_policy_(0) {}
-
-  explicit FakeOutputSurfaceClient(OutputSurface* output_surface)
-      : output_surface_(output_surface),
-        swap_count_(0),
-        deferred_initialize_called_(false),
-        did_lose_output_surface_called_(false),
-        memory_policy_(0) {}
-
-  void DeferredInitialize() override;
-  void ReleaseGL() override;
-  void CommitVSyncParameters(base::TimeTicks timebase,
-                             base::TimeDelta interval) override {}
-  void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override {}
-  void DidSwapBuffers() override;
-  void DidSwapBuffersComplete() override {}
-  void ReclaimResources(const CompositorFrameAck* ack) override {}
-  void DidLoseOutputSurface() override;
-  void SetExternalDrawConstraints(
-      const gfx::Transform& transform,
-      const gfx::Rect& viewport,
-      const gfx::Rect& clip,
-      const gfx::Rect& viewport_rect_for_tile_priority,
-      const gfx::Transform& transform_for_tile_priority,
-      bool resourceless_software_draw) override {}
-  void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override;
-  void SetTreeActivationCallback(const base::Closure&) override {}
-
-  int swap_count() { return swap_count_; }
-
-  bool deferred_initialize_called() {
-    return deferred_initialize_called_;
-  }
-
-  bool did_lose_output_surface_called() {
-    return did_lose_output_surface_called_;
-  }
-
-  const ManagedMemoryPolicy& memory_policy() const { return memory_policy_; }
-
- private:
-  OutputSurface* output_surface_;
-  int swap_count_;
-  bool deferred_initialize_called_;
-  bool did_lose_output_surface_called_;
-  ManagedMemoryPolicy memory_policy_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAKE_OUTPUT_SURFACE_CLIENT_H_
diff --git a/cc/test/fake_renderer_client.cc b/cc/test/fake_renderer_client.cc
deleted file mode 100644
index f45831d..0000000
--- a/cc/test/fake_renderer_client.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/fake_renderer_client.h"
-
-namespace cc {
-
-FakeRendererClient::FakeRendererClient()
-    : set_full_root_layer_damage_count_(0) {
-}
-
-void FakeRendererClient::SetFullRootLayerDamage() {
-  ++set_full_root_layer_damage_count_;
-}
-
-}  // namespace cc
diff --git a/cc/test/fake_renderer_client.h b/cc/test/fake_renderer_client.h
deleted file mode 100644
index 772b44a..0000000
--- a/cc/test/fake_renderer_client.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_FAKE_RENDERER_CLIENT_H_
-#define CC_TEST_FAKE_RENDERER_CLIENT_H_
-
-#include "cc/output/renderer.h"
-
-namespace cc {
-
-class FakeRendererClient : public RendererClient {
- public:
-  FakeRendererClient();
-
-  // RendererClient methods.
-  void SetFullRootLayerDamage() override;
-
-  // Methods added for test.
-  int set_full_root_layer_damage_count() const {
-    return set_full_root_layer_damage_count_;
-  }
-
- private:
-  int set_full_root_layer_damage_count_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAKE_RENDERER_CLIENT_H_
diff --git a/cc/test/fake_rendering_stats_instrumentation.h b/cc/test/fake_rendering_stats_instrumentation.h
deleted file mode 100644
index ebe129b..0000000
--- a/cc/test/fake_rendering_stats_instrumentation.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_FAKE_RENDERING_STATS_INSTRUMENTATION_H_
-#define CC_TEST_FAKE_RENDERING_STATS_INSTRUMENTATION_H_
-
-#include "cc/debug/rendering_stats_instrumentation.h"
-
-namespace cc {
-
-class FakeRenderingStatsInstrumentation : public RenderingStatsInstrumentation {
- public:
-  FakeRenderingStatsInstrumentation() {}
-  ~FakeRenderingStatsInstrumentation() override {}
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_FAKE_RENDERING_STATS_INSTRUMENTATION_H_
diff --git a/cc/test/geometry_test_utils.cc b/cc/test/geometry_test_utils.cc
deleted file mode 100644
index 9bf5811..0000000
--- a/cc/test/geometry_test_utils.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/geometry_test_utils.h"
-
-#include "base/logging.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-// NOTE: even though transform data types use double precision, we only check
-// for equality within single-precision error bounds because many transforms
-// originate from single-precision data types such as quads/rects/etc.
-
-void ExpectTransformationMatrixEq(const gfx::Transform& expected,
-                                  const gfx::Transform& actual) {
-  EXPECT_FLOAT_EQ((expected).matrix().get(0, 0), (actual).matrix().get(0, 0));
-  EXPECT_FLOAT_EQ((expected).matrix().get(1, 0), (actual).matrix().get(1, 0));
-  EXPECT_FLOAT_EQ((expected).matrix().get(2, 0), (actual).matrix().get(2, 0));
-  EXPECT_FLOAT_EQ((expected).matrix().get(3, 0), (actual).matrix().get(3, 0));
-  EXPECT_FLOAT_EQ((expected).matrix().get(0, 1), (actual).matrix().get(0, 1));
-  EXPECT_FLOAT_EQ((expected).matrix().get(1, 1), (actual).matrix().get(1, 1));
-  EXPECT_FLOAT_EQ((expected).matrix().get(2, 1), (actual).matrix().get(2, 1));
-  EXPECT_FLOAT_EQ((expected).matrix().get(3, 1), (actual).matrix().get(3, 1));
-  EXPECT_FLOAT_EQ((expected).matrix().get(0, 2), (actual).matrix().get(0, 2));
-  EXPECT_FLOAT_EQ((expected).matrix().get(1, 2), (actual).matrix().get(1, 2));
-  EXPECT_FLOAT_EQ((expected).matrix().get(2, 2), (actual).matrix().get(2, 2));
-  EXPECT_FLOAT_EQ((expected).matrix().get(3, 2), (actual).matrix().get(3, 2));
-  EXPECT_FLOAT_EQ((expected).matrix().get(0, 3), (actual).matrix().get(0, 3));
-  EXPECT_FLOAT_EQ((expected).matrix().get(1, 3), (actual).matrix().get(1, 3));
-  EXPECT_FLOAT_EQ((expected).matrix().get(2, 3), (actual).matrix().get(2, 3));
-  EXPECT_FLOAT_EQ((expected).matrix().get(3, 3), (actual).matrix().get(3, 3));
-}
-
-gfx::Transform Inverse(const gfx::Transform& transform) {
-  gfx::Transform result(gfx::Transform::kSkipInitialization);
-  bool inverted_successfully = transform.GetInverse(&result);
-  DCHECK(inverted_successfully);
-  return result;
-}
-
-}  // namespace cc
diff --git a/cc/test/geometry_test_utils.h b/cc/test/geometry_test_utils.h
deleted file mode 100644
index 3f3197c..0000000
--- a/cc/test/geometry_test_utils.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_TEST_GEOMETRY_TEST_UTILS_H_
-#define CC_TEST_GEOMETRY_TEST_UTILS_H_
-
-namespace gfx {
-class Transform;
-}
-
-namespace cc {
-
-// These are macros instead of functions so that we get useful line numbers
-// where a test failed.
-#define EXPECT_FLOAT_RECT_EQ(expected, actual) \
-do { \
-  EXPECT_FLOAT_EQ((expected).x(), (actual).x()); \
-  EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
-  EXPECT_FLOAT_EQ((expected).width(), (actual).width()); \
-  EXPECT_FLOAT_EQ((expected).height(), (actual).height()); \
-} while (false)
-
-#define EXPECT_RECT_NEAR(expected, actual, abs_error) \
-do { \
-  EXPECT_NEAR((expected).x(), (actual).x(), (abs_error)); \
-  EXPECT_NEAR((expected).y(), (actual).y(), (abs_error)); \
-  EXPECT_NEAR((expected).width(), (actual).width(), (abs_error)); \
-  EXPECT_NEAR((expected).height(), (actual).height(), (abs_error)); \
-} while (false)
-
-#define EXPECT_POINT3F_EQ(expected, actual)      \
-do {                                             \
-  EXPECT_FLOAT_EQ((expected).x(), (actual).x()); \
-  EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
-  EXPECT_FLOAT_EQ((expected).z(), (actual).z()); \
-} while (false)
-
-#define EXPECT_VECTOR_EQ(expected, actual) \
-do { \
-  EXPECT_EQ((expected).x(), (actual).x()); \
-  EXPECT_EQ((expected).y(), (actual).y()); \
-} while (false)
-
-#define EXPECT_VECTOR2DF_EQ(expected, actual) \
-do { \
-  EXPECT_FLOAT_EQ((expected).x(), (actual).x()); \
-  EXPECT_FLOAT_EQ((expected).y(), (actual).y()); \
-} while (false)
-
-#define EXPECT_VECTOR2DF_NEAR(expected, actual, abs_error)  \
-  do {                                                      \
-    EXPECT_NEAR((expected).x(), (actual).x(), (abs_error)); \
-    EXPECT_NEAR((expected).y(), (actual).y(), (abs_error)); \
-  } while (false)
-
-#define EXPECT_FLOAT_ARRAY_EQ(expected, actual, count) \
-do { \
-  for (int i = 0; i < count; i++) { \
-    EXPECT_FLOAT_EQ((expected)[i], (actual)[i]); \
-  } \
-} while (false)
-
-// This is a function rather than a macro because when this is included as a
-// macro in bulk, it causes a significant slow-down in compilation time. This
-// problem exists with both gcc and clang, and bugs have been filed at
-// http://llvm.org/bugs/show_bug.cgi?id=13651
-// and http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54337
-void ExpectTransformationMatrixEq(const gfx::Transform& expected,
-                                  const gfx::Transform& actual);
-
-#define EXPECT_TRANSFORMATION_MATRIX_EQ(expected, actual) \
-  do {                                                    \
-    SCOPED_TRACE("");                                     \
-    ExpectTransformationMatrixEq(expected, actual);       \
-  } while (false)
-
-// Should be used in test code only, for convenience. Production code should use
-// the gfx::Transform::GetInverse() API.
-gfx::Transform Inverse(const gfx::Transform& transform);
-
-}  // namespace cc
-
-#endif  // CC_TEST_GEOMETRY_TEST_UTILS_H_
diff --git a/cc/test/impl_side_painting_settings.h b/cc/test/impl_side_painting_settings.h
deleted file mode 100644
index 1ea7e78..0000000
--- a/cc/test/impl_side_painting_settings.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_IMPL_SIDE_PAINTING_SETTINGS_H_
-#define CC_TEST_IMPL_SIDE_PAINTING_SETTINGS_H_
-
-#include "cc/trees/layer_tree_settings.h"
-
-namespace cc {
-
-class ImplSidePaintingSettings : public LayerTreeSettings {
- public:
-  ImplSidePaintingSettings() {
-    impl_side_painting = true;
-  }
-
-  explicit ImplSidePaintingSettings(int interest_rect_tiles) {
-    impl_side_painting = true;
-    max_tiles_for_interest_area = interest_rect_tiles;
-  }
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_IMPL_SIDE_PAINTING_SETTINGS_H_
diff --git a/cc/test/mock_occlusion_tracker.h b/cc/test/mock_occlusion_tracker.h
deleted file mode 100644
index 649eb76..0000000
--- a/cc/test/mock_occlusion_tracker.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_MOCK_OCCLUSION_TRACKER_H_
-#define CC_TEST_MOCK_OCCLUSION_TRACKER_H_
-
-#include "cc/trees/occlusion_tracker.h"
-
-namespace cc {
-
-template <typename LayerType>
-class MockOcclusionTracker : public OcclusionTracker<LayerType> {
-  // This class is used for testing only. It fakes just enough information to
-  // calculate unoccluded content rect and unoccluded contributing surface
-  // content rect. It calls the helper function of occlusion tracker to avoid
-  // DCHECKs since testing environment won't be set up properly to pass those.
- public:
-  MockOcclusionTracker()
-      : OcclusionTracker<LayerType>(gfx::Rect(0, 0, 1000, 1000)) {
-    typename OcclusionTracker<LayerType>::StackObject stack_obj;
-    OcclusionTracker<LayerType>::stack_.push_back(stack_obj);
-    OcclusionTracker<LayerType>::stack_.push_back(stack_obj);
-  }
-
-  explicit MockOcclusionTracker(const gfx::Rect& screen_scissor_rect)
-      : OcclusionTracker<LayerType>(screen_scissor_rect) {
-    typename OcclusionTracker<LayerType>::StackObject stack_obj;
-    OcclusionTracker<LayerType>::stack_.push_back(stack_obj);
-    OcclusionTracker<LayerType>::stack_.push_back(stack_obj);
-  }
-
-  void set_occluded_target_rect(const gfx::Rect& occluded) {
-    OcclusionTracker<LayerType>::stack_.back().occlusion_from_inside_target =
-        occluded;
-  }
-
-  void set_occluded_target_rect_for_contributing_surface(
-      const gfx::Rect& occluded) {
-    OcclusionTracker<
-        LayerType>::stack_[OcclusionTracker<LayerType>::stack_.size() - 2]
-        .occlusion_from_inside_target = occluded;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockOcclusionTracker);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_MOCK_OCCLUSION_TRACKER_H_
diff --git a/cc/test/ordered_simple_task_runner.cc b/cc/test/ordered_simple_task_runner.cc
deleted file mode 100644
index 9fc22ad..0000000
--- a/cc/test/ordered_simple_task_runner.cc
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/ordered_simple_task_runner.h"
-
-#include <limits>
-#include <set>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include "base/auto_reset.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-
-#define TRACE_TASK(function, task) \
-  TRACE_EVENT_INSTANT1(            \
-      "cc", function, TRACE_EVENT_SCOPE_THREAD, "task", task.AsValue());
-
-#define TRACE_TASK_RUN(function, tag, task)
-
-namespace cc {
-
-// TestOrderablePendingTask implementation
-TestOrderablePendingTask::TestOrderablePendingTask()
-    : base::TestPendingTask(),
-      task_id_(TestOrderablePendingTask::task_id_counter++) {
-}
-
-TestOrderablePendingTask::TestOrderablePendingTask(
-    const tracked_objects::Location& location,
-    const base::Closure& task,
-    base::TimeTicks post_time,
-    base::TimeDelta delay,
-    TestNestability nestability)
-    : base::TestPendingTask(location, task, post_time, delay, nestability),
-      task_id_(TestOrderablePendingTask::task_id_counter++) {
-}
-
-size_t TestOrderablePendingTask::task_id_counter = 0;
-
-TestOrderablePendingTask::~TestOrderablePendingTask() {
-}
-
-bool TestOrderablePendingTask::operator==(
-    const TestOrderablePendingTask& other) const {
-  return task_id_ == other.task_id_;
-}
-
-bool TestOrderablePendingTask::operator<(
-    const TestOrderablePendingTask& other) const {
-  if (*this == other)
-    return false;
-
-  if (GetTimeToRun() == other.GetTimeToRun()) {
-    return task_id_ < other.task_id_;
-  }
-  return ShouldRunBefore(other);
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-TestOrderablePendingTask::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-void TestOrderablePendingTask::AsValueInto(
-    base::trace_event::TracedValue* state) const {
-  state->SetInteger("id", task_id_);
-  state->SetInteger("run_at", GetTimeToRun().ToInternalValue());
-  state->SetString("posted_from", location.ToString());
-}
-
-OrderedSimpleTaskRunner::OrderedSimpleTaskRunner()
-    : advance_now_(true),
-      now_src_(TestNowSource::Create(0)),
-      inside_run_tasks_until_(false) {
-}
-
-OrderedSimpleTaskRunner::OrderedSimpleTaskRunner(
-    scoped_refptr<TestNowSource> now_src,
-    bool advance_now)
-    : advance_now_(advance_now),
-      now_src_(now_src),
-      max_tasks_(kAbsoluteMaxTasks),
-      inside_run_tasks_until_(false) {
-}
-
-OrderedSimpleTaskRunner::~OrderedSimpleTaskRunner() {}
-
-// base::TestSimpleTaskRunner implementation
-bool OrderedSimpleTaskRunner::PostDelayedTask(
-    const tracked_objects::Location& from_here,
-    const base::Closure& task,
-    base::TimeDelta delay) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  TestOrderablePendingTask pt(
-      from_here, task, now_src_->Now(), delay, base::TestPendingTask::NESTABLE);
-
-  TRACE_TASK("OrderedSimpleTaskRunner::PostDelayedTask", pt);
-  pending_tasks_.insert(pt);
-  return true;
-}
-
-bool OrderedSimpleTaskRunner::PostNonNestableDelayedTask(
-    const tracked_objects::Location& from_here,
-    const base::Closure& task,
-    base::TimeDelta delay) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  TestOrderablePendingTask pt(from_here,
-                              task,
-                              now_src_->Now(),
-                              delay,
-                              base::TestPendingTask::NON_NESTABLE);
-
-  TRACE_TASK("OrderedSimpleTaskRunner::PostNonNestableDelayedTask", pt);
-  pending_tasks_.insert(pt);
-  return true;
-}
-
-bool OrderedSimpleTaskRunner::RunsTasksOnCurrentThread() const {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  return true;
-}
-
-size_t OrderedSimpleTaskRunner::NumPendingTasks() const {
-  return pending_tasks_.size();
-}
-
-bool OrderedSimpleTaskRunner::HasPendingTasks() const {
-  return pending_tasks_.size() > 0;
-}
-
-base::TimeTicks OrderedSimpleTaskRunner::NextTaskTime() {
-  if (pending_tasks_.size() <= 0) {
-    return TestNowSource::kAbsoluteMaxNow;
-  }
-
-  return pending_tasks_.begin()->GetTimeToRun();
-}
-
-base::TimeDelta OrderedSimpleTaskRunner::DelayToNextTaskTime() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (pending_tasks_.size() <= 0) {
-    return TestNowSource::kAbsoluteMaxNow - base::TimeTicks();
-  }
-
-  base::TimeDelta delay = NextTaskTime() - now_src_->Now();
-  if (delay > base::TimeDelta())
-    return delay;
-  return base::TimeDelta();
-}
-
-const size_t OrderedSimpleTaskRunner::kAbsoluteMaxTasks =
-    std::numeric_limits<size_t>::max();
-
-bool OrderedSimpleTaskRunner::RunTasksWhile(
-    base::Callback<bool(void)> condition) {
-  std::vector<base::Callback<bool(void)>> conditions(1);
-  conditions[0] = condition;
-  return RunTasksWhile(conditions);
-}
-
-bool OrderedSimpleTaskRunner::RunTasksWhile(
-    const std::vector<base::Callback<bool(void)>>& conditions) {
-  TRACE_EVENT2("cc",
-               "OrderedSimpleTaskRunner::RunPendingTasks",
-               "this",
-               AsValue(),
-               "nested",
-               inside_run_tasks_until_);
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (inside_run_tasks_until_)
-    return true;
-
-  base::AutoReset<bool> reset_inside_run_tasks_until_(&inside_run_tasks_until_,
-                                                      true);
-
-  // Make a copy so we can append some extra run checks.
-  std::vector<base::Callback<bool(void)>> modifiable_conditions(conditions);
-
-  // Provide a timeout base on number of tasks run so this doesn't loop
-  // forever.
-  modifiable_conditions.push_back(TaskRunCountBelow(max_tasks_));
-
-  // If to advance now or not
-  if (!advance_now_) {
-    modifiable_conditions.push_back(NowBefore(now_src_->Now()));
-  } else {
-    modifiable_conditions.push_back(AdvanceNow());
-  }
-
-  while (pending_tasks_.size() > 0) {
-    // Check if we should continue to run pending tasks.
-    bool condition_success = true;
-    for (std::vector<base::Callback<bool(void)>>::iterator it =
-             modifiable_conditions.begin();
-         it != modifiable_conditions.end();
-         it++) {
-      condition_success = it->Run();
-      if (!condition_success)
-        break;
-    }
-
-    // Conditions could modify the pending task length, so we need to recheck
-    // that there are tasks to run.
-    if (!condition_success || !HasPendingTasks()) {
-      break;
-    }
-
-    std::set<TestOrderablePendingTask>::iterator task_to_run =
-        pending_tasks_.begin();
-    {
-      TRACE_EVENT1("cc",
-                   "OrderedSimpleTaskRunner::RunPendingTasks running",
-                   "task",
-                   task_to_run->AsValue());
-      task_to_run->task.Run();
-    }
-
-    pending_tasks_.erase(task_to_run);
-  }
-
-  return HasPendingTasks();
-}
-
-bool OrderedSimpleTaskRunner::RunPendingTasks() {
-  return RunTasksWhile(TaskExistedInitially());
-}
-
-bool OrderedSimpleTaskRunner::RunUntilIdle() {
-  return RunTasksWhile(std::vector<base::Callback<bool(void)>>());
-}
-
-bool OrderedSimpleTaskRunner::RunUntilTime(base::TimeTicks time) {
-  // If we are not auto advancing, force now forward to the time.
-  if (!advance_now_ && now_src_->Now() < time)
-    now_src_->SetNow(time);
-
-  // Run tasks
-  bool result = RunTasksWhile(NowBefore(time));
-
-  // If the next task is after the stopping time and auto-advancing now, then
-  // force time to be the stopping time.
-  if (!result && advance_now_ && now_src_->Now() < time) {
-    now_src_->SetNow(time);
-  }
-
-  return result;
-}
-
-bool OrderedSimpleTaskRunner::RunForPeriod(base::TimeDelta period) {
-  return RunUntilTime(now_src_->Now() + period);
-}
-
-// base::trace_event tracing functionality
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-OrderedSimpleTaskRunner::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-void OrderedSimpleTaskRunner::AsValueInto(
-    base::trace_event::TracedValue* state) const {
-  state->SetInteger("pending_tasks", pending_tasks_.size());
-
-  state->BeginArray("tasks");
-  for (std::set<TestOrderablePendingTask>::const_iterator it =
-           pending_tasks_.begin();
-       it != pending_tasks_.end();
-       ++it) {
-    state->BeginDictionary();
-    it->AsValueInto(state);
-    state->EndDictionary();
-  }
-  state->EndArray();
-
-  state->BeginDictionary("now_src");
-  now_src_->AsValueInto(state);
-  state->EndDictionary();
-}
-
-base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskRunCountBelow(
-    size_t max_tasks) {
-  return base::Bind(&OrderedSimpleTaskRunner::TaskRunCountBelowCallback,
-                    max_tasks,
-                    base::Owned(new size_t(0)));
-}
-
-bool OrderedSimpleTaskRunner::TaskRunCountBelowCallback(size_t max_tasks,
-                                                        size_t* tasks_run) {
-  return (*tasks_run)++ < max_tasks;
-}
-
-base::Callback<bool(void)> OrderedSimpleTaskRunner::TaskExistedInitially() {
-  // base::Bind takes a copy of pending_tasks_
-  return base::Bind(&OrderedSimpleTaskRunner::TaskExistedInitiallyCallback,
-                    base::Unretained(this),
-                    pending_tasks_);
-}
-
-bool OrderedSimpleTaskRunner::TaskExistedInitiallyCallback(
-    const std::set<TestOrderablePendingTask>& existing_tasks) {
-  return existing_tasks.find(*pending_tasks_.begin()) != existing_tasks.end();
-}
-
-base::Callback<bool(void)> OrderedSimpleTaskRunner::NowBefore(
-    base::TimeTicks stop_at) {
-  return base::Bind(&OrderedSimpleTaskRunner::NowBeforeCallback,
-                    base::Unretained(this),
-                    stop_at);
-}
-bool OrderedSimpleTaskRunner::NowBeforeCallback(base::TimeTicks stop_at) {
-  return NextTaskTime() <= stop_at;
-}
-
-base::Callback<bool(void)> OrderedSimpleTaskRunner::AdvanceNow() {
-  return base::Bind(&OrderedSimpleTaskRunner::AdvanceNowCallback,
-                    base::Unretained(this));
-}
-
-bool OrderedSimpleTaskRunner::AdvanceNowCallback() {
-  base::TimeTicks next_task_time = NextTaskTime();
-  if (now_src_->Now() < next_task_time) {
-    now_src_->SetNow(next_task_time);
-  }
-  return true;
-}
-
-}  // namespace cc
diff --git a/cc/test/ordered_simple_task_runner.h b/cc/test/ordered_simple_task_runner.h
deleted file mode 100644
index 6848303..0000000
--- a/cc/test/ordered_simple_task_runner.h
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
-#define CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
-
-#include <limits>
-#include <set>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/compiler_specific.h"
-#include "base/logging.h"
-#include "base/test/test_simple_task_runner.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/test/test_now_source.h"
-
-namespace cc {
-
-// Subclass of TestPendingTask which has a unique ID for every task, supports
-// being used inside a std::set and has debug tracing support.
-class TestOrderablePendingTask : public base::TestPendingTask {
- public:
-  TestOrderablePendingTask();
-  TestOrderablePendingTask(const tracked_objects::Location& location,
-                           const base::Closure& task,
-                           base::TimeTicks post_time,
-                           base::TimeDelta delay,
-                           TestNestability nestability);
-  ~TestOrderablePendingTask();
-
-  // operators needed by std::set and comparison
-  bool operator==(const TestOrderablePendingTask& other) const;
-  bool operator<(const TestOrderablePendingTask& other) const;
-
-  // base::trace_event tracing functionality
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* state) const;
-
- private:
-  static size_t task_id_counter;
-  const size_t task_id_;
-};
-
-// This runs pending tasks based on task's post_time + delay.
-// We should not execute a delayed task sooner than some of the queued tasks
-// which don't have a delay even though it is queued early.
-class OrderedSimpleTaskRunner : public base::SingleThreadTaskRunner {
- public:
-  OrderedSimpleTaskRunner();
-  OrderedSimpleTaskRunner(scoped_refptr<TestNowSource> now_src,
-                          bool advance_now);
-
-  // base::TestSimpleTaskRunner implementation:
-  bool PostDelayedTask(const tracked_objects::Location& from_here,
-                       const base::Closure& task,
-                       base::TimeDelta delay) override;
-  bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
-                                  const base::Closure& task,
-                                  base::TimeDelta delay) override;
-
-  bool RunsTasksOnCurrentThread() const override;
-
-  // Set a maximum number of tasks to run at once. Useful as a timeout to
-  // prevent infinite task loops.
-  static const size_t kAbsoluteMaxTasks;
-  void SetRunTaskLimit(size_t max_tasks) { max_tasks_ = max_tasks; }
-  void ClearRunTaskLimit() { max_tasks_ = kAbsoluteMaxTasks; }
-
-  // Allow task runner to advance now when running tasks.
-  void SetAutoAdvanceNowToPendingTasks(bool advance_now) {
-    advance_now_ = advance_now;
-  }
-
-  size_t NumPendingTasks() const;
-  bool HasPendingTasks() const;
-  base::TimeTicks NextTaskTime();
-  base::TimeDelta DelayToNextTaskTime();
-
-  // Run tasks while the callback returns true or too many tasks have been run.
-  // Returns true if there are still pending tasks left.
-  bool RunTasksWhile(base::Callback<bool(void)> condition);
-
-  // Run tasks while *all* of the callbacks return true or too many tasks have
-  // been run. Exits on the *first* condition which returns false, skipping
-  // calling all remaining conditions. Conditions can have side effects,
-  // including modifying the task queue.
-  // Returns true if there are still pending tasks left.
-  bool RunTasksWhile(const std::vector<base::Callback<bool(void)>>& conditions);
-
-  // Convenience functions to run tasks with common conditions.
-
-  // Run tasks which existed at the start of this call.
-  // Return code indicates tasks still exist to run.
-  bool RunPendingTasks();
-  // Keep running tasks until no tasks are left.
-  // Return code indicates tasks still exist to run which also indicates if
-  // runner reached idle.
-  bool RunUntilIdle();
-  // Keep running tasks until given time period.
-  // Return code indicates tasks still exist to run.
-  bool RunUntilTime(base::TimeTicks time);
-  bool RunForPeriod(base::TimeDelta period);
-
-  // base::trace_event tracing functionality
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  virtual void AsValueInto(base::trace_event::TracedValue* state) const;
-
-  // Common conditions to run for, exposed publicly to allow external users to
-  // use their own combinations.
-  // -------------------------------------------------------------------------
-
-  // Keep running until the given number of tasks have run.
-  // You generally shouldn't use this check as it will cause your tests to fail
-  // when code is changed adding a new task. It is useful as a "timeout" type
-  // solution.
-  base::Callback<bool(void)> TaskRunCountBelow(size_t max_tasks);
-
-  // Keep running until a task which didn't exist initially would run.
-  base::Callback<bool(void)> TaskExistedInitially();
-
-  // Stop running tasks when NextTaskTime() >= stop_at
-  base::Callback<bool(void)> NowBefore(base::TimeTicks stop_at);
-
-  // Advance Now() to the next task to run.
-  base::Callback<bool(void)> AdvanceNow();
-
- protected:
-  static bool TaskRunCountBelowCallback(size_t max_tasks, size_t* task_run);
-  bool TaskExistedInitiallyCallback(
-      const std::set<TestOrderablePendingTask>& existing_tasks);
-  bool NowBeforeCallback(base::TimeTicks stop_at);
-  bool AdvanceNowCallback();
-
-  ~OrderedSimpleTaskRunner() override;
-
-  base::ThreadChecker thread_checker_;
-
-  bool advance_now_;
-  scoped_refptr<TestNowSource> now_src_;
-
-  size_t max_tasks_;
-
-  bool inside_run_tasks_until_;
-  std::set<TestOrderablePendingTask> pending_tasks_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(OrderedSimpleTaskRunner);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_ORDERED_SIMPLE_TASK_RUNNER_H_
diff --git a/cc/test/ordered_simple_task_runner_unittest.cc b/cc/test/ordered_simple_task_runner_unittest.cc
deleted file mode 100644
index 568cbb5..0000000
--- a/cc/test/ordered_simple_task_runner_unittest.cc
+++ /dev/null
@@ -1,446 +0,0 @@
-// Copyright 2014 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.
-
-#include <string>
-
-#include "base/cancelable_callback.h"
-#include "base/format_macros.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/strings/stringprintf.h"
-#include "base/test/test_pending_task.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-// We pass EXPECT_TRUE / EXPECT_FALSE macros rather than a boolean as on some
-// compilers EXPECT_EQ(false, XXXX) fails to compile as  gtest tries to convert
-// the false value to null causing a -Werror=conversion-null error.
-#define RUN_AND_CHECK_RESULT(                             \
-    tasks_remain_expect_macro, run_func, expected_result) \
-  tasks_remain_expect_macro(task_runner_->run_func);      \
-  EXPECT_EQ(expected_result, executed_tasks_);            \
-  executed_tasks_ = "";
-
-namespace {
-
-bool ReturnTrue() {
-  return true;
-}
-
-bool ReturnFalse() {
-  return false;
-}
-};
-
-namespace cc {
-
-TEST(TestOrderablePendingTask, Ordering) {
-  TestOrderablePendingTask a;
-  TestOrderablePendingTask b;
-  TestOrderablePendingTask c;
-
-  EXPECT_EQ(a, a);
-  EXPECT_EQ(b, b);
-  EXPECT_EQ(c, c);
-  EXPECT_LT(a, b);
-  EXPECT_LT(b, c);
-  EXPECT_LT(a, c);
-
-  TestOrderablePendingTask a2 = a;
-  EXPECT_EQ(a, a2);
-  EXPECT_LT(a2, b);
-  EXPECT_LT(b, c);
-  EXPECT_LT(a2, c);
-}
-
-class OrderedSimpleTaskRunnerTest : public testing::Test {
- public:
-  OrderedSimpleTaskRunnerTest()
-      : now_src_(TestNowSource::Create(base::TimeTicks())) {
-    task_runner_ = new OrderedSimpleTaskRunner(now_src_, true);
-  }
-  ~OrderedSimpleTaskRunnerTest() override {}
-
- protected:
-  std::string executed_tasks_;
-  scoped_refptr<TestNowSource> now_src_;
-  scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
-
-  void PostTask(int task_num, base::TimeDelta delay) {
-    base::Closure test_task = base::Bind(&OrderedSimpleTaskRunnerTest::Task,
-                                         base::Unretained(this),
-                                         task_num);
-    task_runner_->PostDelayedTask(FROM_HERE, test_task, delay);
-  }
-
-  void PostTaskWhichPostsInstantTask(int task_num, base::TimeDelta delay) {
-    base::Closure test_task =
-        base::Bind(&OrderedSimpleTaskRunnerTest::TaskWhichPostsInstantTask,
-                   base::Unretained(this),
-                   task_num);
-    task_runner_->PostDelayedTask(FROM_HERE, test_task, delay);
-  }
-
-  void PostTaskWhichPostsDelayedTask(int task_num,
-                                     base::TimeDelta delay1,
-                                     base::TimeDelta delay2) {
-    base::Closure test_task =
-        base::Bind(&OrderedSimpleTaskRunnerTest::TaskWhichPostsDelayedTask,
-                   base::Unretained(this),
-                   task_num,
-                   delay2);
-    task_runner_->PostDelayedTask(FROM_HERE, test_task, delay1);
-  }
-
-  void PostTaskWhichCallsRun(int task_num, base::TimeDelta delay) {
-    base::Closure test_task =
-        base::Bind(&OrderedSimpleTaskRunnerTest::TaskWhichCallsRun,
-                   base::Unretained(this),
-                   task_num);
-    task_runner_->PostDelayedTask(FROM_HERE, test_task, delay);
-  }
-
-  void PostTaskWhichPostsTaskAgain(int task_num, base::TimeDelta delay) {
-    base::Closure test_task =
-        base::Bind(&OrderedSimpleTaskRunnerTest::TaskWhichPostsAgain,
-                   base::Unretained(this),
-                   task_num,
-                   delay);
-    task_runner_->PostDelayedTask(FROM_HERE, test_task, delay);
-  }
-
- private:
-  void Task(int task_num) {
-    if (!executed_tasks_.empty())
-      executed_tasks_ += " ";
-    executed_tasks_ +=
-        base::StringPrintf("%d(%" PRId64 "ms)",
-                           task_num,
-                           now_src_->Now().ToInternalValue() /
-                               base::Time::kMicrosecondsPerMillisecond);
-  }
-
-  void TaskWhichPostsInstantTask(int task_num) {
-    Task(task_num);
-    PostTask(-task_num, base::TimeDelta());
-  }
-
-  void TaskWhichPostsDelayedTask(int task_num, base::TimeDelta delay) {
-    Task(task_num);
-    PostTask(-task_num, delay);
-  }
-
-  void TaskWhichCallsRun(int task_num) {
-    Task(task_num);
-    task_runner_->RunPendingTasks();
-  }
-
-  void TaskWhichPostsAgain(int task_num, base::TimeDelta delay) {
-    Task(task_num);
-    PostTaskWhichPostsTaskAgain(task_num, delay);
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(OrderedSimpleTaskRunnerTest);
-};
-
-TEST_F(OrderedSimpleTaskRunnerTest, SimpleOrderingTest) {
-  PostTask(1, base::TimeDelta());
-  PostTask(2, base::TimeDelta());
-  PostTask(3, base::TimeDelta());
-
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-
-  PostTask(4, base::TimeDelta());
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "4(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, SimpleOrderingTestPostingTasks) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(2, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta());
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunPendingTasks(), "-1(0ms) -2(0ms) -3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, SimpleOrderingTestPostingDelayedTasks) {
-  PostTaskWhichPostsDelayedTask(
-      1, base::TimeDelta(), base::TimeDelta::FromMilliseconds(1));
-  PostTaskWhichPostsDelayedTask(
-      2, base::TimeDelta(), base::TimeDelta::FromMilliseconds(1));
-  PostTaskWhichPostsDelayedTask(
-      3, base::TimeDelta(), base::TimeDelta::FromMilliseconds(1));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunPendingTasks(), "-1(1ms) -2(1ms) -3(1ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest,
-       SimpleOrderingTestPostingReordingDelayedTasks) {
-  PostTaskWhichPostsDelayedTask(1,
-                                base::TimeDelta::FromMilliseconds(1),
-                                base::TimeDelta::FromMilliseconds(20));
-  PostTaskWhichPostsDelayedTask(2,
-                                base::TimeDelta::FromMilliseconds(2),
-                                base::TimeDelta::FromMilliseconds(5));
-  PostTaskWhichPostsDelayedTask(3,
-                                base::TimeDelta::FromMilliseconds(3),
-                                base::TimeDelta::FromMilliseconds(5));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(1ms) 2(2ms) 3(3ms)");
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunPendingTasks(), "-2(7ms) -3(8ms) -1(21ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest,
-       SimpleOrderingTestPostingReordingDelayedTasksOverlap) {
-  PostTaskWhichPostsDelayedTask(1,
-                                base::TimeDelta::FromMilliseconds(1),
-                                base::TimeDelta::FromMilliseconds(5));
-  PostTaskWhichPostsDelayedTask(2,
-                                base::TimeDelta::FromMilliseconds(5),
-                                base::TimeDelta::FromMilliseconds(10));
-  PostTaskWhichPostsDelayedTask(3,
-                                base::TimeDelta::FromMilliseconds(10),
-                                base::TimeDelta::FromMilliseconds(1));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(1ms) 2(5ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "-1(6ms) 3(10ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "-3(11ms) -2(15ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, SimpleOrderingTestPostingAndRentrantTasks) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichCallsRun(2, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta());
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "-1(0ms) -3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest,
-       SimpleOrderingTestPostingDelayedAndRentrantTasks) {
-  PostTaskWhichPostsDelayedTask(
-      1, base::TimeDelta(), base::TimeDelta::FromMilliseconds(1));
-  PostTaskWhichCallsRun(2, base::TimeDelta());
-  PostTaskWhichPostsDelayedTask(
-      3, base::TimeDelta(), base::TimeDelta::FromMilliseconds(1));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "-1(1ms) -3(1ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, OrderingTestWithDelayedTasks) {
-  PostTask(1, base::TimeDelta());
-  PostTask(2, base::TimeDelta::FromMilliseconds(15));
-  PostTask(3, base::TimeDelta());
-  PostTask(4, base::TimeDelta::FromMilliseconds(8));
-
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunPendingTasks(), "1(0ms) 3(0ms) 4(8ms) 2(15ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, OrderingTestWithDelayedPostingTasks) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(2, base::TimeDelta::FromMilliseconds(15));
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(4, base::TimeDelta::FromMilliseconds(8));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(
-      EXPECT_TRUE, RunPendingTasks(), "-1(0ms) -3(0ms) 4(8ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "-4(8ms) 2(15ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "-2(15ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, OrderingTestWithDelayedTasksManualNow) {
-  task_runner_->SetAutoAdvanceNowToPendingTasks(false);
-  PostTask(1, base::TimeDelta());
-  PostTask(2, base::TimeDelta::FromMilliseconds(15));
-  PostTask(3, base::TimeDelta());
-  PostTask(4, base::TimeDelta::FromMilliseconds(8));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 3(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "");
-  EXPECT_EQ(task_runner_->DelayToNextTaskTime(),
-            base::TimeDelta::FromMilliseconds(8));
-  now_src_->SetNow(base::TimeTicks::FromInternalValue(5000));
-  EXPECT_EQ(task_runner_->DelayToNextTaskTime(),
-            base::TimeDelta::FromMilliseconds(3));
-  now_src_->SetNow(base::TimeTicks::FromInternalValue(25000));
-  EXPECT_EQ(task_runner_->DelayToNextTaskTime(), base::TimeDelta());
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "4(25ms) 2(25ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunUntilIdle) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilIdle(), "1(0ms) -1(0ms)");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilIdle(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunUntilTimeAutoNow) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(2, base::TimeDelta::FromMilliseconds(2));
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta::FromMilliseconds(3));
-
-  task_runner_->SetAutoAdvanceNowToPendingTasks(true);
-
-  base::TimeTicks run_at = base::TimeTicks();
-
-  run_at += base::TimeDelta::FromMilliseconds(2);
-  RUN_AND_CHECK_RESULT(
-      EXPECT_TRUE, RunUntilTime(run_at), "1(0ms) -1(0ms) 2(2ms) -2(2ms)");
-  EXPECT_EQ(run_at, now_src_->Now());
-
-  run_at += base::TimeDelta::FromMilliseconds(1);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilTime(run_at), "3(3ms) -3(3ms)");
-  EXPECT_EQ(run_at, now_src_->Now());
-
-  run_at += base::TimeDelta::FromMilliseconds(1);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilTime(run_at), "");
-  EXPECT_EQ(run_at, now_src_->Now());
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunUntilTimeManualNow) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(2, base::TimeDelta::FromMilliseconds(2));
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta::FromMilliseconds(3));
-
-  task_runner_->SetAutoAdvanceNowToPendingTasks(false);
-
-  base::TimeTicks run_at = base::TimeTicks();
-
-  run_at += base::TimeDelta::FromMilliseconds(2);
-  RUN_AND_CHECK_RESULT(
-      EXPECT_TRUE, RunUntilTime(run_at), "1(2ms) 2(2ms) -1(2ms) -2(2ms)");
-  EXPECT_EQ(run_at, now_src_->Now());
-
-  run_at += base::TimeDelta::FromMilliseconds(1);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilTime(run_at), "3(3ms) -3(3ms)");
-  EXPECT_EQ(run_at, now_src_->Now());
-
-  run_at += base::TimeDelta::FromMilliseconds(1);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilTime(run_at), "");
-  EXPECT_EQ(run_at, now_src_->Now());
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunForPeriod) {
-  PostTaskWhichPostsInstantTask(1, base::TimeDelta());
-  PostTaskWhichPostsInstantTask(2, base::TimeDelta::FromMilliseconds(2));
-  PostTaskWhichPostsInstantTask(3, base::TimeDelta::FromMilliseconds(3));
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE,
-                       RunForPeriod(base::TimeDelta::FromMilliseconds(2)),
-                       "1(0ms) -1(0ms) 2(2ms) -2(2ms)");
-  EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromMilliseconds(2),
-            now_src_->Now());
-
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE,
-                       RunForPeriod(base::TimeDelta::FromMilliseconds(1)),
-                       "3(3ms) -3(3ms)");
-  EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromMilliseconds(3),
-            now_src_->Now());
-
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunForPeriod(base::TimeDelta::FromMilliseconds(1)), "");
-  EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromMilliseconds(4),
-            now_src_->Now());
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunTasksWhileWithCallback) {
-  base::Callback<bool(void)> return_true = base::Bind(&ReturnTrue);
-  base::Callback<bool(void)> return_false = base::Bind(&ReturnFalse);
-
-  PostTask(1, base::TimeDelta());
-
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunTasksWhile(return_false), "");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunTasksWhile(return_true), "1(0ms)");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, EmptyTaskList) {
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunPendingTasks(), "");
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilIdle(), "");
-
-  ASSERT_EQ(base::TimeTicks(), now_src_->Now());
-
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunUntilTime(base::TimeTicks::FromInternalValue(100)), "");
-  EXPECT_EQ(base::TimeTicks::FromInternalValue(100), now_src_->Now());
-
-  RUN_AND_CHECK_RESULT(
-      EXPECT_FALSE, RunForPeriod(base::TimeDelta::FromInternalValue(100)), "");
-  EXPECT_EQ(base::TimeTicks::FromInternalValue(200), now_src_->Now());
-
-  base::Callback<bool(void)> return_true = base::Bind(&ReturnTrue);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunTasksWhile(return_true), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunPendingTasksTimeout) {
-  PostTask(1, base::TimeDelta());
-  PostTask(2, base::TimeDelta());
-  PostTask(3, base::TimeDelta());
-  PostTask(4, base::TimeDelta());
-  PostTask(5, base::TimeDelta());
-  PostTask(6, base::TimeDelta());
-
-  task_runner_->SetRunTaskLimit(3);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "1(0ms) 2(0ms) 3(0ms)");
-
-  task_runner_->SetRunTaskLimit(2);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "4(0ms) 5(0ms)");
-
-  task_runner_->SetRunTaskLimit(0);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunPendingTasks(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunUntilIdleTimeout) {
-  PostTaskWhichPostsTaskAgain(1, base::TimeDelta::FromMilliseconds(3));
-
-  task_runner_->SetRunTaskLimit(3);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunUntilIdle(), "1(3ms) 1(6ms) 1(9ms)");
-
-  task_runner_->SetRunTaskLimit(2);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunUntilIdle(), "1(12ms) 1(15ms)");
-
-  task_runner_->SetRunTaskLimit(0);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunUntilIdle(), "");
-}
-
-TEST_F(OrderedSimpleTaskRunnerTest, RunUntilTimeout) {
-  base::TimeTicks run_to = base::TimeTicks() + base::TimeDelta::FromSeconds(1);
-
-  PostTask(1, base::TimeDelta::FromMilliseconds(1));
-  PostTask(2, base::TimeDelta::FromMilliseconds(2));
-  PostTask(3, base::TimeDelta::FromMilliseconds(3));
-  PostTask(4, base::TimeDelta::FromMilliseconds(4));
-  PostTask(5, base::TimeDelta::FromMilliseconds(5));
-
-  EXPECT_EQ(base::TimeTicks(), now_src_->Now());
-  task_runner_->SetRunTaskLimit(3);
-  RUN_AND_CHECK_RESULT(
-      EXPECT_TRUE, RunUntilTime(run_to), "1(1ms) 2(2ms) 3(3ms)");
-  EXPECT_EQ(base::TimeTicks() + base::TimeDelta::FromMilliseconds(3),
-            now_src_->Now());
-
-  task_runner_->SetRunTaskLimit(0);
-  RUN_AND_CHECK_RESULT(EXPECT_TRUE, RunUntilTime(run_to), "");
-
-  task_runner_->SetRunTaskLimit(100);
-  RUN_AND_CHECK_RESULT(EXPECT_FALSE, RunUntilTime(run_to), "4(4ms) 5(5ms)");
-  EXPECT_EQ(run_to, now_src_->Now());
-}
-
-}  // namespace cc
diff --git a/cc/test/ordered_texture_map.cc b/cc/test/ordered_texture_map.cc
deleted file mode 100644
index 649700c..0000000
--- a/cc/test/ordered_texture_map.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/ordered_texture_map.h"
-
-#include "base/logging.h"
-#include "cc/test/test_texture.h"
-
-namespace cc {
-
-OrderedTextureMap::OrderedTextureMap() {}
-
-OrderedTextureMap::~OrderedTextureMap() {}
-
-void OrderedTextureMap::Append(GLuint id,
-                               scoped_refptr<TestTexture> texture) {
-  DCHECK(texture.get());
-  DCHECK(!ContainsId(id));
-
-  textures_[id] = texture;
-  ordered_textures_.push_back(id);
-}
-
-void OrderedTextureMap::Replace(GLuint id,
-                                scoped_refptr<TestTexture> texture) {
-  DCHECK(texture.get());
-  DCHECK(ContainsId(id));
-
-  textures_[id] = texture;
-}
-
-void OrderedTextureMap::Remove(GLuint id) {
-  TextureMap::iterator map_it = textures_.find(id);
-  // for some test we generate dummy tex id, which are not registered,
-  // nothing to remove in that case.
-  if (map_it == textures_.end())
-    return;
-  textures_.erase(map_it);
-
-  TextureList::iterator list_it =
-      std::find(ordered_textures_.begin(), ordered_textures_.end(), id);
-  DCHECK(list_it != ordered_textures_.end());
-  ordered_textures_.erase(list_it);
-}
-
-size_t OrderedTextureMap::Size() { return ordered_textures_.size(); }
-
-bool OrderedTextureMap::ContainsId(GLuint id) {
-  return textures_.find(id) != textures_.end();
-}
-
-scoped_refptr<TestTexture> OrderedTextureMap::TextureForId(GLuint id) {
-  DCHECK(ContainsId(id));
-  scoped_refptr<TestTexture> texture = textures_[id];
-  DCHECK(texture.get());
-  return texture;
-}
-
-GLuint OrderedTextureMap::IdAt(size_t index) {
-  DCHECK(index < Size());
-  return ordered_textures_[index];
-}
-
-}  // namespace cc
diff --git a/cc/test/ordered_texture_map.h b/cc/test/ordered_texture_map.h
deleted file mode 100644
index 2aa3111..0000000
--- a/cc/test/ordered_texture_map.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_ORDERED_TEXTURE_MAP_H_
-#define CC_TEST_ORDERED_TEXTURE_MAP_H_
-
-#include <vector>
-
-#include "base/containers/hash_tables.h"
-#include "base/memory/ref_counted.h"
-#include "third_party/khronos/GLES2/gl2.h"
-
-namespace cc {
-
-struct TestTexture;
-
-class OrderedTextureMap {
- public:
-  OrderedTextureMap();
-  ~OrderedTextureMap();
-
-  void Append(GLuint id, scoped_refptr<TestTexture> texture);
-  void Replace(GLuint id, scoped_refptr<TestTexture> texture);
-  void Remove(GLuint id);
-
-  size_t Size();
-
-  bool ContainsId(GLuint id);
-
-  scoped_refptr<TestTexture> TextureForId(GLuint id);
-  GLuint IdAt(size_t index);
-
- private:
-  typedef base::hash_map<GLuint, scoped_refptr<TestTexture>> TextureMap;
-  typedef std::vector<GLuint> TextureList;
-
-  TextureMap textures_;
-  TextureList ordered_textures_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_ORDERED_TEXTURE_MAP_H_
diff --git a/cc/test/paths.cc b/cc/test/paths.cc
deleted file mode 100644
index bcd324b..0000000
--- a/cc/test/paths.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "cc/test/paths.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-
-namespace cc {
-
-bool PathProvider(int key, base::FilePath* result) {
-  base::FilePath cur;
-  switch (key) {
-    // The following are only valid in the development environment, and
-    // will fail if executed from an installed executable (because the
-    // generated path won't exist).
-    case CCPaths::DIR_TEST_DATA:
-      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
-        return false;
-      cur = cur.Append(FILE_PATH_LITERAL("cc"));
-      cur = cur.Append(FILE_PATH_LITERAL("test"));
-      cur = cur.Append(FILE_PATH_LITERAL("data"));
-      if (!base::PathExists(cur))  // we don't want to create this
-        return false;
-      break;
-    default:
-      return false;
-  }
-
-  *result = cur;
-  return true;
-}
-
-// This cannot be done as a static initializer sadly since Visual Studio will
-// eliminate this object file if there is no direct entry point into it.
-void CCPaths::RegisterPathProvider() {
-  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
-}
-
-}  // namespace cc
diff --git a/cc/test/paths.h b/cc/test/paths.h
deleted file mode 100644
index f48177e..0000000
--- a/cc/test/paths.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CC_TEST_PATHS_H_
-#define CC_TEST_PATHS_H_
-
-namespace cc {
-
-class CCPaths {
- public:
-  enum {
-    PATH_START = 5000,
-
-    // Valid only in development and testing environments.
-    DIR_TEST_DATA,
-    PATH_END
-  };
-
-  // Call once to register the provider for the path keys defined above.
-  static void RegisterPathProvider();
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_PATHS_H_
diff --git a/cc/test/pixel_comparator.cc b/cc/test/pixel_comparator.cc
deleted file mode 100644
index 4067787..0000000
--- a/cc/test/pixel_comparator.cc
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright (c) 2013 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.
-
-#include "cc/test/pixel_comparator.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-ExactPixelComparator::ExactPixelComparator(const bool discard_alpha)
-    : discard_alpha_(discard_alpha) {
-}
-
-bool ExactPixelComparator::Compare(const SkBitmap& actual_bmp,
-                                   const SkBitmap& expected_bmp) const {
-  // Number of pixels with an error
-  int error_pixels_count = 0;
-
-  gfx::Rect error_bounding_rect = gfx::Rect();
-
-  // Check that bitmaps have identical dimensions.
-  DCHECK(actual_bmp.width() == expected_bmp.width() &&
-         actual_bmp.height() == expected_bmp.height());
-
-  SkAutoLockPixels lock_actual_bmp(actual_bmp);
-  SkAutoLockPixels lock_expected_bmp(expected_bmp);
-
-  for (int x = 0; x < actual_bmp.width(); ++x) {
-    for (int y = 0; y < actual_bmp.height(); ++y) {
-      SkColor actual_color = actual_bmp.getColor(x, y);
-      SkColor expected_color = expected_bmp.getColor(x, y);
-      if (discard_alpha_) {
-        actual_color = SkColorSetA(actual_color, 0);
-        expected_color = SkColorSetA(expected_color, 0);
-      }
-      if (actual_color != expected_color) {
-        ++error_pixels_count;
-        error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
-      }
-    }
-  }
-
-  if (error_pixels_count != 0) {
-    LOG(ERROR) << "Number of pixel with an error: " << error_pixels_count;
-    LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
-    return false;
-  }
-
-  return true;
-}
-
-FuzzyPixelComparator::FuzzyPixelComparator(
-    const bool discard_alpha,
-    const float error_pixels_percentage_limit,
-    const float small_error_pixels_percentage_limit,
-    const float avg_abs_error_limit,
-    const int max_abs_error_limit,
-    const int small_error_threshold)
-    : discard_alpha_(discard_alpha),
-      error_pixels_percentage_limit_(error_pixels_percentage_limit),
-      small_error_pixels_percentage_limit_(small_error_pixels_percentage_limit),
-      avg_abs_error_limit_(avg_abs_error_limit),
-      max_abs_error_limit_(max_abs_error_limit),
-      small_error_threshold_(small_error_threshold) {
-}
-
-bool FuzzyPixelComparator::Compare(const SkBitmap& actual_bmp,
-                                   const SkBitmap& expected_bmp) const {
-  // Number of pixels with an error
-  int error_pixels_count = 0;
-  // Number of pixels with a small error
-  int small_error_pixels_count = 0;
-  // The per channel sums of absolute errors over all pixels.
-  int64 sum_abs_error_r = 0;
-  int64 sum_abs_error_g = 0;
-  int64 sum_abs_error_b = 0;
-  int64 sum_abs_error_a = 0;
-  // The per channel maximum absolute errors over all pixels.
-  int max_abs_error_r = 0;
-  int max_abs_error_g = 0;
-  int max_abs_error_b = 0;
-  int max_abs_error_a = 0;
-
-  gfx::Rect error_bounding_rect = gfx::Rect();
-
-  // Check that bitmaps have identical dimensions.
-  DCHECK(actual_bmp.width() == expected_bmp.width() &&
-         actual_bmp.height() == expected_bmp.height());
-
-  // Check that bitmaps are not empty.
-  DCHECK(actual_bmp.width() > 0 && actual_bmp.height() > 0);
-
-  SkAutoLockPixels lock_actual_bmp(actual_bmp);
-  SkAutoLockPixels lock_expected_bmp(expected_bmp);
-
-  for (int x = 0; x < actual_bmp.width(); ++x) {
-    for (int y = 0; y < actual_bmp.height(); ++y) {
-      SkColor actual_color = actual_bmp.getColor(x, y);
-      SkColor expected_color = expected_bmp.getColor(x, y);
-      if (discard_alpha_) {
-        actual_color = SkColorSetA(actual_color, 0);
-        expected_color = SkColorSetA(expected_color, 0);
-      }
-
-      if (actual_color != expected_color) {
-        ++error_pixels_count;
-
-        // Compute per channel errors
-        int error_r = SkColorGetR(actual_color) - SkColorGetR(expected_color);
-        int error_g = SkColorGetG(actual_color) - SkColorGetG(expected_color);
-        int error_b = SkColorGetB(actual_color) - SkColorGetB(expected_color);
-        int error_a = SkColorGetA(actual_color) - SkColorGetA(expected_color);
-        int abs_error_r = std::abs(error_r);
-        int abs_error_g = std::abs(error_g);
-        int abs_error_b = std::abs(error_b);
-        int abs_error_a = std::abs(error_a);
-
-        // Increment small error counter if error is below threshold
-        if (abs_error_r <= small_error_threshold_ &&
-            abs_error_g <= small_error_threshold_ &&
-            abs_error_b <= small_error_threshold_ &&
-            abs_error_a <= small_error_threshold_)
-          ++small_error_pixels_count;
-
-        // Update per channel maximum absolute errors
-        max_abs_error_r = std::max(max_abs_error_r, abs_error_r);
-        max_abs_error_g = std::max(max_abs_error_g, abs_error_g);
-        max_abs_error_b = std::max(max_abs_error_b, abs_error_b);
-        max_abs_error_a = std::max(max_abs_error_a, abs_error_a);
-
-        // Update per channel absolute error sums
-        sum_abs_error_r += abs_error_r;
-        sum_abs_error_g += abs_error_g;
-        sum_abs_error_b += abs_error_b;
-        sum_abs_error_a += abs_error_a;
-      }
-    }
-  }
-
-  // Compute error metrics from collected data
-  int pixels_count = actual_bmp.width() * actual_bmp.height();
-  float error_pixels_percentage = 0.0f;
-  float small_error_pixels_percentage = 0.0f;
-  if (pixels_count > 0) {
-    error_pixels_percentage = static_cast<float>(error_pixels_count) /
-        pixels_count * 100.0f;
-    small_error_pixels_percentage =
-        static_cast<float>(small_error_pixels_count) / pixels_count * 100.0f;
-  }
-  float avg_abs_error_r = 0.0f;
-  float avg_abs_error_g = 0.0f;
-  float avg_abs_error_b = 0.0f;
-  float avg_abs_error_a = 0.0f;
-  if (error_pixels_count > 0) {
-    avg_abs_error_r = static_cast<float>(sum_abs_error_r) / error_pixels_count;
-    avg_abs_error_g = static_cast<float>(sum_abs_error_g) / error_pixels_count;
-    avg_abs_error_b = static_cast<float>(sum_abs_error_b) / error_pixels_count;
-    avg_abs_error_a = static_cast<float>(sum_abs_error_a) / error_pixels_count;
-  }
-
-  if (error_pixels_percentage > error_pixels_percentage_limit_ ||
-      small_error_pixels_percentage > small_error_pixels_percentage_limit_ ||
-      avg_abs_error_r > avg_abs_error_limit_ ||
-      avg_abs_error_g > avg_abs_error_limit_ ||
-      avg_abs_error_b > avg_abs_error_limit_ ||
-      avg_abs_error_a > avg_abs_error_limit_ ||
-      max_abs_error_r > max_abs_error_limit_ ||
-      max_abs_error_g > max_abs_error_limit_ ||
-      max_abs_error_b > max_abs_error_limit_ ||
-      max_abs_error_a > max_abs_error_limit_) {
-    LOG(ERROR) << "Percentage of pixels with an error: "
-               << error_pixels_percentage;
-    LOG(ERROR) << "Percentage of pixels with errors not greater than "
-               << small_error_threshold_ << ": "
-               << small_error_pixels_percentage;
-    LOG(ERROR) << "Average absolute error (excluding identical pixels): "
-               << "R=" << avg_abs_error_r << " "
-               << "G=" << avg_abs_error_g << " "
-               << "B=" << avg_abs_error_b << " "
-               << "A=" << avg_abs_error_a;
-    LOG(ERROR) << "Largest absolute error: "
-               << "R=" << max_abs_error_r << " "
-               << "G=" << max_abs_error_g << " "
-               << "B=" << max_abs_error_b << " "
-               << "A=" << max_abs_error_a;
-
-      for (int x = 0; x < actual_bmp.width(); ++x) {
-        for (int y = 0; y < actual_bmp.height(); ++y) {
-          SkColor actual_color = actual_bmp.getColor(x, y);
-          SkColor expected_color = expected_bmp.getColor(x, y);
-          if (discard_alpha_) {
-            actual_color = SkColorSetA(actual_color, 0);
-            expected_color = SkColorSetA(expected_color, 0);
-          }
-          if (actual_color != expected_color)
-            error_bounding_rect.Union(gfx::Rect(x, y, 1, 1));
-        }
-      }
-      LOG(ERROR) << "Error Bounding Box : " << error_bounding_rect.ToString();
-    return false;
-  } else {
-    return true;
-  }
-}
-
-}  // namespace cc
diff --git a/cc/test/pixel_comparator.h b/cc/test/pixel_comparator.h
deleted file mode 100644
index 7228858..0000000
--- a/cc/test/pixel_comparator.h
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) 2013 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.
-
-#ifndef CC_TEST_PIXEL_COMPARATOR_H_
-#define CC_TEST_PIXEL_COMPARATOR_H_
-
-#include "base/compiler_specific.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-
-namespace cc {
-
-// Interface for pixel comparators.
-class PixelComparator {
- public:
-  virtual ~PixelComparator() {}
-
-  virtual bool Compare(const SkBitmap& actual_bmp,
-                       const SkBitmap& expected_bmp) const = 0;
-};
-
-// Exact pixel comparator. Counts the number of pixel with an error.
-class ExactPixelComparator : public PixelComparator {
- public:
-  explicit ExactPixelComparator(const bool discard_alpha);
-  ~ExactPixelComparator() override {}
-
-  // Returns true if the two bitmaps are identical. Otherwise, returns false
-  // and report the number of pixels with an error on LOG(ERROR). Differences
-  // in the alpha channel are ignored.
-  bool Compare(const SkBitmap& actual_bmp,
-               const SkBitmap& expected_bmp) const override;
-
- private:
-  // Exclude alpha channel from comparison?
-  bool discard_alpha_;
-};
-
-// Fuzzy pixel comparator. Counts small and arbitrary errors separately and
-// computes average and maximum absolute errors per color channel.
-class FuzzyPixelComparator : public PixelComparator {
- public:
-  FuzzyPixelComparator(const bool discard_alpha,
-                       const float error_pixels_percentage_limit,
-                       const float small_error_pixels_percentage_limit,
-                       const float avg_abs_error_limit,
-                       const int max_abs_error_limit,
-                       const int small_error_threshold);
-  ~FuzzyPixelComparator() override {}
-
-  // Computes error metrics and returns true if the errors don't exceed the
-  // specified limits. Otherwise, returns false and reports the error metrics on
-  // LOG(ERROR). Differences in the alpha channel are ignored.
-  bool Compare(const SkBitmap& actual_bmp,
-               const SkBitmap& expected_bmp) const override;
-
- private:
-  // Exclude alpha channel from comparison?
-  bool discard_alpha_;
-  // Limit for percentage of pixels with an error.
-  float error_pixels_percentage_limit_;
-  // Limit for percentage of pixels with a small error.
-  float small_error_pixels_percentage_limit_;
-  // Limit for average absolute error (excluding identical pixels).
-  float avg_abs_error_limit_;
-  // Limit for largest absolute error.
-  int max_abs_error_limit_;
-  // Threshold for small errors.
-  int small_error_threshold_;
-};
-
-// All pixels can be off by one, but any more than that is an error.
-class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator {
- public:
-  explicit FuzzyPixelOffByOneComparator(bool discard_alpha)
-      : FuzzyPixelComparator(discard_alpha, 100.f, 0.f, 1.f, 1, 0) {}
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_PIXEL_COMPARATOR_H_
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
deleted file mode 100644
index c8c573d..0000000
--- a/cc/test/pixel_test.cc
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/pixel_test.h"
-
-#include "base/command_line.h"
-#include "base/message_loop/message_loop_proxy.h"
-#include "base/path_service.h"
-#include "base/run_loop.h"
-#include "cc/base/blocking_task_runner.h"
-#include "cc/base/switches.h"
-#include "cc/output/compositor_frame_metadata.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/output/software_renderer.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/resources/texture_mailbox_deleter.h"
-#include "cc/resources/tile_task_worker_pool.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/paths.h"
-#include "cc/test/pixel_test_output_surface.h"
-#include "cc/test/pixel_test_software_output_device.h"
-#include "cc/test/pixel_test_utils.h"
-#include "cc/test/test_gpu_memory_buffer_manager.h"
-#include "cc/test/test_in_process_context_provider.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-PixelTest::PixelTest()
-    : device_viewport_size_(gfx::Size(200, 200)),
-      disable_picture_quad_image_filtering_(false),
-      output_surface_client_(new FakeOutputSurfaceClient),
-      main_thread_task_runner_(
-          BlockingTaskRunner::Create(base::MessageLoopProxy::current())) {
-}
-PixelTest::~PixelTest() {}
-
-bool PixelTest::RunPixelTest(RenderPassList* pass_list,
-                             const base::FilePath& ref_file,
-                             const PixelComparator& comparator) {
-  return RunPixelTestWithReadbackTarget(pass_list,
-                                        pass_list->back(),
-                                        ref_file,
-                                        comparator);
-}
-
-bool PixelTest::RunPixelTestWithReadbackTarget(
-    RenderPassList* pass_list,
-    RenderPass* target,
-    const base::FilePath& ref_file,
-    const PixelComparator& comparator) {
-  return RunPixelTestWithReadbackTargetAndArea(
-      pass_list, target, ref_file, comparator, nullptr);
-}
-
-bool PixelTest::RunPixelTestWithReadbackTargetAndArea(
-    RenderPassList* pass_list,
-    RenderPass* target,
-    const base::FilePath& ref_file,
-    const PixelComparator& comparator,
-    const gfx::Rect* copy_rect) {
-  base::RunLoop run_loop;
-
-  scoped_ptr<CopyOutputRequest> request =
-      CopyOutputRequest::CreateBitmapRequest(
-          base::Bind(&PixelTest::ReadbackResult,
-                     base::Unretained(this),
-                     run_loop.QuitClosure()));
-  if (copy_rect)
-    request->set_area(*copy_rect);
-  target->copy_requests.push_back(request.Pass());
-
-  float device_scale_factor = 1.f;
-  gfx::Rect device_viewport_rect =
-      gfx::Rect(device_viewport_size_) + external_device_viewport_offset_;
-  gfx::Rect device_clip_rect = external_device_clip_rect_.IsEmpty()
-                                   ? device_viewport_rect
-                                   : external_device_clip_rect_;
-  renderer_->DecideRenderPassAllocationsForFrame(*pass_list);
-  renderer_->DrawFrame(pass_list,
-                       device_scale_factor,
-                       device_viewport_rect,
-                       device_clip_rect,
-                       disable_picture_quad_image_filtering_);
-
-  // Wait for the readback to complete.
-  if (output_surface_->context_provider())
-    output_surface_->context_provider()->ContextGL()->Finish();
-  run_loop.Run();
-
-  return PixelsMatchReference(ref_file, comparator);
-}
-
-void PixelTest::ReadbackResult(base::Closure quit_run_loop,
-                               scoped_ptr<CopyOutputResult> result) {
-  ASSERT_TRUE(result->HasBitmap());
-  result_bitmap_ = result->TakeBitmap().Pass();
-  quit_run_loop.Run();
-}
-
-bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
-                                     const PixelComparator& comparator) {
-  base::FilePath test_data_dir;
-  if (!PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir))
-    return false;
-
-  // If this is false, we didn't set up a readback on a render pass.
-  if (!result_bitmap_)
-    return false;
-
-  base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
-  if (cmd->HasSwitch(switches::kCCRebaselinePixeltests))
-    return WritePNGFile(*result_bitmap_, test_data_dir.Append(ref_file), true);
-
-  return MatchesPNGFile(
-      *result_bitmap_, test_data_dir.Append(ref_file), comparator);
-}
-
-void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend,
-                                bool flipped_output_surface) {
-  enable_pixel_output_.reset(new gfx::DisableNullDrawGLBindings);
-
-  output_surface_.reset(new PixelTestOutputSurface(
-      new TestInProcessContextProvider, new TestInProcessContextProvider,
-      flipped_output_surface));
-  output_surface_->BindToClient(output_surface_client_.get());
-
-  shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-  gpu_memory_buffer_manager_.reset(new TestGpuMemoryBufferManager);
-  resource_provider_ =
-      ResourceProvider::Create(output_surface_.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               main_thread_task_runner_.get(),
-                               0,
-                               false,
-                               1);
-
-  texture_mailbox_deleter_ = make_scoped_ptr(
-      new TextureMailboxDeleter(base::MessageLoopProxy::current()));
-
-  renderer_ = GLRenderer::Create(
-      this, &settings_.renderer_settings, output_surface_.get(),
-      resource_provider_.get(), texture_mailbox_deleter_.get(), 0);
-}
-
-void PixelTest::ForceExpandedViewport(const gfx::Size& surface_expansion) {
-  static_cast<PixelTestOutputSurface*>(output_surface_.get())
-      ->set_surface_expansion_size(surface_expansion);
-  SoftwareOutputDevice* device = output_surface_->software_device();
-  if (device) {
-    static_cast<PixelTestSoftwareOutputDevice*>(device)
-        ->set_surface_expansion_size(surface_expansion);
-  }
-}
-
-void PixelTest::ForceViewportOffset(const gfx::Vector2d& viewport_offset) {
-  external_device_viewport_offset_ = viewport_offset;
-}
-
-void PixelTest::ForceDeviceClip(const gfx::Rect& clip) {
-  external_device_clip_rect_ = clip;
-}
-
-void PixelTest::EnableExternalStencilTest() {
-  static_cast<PixelTestOutputSurface*>(output_surface_.get())
-      ->set_has_external_stencil_test(true);
-}
-
-void PixelTest::SetUpSoftwareRenderer() {
-  scoped_ptr<SoftwareOutputDevice> device(new PixelTestSoftwareOutputDevice());
-  output_surface_.reset(new PixelTestOutputSurface(device.Pass()));
-  output_surface_->BindToClient(output_surface_client_.get());
-  shared_bitmap_manager_.reset(new TestSharedBitmapManager());
-  resource_provider_ =
-      ResourceProvider::Create(output_surface_.get(),
-                               shared_bitmap_manager_.get(),
-                               gpu_memory_buffer_manager_.get(),
-                               main_thread_task_runner_.get(),
-                               0,
-                               false,
-                               1);
-  renderer_ =
-      SoftwareRenderer::Create(this, &settings_.renderer_settings,
-                               output_surface_.get(), resource_provider_.get());
-}
-
-}  // namespace cc
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
deleted file mode 100644
index 08bad36..0000000
--- a/cc/test/pixel_test.h
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2013 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.
-
-#include "base/files/file_util.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/software_renderer.h"
-#include "cc/quads/render_pass.h"
-#include "cc/test/pixel_comparator.h"
-#include "cc/trees/layer_tree_settings.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gfx/geometry/size.h"
-#include "ui/gl/gl_implementation.h"
-
-#ifndef CC_TEST_PIXEL_TEST_H_
-#define CC_TEST_PIXEL_TEST_H_
-
-namespace cc {
-class CopyOutputResult;
-class DirectRenderer;
-class FakeOutputSurfaceClient;
-class OutputSurface;
-class ResourceProvider;
-class SoftwareRenderer;
-class TestGpuMemoryBufferManager;
-class TestSharedBitmapManager;
-
-class PixelTest : public testing::Test, RendererClient {
- protected:
-  PixelTest();
-  ~PixelTest() override;
-
-  bool RunPixelTest(RenderPassList* pass_list,
-                    const base::FilePath& ref_file,
-                    const PixelComparator& comparator);
-
-  bool RunPixelTestWithReadbackTarget(
-      RenderPassList* pass_list,
-      RenderPass* target,
-      const base::FilePath& ref_file,
-      const PixelComparator& comparator);
-
-  bool RunPixelTestWithReadbackTargetAndArea(RenderPassList* pass_list,
-                                             RenderPass* target,
-                                             const base::FilePath& ref_file,
-                                             const PixelComparator& comparator,
-                                             const gfx::Rect* copy_rect);
-
-  LayerTreeSettings settings_;
-  gfx::Size device_viewport_size_;
-  bool disable_picture_quad_image_filtering_;
-  class PixelTestRendererClient;
-  scoped_ptr<FakeOutputSurfaceClient> output_surface_client_;
-  scoped_ptr<OutputSurface> output_surface_;
-  scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_;
-  scoped_ptr<TestGpuMemoryBufferManager> gpu_memory_buffer_manager_;
-  scoped_ptr<BlockingTaskRunner> main_thread_task_runner_;
-  scoped_ptr<ResourceProvider> resource_provider_;
-  scoped_ptr<TextureMailboxDeleter> texture_mailbox_deleter_;
-  scoped_ptr<DirectRenderer> renderer_;
-  scoped_ptr<SkBitmap> result_bitmap_;
-  gfx::Vector2d external_device_viewport_offset_;
-  gfx::Rect external_device_clip_rect_;
-
-  void SetUpGLRenderer(bool use_skia_gpu_backend, bool flipped_output_surface);
-  void SetUpSoftwareRenderer();
-
-  void ForceExpandedViewport(const gfx::Size& surface_expansion);
-  void ForceViewportOffset(const gfx::Vector2d& viewport_offset);
-  void ForceDeviceClip(const gfx::Rect& clip);
-  void EnableExternalStencilTest();
-
-  // RendererClient implementation.
-  void SetFullRootLayerDamage() override {}
-
- private:
-  void ReadbackResult(base::Closure quit_run_loop,
-                      scoped_ptr<CopyOutputResult> result);
-
-  bool PixelsMatchReference(const base::FilePath& ref_file,
-                            const PixelComparator& comparator);
-
-  scoped_ptr<gfx::DisableNullDrawGLBindings> enable_pixel_output_;
-};
-
-template<typename RendererType>
-class RendererPixelTest : public PixelTest {
- public:
-  RendererType* renderer() {
-    return static_cast<RendererType*>(renderer_.get());
-  }
-
- protected:
-  void SetUp() override;
-};
-
-// Wrappers to differentiate renderers where the the output surface and viewport
-// have an externally determined size and offset.
-class GLRendererWithExpandedViewport : public GLRenderer {
- public:
-  GLRendererWithExpandedViewport(RendererClient* client,
-                                 const RendererSettings* settings,
-                                 OutputSurface* output_surface,
-                                 ResourceProvider* resource_provider,
-                                 TextureMailboxDeleter* texture_mailbox_deleter,
-                                 int highp_threshold_min)
-      : GLRenderer(client,
-                   settings,
-                   output_surface,
-                   resource_provider,
-                   texture_mailbox_deleter,
-                   highp_threshold_min) {}
-};
-
-class SoftwareRendererWithExpandedViewport : public SoftwareRenderer {
- public:
-  SoftwareRendererWithExpandedViewport(RendererClient* client,
-                                       const RendererSettings* settings,
-                                       OutputSurface* output_surface,
-                                       ResourceProvider* resource_provider)
-      : SoftwareRenderer(client, settings, output_surface, resource_provider) {}
-};
-
-class GLRendererWithFlippedSurface : public GLRenderer {
- public:
-  GLRendererWithFlippedSurface(RendererClient* client,
-                               const RendererSettings* settings,
-                               OutputSurface* output_surface,
-                               ResourceProvider* resource_provider,
-                               TextureMailboxDeleter* texture_mailbox_deleter,
-                               int highp_threshold_min)
-      : GLRenderer(client,
-                   settings,
-                   output_surface,
-                   resource_provider,
-                   texture_mailbox_deleter,
-                   highp_threshold_min) {}
-};
-
-template<>
-inline void RendererPixelTest<GLRenderer>::SetUp() {
-  SetUpGLRenderer(false, false);
-}
-
-template<>
-inline void RendererPixelTest<GLRendererWithExpandedViewport>::SetUp() {
-  SetUpGLRenderer(false, false);
-  ForceExpandedViewport(gfx::Size(50, 50));
-  ForceViewportOffset(gfx::Vector2d(10, 20));
-}
-
-template <>
-inline void RendererPixelTest<GLRendererWithFlippedSurface>::SetUp() {
-  SetUpGLRenderer(false, true);
-}
-
-template <>
-inline void RendererPixelTest<SoftwareRenderer>::SetUp() {
-  SetUpSoftwareRenderer();
-}
-
-template<>
-inline void RendererPixelTest<SoftwareRendererWithExpandedViewport>::SetUp() {
-  SetUpSoftwareRenderer();
-  ForceExpandedViewport(gfx::Size(50, 50));
-  ForceViewportOffset(gfx::Vector2d(10, 20));
-}
-
-typedef RendererPixelTest<GLRenderer> GLRendererPixelTest;
-typedef RendererPixelTest<SoftwareRenderer> SoftwareRendererPixelTest;
-
-}  // namespace cc
-
-#endif  // CC_TEST_PIXEL_TEST_H_
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc
deleted file mode 100644
index 616103c..0000000
--- a/cc/test/pixel_test_output_surface.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/pixel_test_output_surface.h"
-
-#include "cc/output/output_surface_client.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-PixelTestOutputSurface::PixelTestOutputSurface(
-    scoped_refptr<ContextProvider> context_provider,
-    scoped_refptr<ContextProvider> worker_context_provider,
-    bool flipped_output_surface)
-    : OutputSurface(context_provider, worker_context_provider),
-      external_stencil_test_(false) {
-  capabilities_.flipped_output_surface = flipped_output_surface;
-}
-
-PixelTestOutputSurface::PixelTestOutputSurface(
-    scoped_refptr<ContextProvider> context_provider,
-    bool flipped_output_surface)
-    : PixelTestOutputSurface(context_provider,
-                             nullptr,
-                             flipped_output_surface) {
-}
-
-PixelTestOutputSurface::PixelTestOutputSurface(
-    scoped_ptr<SoftwareOutputDevice> software_device)
-    : OutputSurface(software_device.Pass()), external_stencil_test_(false) {
-}
-
-void PixelTestOutputSurface::Reshape(const gfx::Size& size,
-                                     float scale_factor) {
-  gfx::Size expanded_size(size.width() + surface_expansion_size_.width(),
-                          size.height() + surface_expansion_size_.height());
-  OutputSurface::Reshape(expanded_size, scale_factor);
-}
-
-bool PixelTestOutputSurface::HasExternalStencilTest() const {
-  return external_stencil_test_;
-}
-
-void PixelTestOutputSurface::SwapBuffers(CompositorFrame* frame) {
-  PostSwapBuffersComplete();
-  client_->DidSwapBuffers();
-}
-
-}  // namespace cc
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h
deleted file mode 100644
index 27819c1..0000000
--- a/cc/test/pixel_test_output_surface.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
-#define CC_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
-
-#include "cc/output/output_surface.h"
-
-namespace cc {
-
-class PixelTestOutputSurface : public OutputSurface {
- public:
-  explicit PixelTestOutputSurface(
-      scoped_refptr<ContextProvider> context_provider,
-      scoped_refptr<ContextProvider> worker_context_provider,
-      bool flipped_output_surface);
-  explicit PixelTestOutputSurface(
-      scoped_refptr<ContextProvider> context_provider,
-      bool flipped_output_surface);
-  explicit PixelTestOutputSurface(
-      scoped_ptr<SoftwareOutputDevice> software_device);
-
-  void Reshape(const gfx::Size& size, float scale_factor) override;
-  bool HasExternalStencilTest() const override;
-  void SwapBuffers(CompositorFrame* frame) override;
-
-  void set_surface_expansion_size(const gfx::Size& surface_expansion_size) {
-    surface_expansion_size_ = surface_expansion_size;
-  }
-  void set_has_external_stencil_test(bool has_test) {
-    external_stencil_test_ = has_test;
-  }
-
- private:
-  gfx::Size surface_expansion_size_;
-  bool external_stencil_test_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_PIXEL_TEST_OUTPUT_SURFACE_H_
diff --git a/cc/test/pixel_test_software_output_device.cc b/cc/test/pixel_test_software_output_device.cc
deleted file mode 100644
index 6d049ac..0000000
--- a/cc/test/pixel_test_software_output_device.cc
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/pixel_test_software_output_device.h"
-
-namespace cc {
-
-void PixelTestSoftwareOutputDevice::Resize(const gfx::Size& pixel_size,
-                                           float scale_factor) {
-  gfx::Size expanded_size(
-      pixel_size.width() + surface_expansion_size_.width(),
-      pixel_size.height() + surface_expansion_size_.height());
-  SoftwareOutputDevice::Resize(expanded_size, scale_factor);
-}
-
-}  // namespace cc
diff --git a/cc/test/pixel_test_software_output_device.h b/cc/test/pixel_test_software_output_device.h
deleted file mode 100644
index d339538..0000000
--- a/cc/test/pixel_test_software_output_device.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
-#define CC_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
-
-#include "cc/output/software_output_device.h"
-
-namespace cc {
-
-class PixelTestSoftwareOutputDevice : public SoftwareOutputDevice {
- public:
-  void Resize(const gfx::Size& pixel_size, float scale_factor) override;
-
-  void set_surface_expansion_size(const gfx::Size& surface_expansion_size) {
-    surface_expansion_size_ = surface_expansion_size;
-  }
-
- private:
-  gfx::Size surface_expansion_size_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_PIXEL_TEST_SOFTWARE_OUTPUT_DEVICE_H_
diff --git a/cc/test/pixel_test_utils.cc b/cc/test/pixel_test_utils.cc
deleted file mode 100644
index 43e70df..0000000
--- a/cc/test/pixel_test_utils.cc
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "cc/test/pixel_test_utils.h"
-
-#include <string>
-#include <vector>
-
-#include "base/base64.h"
-#include "base/files/file_util.h"
-#include "base/logging.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/gfx/codec/png_codec.h"
-
-namespace cc {
-
-bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
-    bool discard_transparency) {
-  std::vector<unsigned char> png_data;
-  if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
-                                        discard_transparency,
-                                        &png_data) &&
-      base::CreateDirectory(file_path.DirName())) {
-    char* data = reinterpret_cast<char*>(&png_data[0]);
-    int size = static_cast<int>(png_data.size());
-    return base::WriteFile(file_path, data, size) == size;
-  }
-  return false;
-}
-
-std::string GetPNGDataUrl(const SkBitmap& bitmap) {
-  std::vector<unsigned char> png_data;
-  gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &png_data);
-  std::string data_url;
-  data_url.insert(data_url.end(), png_data.begin(), png_data.end());
-  base::Base64Encode(data_url, &data_url);
-  data_url.insert(0, "data:image/png;base64,");
-
-  return data_url;
-}
-
-bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap) {
-  DCHECK(bitmap);
-  std::string png_data;
-  return base::ReadFileToString(file_path, &png_data) &&
-         gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]),
-                               png_data.length(),
-                               bitmap);
-}
-
-bool MatchesPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path,
-                    const PixelComparator& comparator) {
-  SkBitmap ref_bmp;
-  if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
-    LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
-    return false;
-  }
-
-  // Check if images size matches
-  if (gen_bmp.width() != ref_bmp.width() ||
-      gen_bmp.height() != ref_bmp.height()) {
-    LOG(ERROR)
-        << "Dimensions do not match! "
-        << "Actual: " << gen_bmp.width() << "x" << gen_bmp.height()
-        << "; "
-        << "Expected: " << ref_bmp.width() << "x" << ref_bmp.height();
-    return false;
-  }
-
-  // Shortcut for empty images. They are always equal.
-  if (gen_bmp.width() == 0 || gen_bmp.height() == 0)
-    return true;
-
-  bool compare = comparator.Compare(gen_bmp, ref_bmp);
-  if (!compare) {
-    std::string gen_bmp_data_url = GetPNGDataUrl(gen_bmp);
-    std::string ref_bmp_data_url = GetPNGDataUrl(ref_bmp);
-    LOG(ERROR) << "Pixels do not match!";
-    LOG(ERROR) << "Actual: " << gen_bmp_data_url;
-    LOG(ERROR) << "Expected: " << ref_bmp_data_url;
-  }
-  return compare;
-}
-
-}  // namespace cc
diff --git a/cc/test/pixel_test_utils.h b/cc/test/pixel_test_utils.h
deleted file mode 100644
index 81d20ce..0000000
--- a/cc/test/pixel_test_utils.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CC_TEST_PIXEL_TEST_UTILS_H_
-#define CC_TEST_PIXEL_TEST_UTILS_H_
-
-#include <string>
-
-#include "base/files/file_path.h"
-#include "cc/test/pixel_comparator.h"
-
-class SkBitmap;
-
-namespace cc {
-
-// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
-// parent directory does not have to exist.
-bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
-    bool discard_transparency);
-
-// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
-// should have been encoded using |gfx::PNGCodec::Encode|.
-bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap);
-
-std::string GetPNGDataUrl(const SkBitmap& bitmap);
-
-// Compares with a PNG file on disk using the given PixelComparator, and returns
-// true if the comparator returns a match. |ref_img_path| is absolute.
-bool MatchesPNGFile(const SkBitmap& gen_bmp,
-                    base::FilePath ref_img_path,
-                    const PixelComparator& comparator);
-
-}  // namespace cc
-
-#endif  // CC_TEST_PIXEL_TEST_UTILS_H_
diff --git a/cc/test/render_pass_test_common.cc b/cc/test/render_pass_test_common.cc
deleted file mode 100644
index fd63f7e..0000000
--- a/cc/test/render_pass_test_common.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/render_pass_test_common.h"
-
-#include "base/bind.h"
-#include "cc/base/blocking_task_runner.h"
-#include "cc/quads/checkerboard_draw_quad.h"
-#include "cc/quads/debug_border_draw_quad.h"
-#include "cc/quads/io_surface_draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/stream_video_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/quads/tile_draw_quad.h"
-#include "cc/quads/yuv_video_draw_quad.h"
-#include "cc/resources/resource_provider.h"
-#include "ui/gfx/transform.h"
-
-namespace cc {
-
-static void EmptyReleaseCallback(uint32 sync_point,
-                                 bool lost_resource,
-                                 BlockingTaskRunner* main_thread_task_runner) {
-}
-
-void TestRenderPass::AppendOneOfEveryQuadType(
-    ResourceProvider* resource_provider,
-    RenderPassId child_pass) {
-  gfx::Rect rect(0, 0, 100, 100);
-  gfx::Rect opaque_rect(10, 10, 80, 80);
-  gfx::Rect visible_rect(0, 0, 100, 100);
-  const float vertex_opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
-
-  ResourceProvider::ResourceId resource1 = resource_provider->CreateResource(
-      gfx::Size(45, 5), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource1);
-  ResourceProvider::ResourceId resource2 = resource_provider->CreateResource(
-      gfx::Size(346, 61), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource2);
-  ResourceProvider::ResourceId resource3 = resource_provider->CreateResource(
-      gfx::Size(12, 134), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource3);
-  ResourceProvider::ResourceId resource4 = resource_provider->CreateResource(
-      gfx::Size(56, 12), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource4);
-  gfx::Size resource5_size(73, 26);
-  ResourceProvider::ResourceId resource5 = resource_provider->CreateResource(
-      resource5_size, GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource5);
-  ResourceProvider::ResourceId resource6 = resource_provider->CreateResource(
-      gfx::Size(64, 92), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource6);
-  ResourceProvider::ResourceId resource7 = resource_provider->CreateResource(
-      gfx::Size(9, 14), GL_CLAMP_TO_EDGE,
-      ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-      resource_provider->best_texture_format());
-  resource_provider->AllocateForTesting(resource7);
-
-  unsigned target = GL_TEXTURE_2D;
-  gpu::Mailbox gpu_mailbox;
-  memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
-  scoped_ptr<SingleReleaseCallbackImpl> callback =
-      SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-  TextureMailbox mailbox(gpu_mailbox, target, kSyncPointForMailboxTextureQuad);
-  ResourceProvider::ResourceId resource8 =
-      resource_provider->CreateResourceFromTextureMailbox(mailbox,
-                                                          callback.Pass());
-  resource_provider->AllocateForTesting(resource8);
-
-  SharedQuadState* shared_state = this->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       rect.size(),
-                       rect,
-                       rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-
-  CheckerboardDrawQuad* checkerboard_quad =
-      this->CreateAndAppendDrawQuad<CheckerboardDrawQuad>();
-  checkerboard_quad->SetNew(shared_state, rect, visible_rect, SK_ColorRED, 1.f);
-
-  DebugBorderDrawQuad* debug_border_quad =
-      this->CreateAndAppendDrawQuad<DebugBorderDrawQuad>();
-  debug_border_quad->SetNew(shared_state, rect, visible_rect, SK_ColorRED, 1);
-
-  IOSurfaceDrawQuad* io_surface_quad =
-      this->CreateAndAppendDrawQuad<IOSurfaceDrawQuad>();
-  io_surface_quad->SetNew(shared_state,
-                          rect,
-                          opaque_rect,
-                          visible_rect,
-                          gfx::Size(50, 50),
-                          resource7,
-                          IOSurfaceDrawQuad::FLIPPED);
-
-  if (child_pass.layer_id) {
-    RenderPassDrawQuad* render_pass_quad =
-        this->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-    render_pass_quad->SetNew(shared_state,
-                             rect,
-                             visible_rect,
-                             child_pass,
-                             resource5,
-                             gfx::Vector2dF(1.f, 1.f),
-                             resource5_size,
-                             FilterOperations(),
-                             gfx::Vector2dF(),
-                             FilterOperations());
-
-    RenderPassDrawQuad* render_pass_replica_quad =
-        this->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-    render_pass_replica_quad->SetNew(shared_state,
-                                     rect,
-                                     visible_rect,
-                                     child_pass,
-                                     resource5,
-                                     gfx::Vector2dF(1.f, 1.f),
-                                     resource5_size,
-                                     FilterOperations(),
-                                     gfx::Vector2dF(),
-                                     FilterOperations());
-  }
-
-  SolidColorDrawQuad* solid_color_quad =
-      this->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  solid_color_quad->SetNew(
-      shared_state, rect, visible_rect, SK_ColorRED, false);
-
-  StreamVideoDrawQuad* stream_video_quad =
-      this->CreateAndAppendDrawQuad<StreamVideoDrawQuad>();
-  stream_video_quad->SetNew(shared_state,
-                            rect,
-                            opaque_rect,
-                            visible_rect,
-                            resource6,
-                            gfx::Transform());
-
-  TextureDrawQuad* texture_quad =
-      this->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  texture_quad->SetNew(shared_state,
-                       rect,
-                       opaque_rect,
-                       visible_rect,
-                       resource1,
-                       false,
-                       gfx::PointF(0.f, 0.f),
-                       gfx::PointF(1.f, 1.f),
-                       SK_ColorTRANSPARENT,
-                       vertex_opacity,
-                       false,
-                       false);
-
-  TextureDrawQuad* mailbox_texture_quad =
-      this->CreateAndAppendDrawQuad<TextureDrawQuad>();
-  mailbox_texture_quad->SetNew(shared_state,
-                               rect,
-                               opaque_rect,
-                               visible_rect,
-                               resource8,
-                               false,
-                               gfx::PointF(0.f, 0.f),
-                               gfx::PointF(1.f, 1.f),
-                               SK_ColorTRANSPARENT,
-                               vertex_opacity,
-                               false,
-                               false);
-
-  TileDrawQuad* scaled_tile_quad =
-      this->CreateAndAppendDrawQuad<TileDrawQuad>();
-  scaled_tile_quad->SetNew(shared_state,
-                           rect,
-                           opaque_rect,
-                           visible_rect,
-                           resource2,
-                           gfx::RectF(0, 0, 50, 50),
-                           gfx::Size(50, 50),
-                           false,
-                           false);
-
-  SharedQuadState* transformed_state = this->CreateAndAppendSharedQuadState();
-  transformed_state->CopyFrom(shared_state);
-  gfx::Transform rotation;
-  rotation.Rotate(45);
-  transformed_state->content_to_target_transform =
-      transformed_state->content_to_target_transform * rotation;
-  TileDrawQuad* transformed_tile_quad =
-      this->CreateAndAppendDrawQuad<TileDrawQuad>();
-  transformed_tile_quad->SetNew(transformed_state,
-                                rect,
-                                opaque_rect,
-                                visible_rect,
-                                resource3,
-                                gfx::RectF(0, 0, 100, 100),
-                                gfx::Size(100, 100),
-                                false,
-                                false);
-
-  SharedQuadState* shared_state2 = this->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       rect.size(),
-                       rect,
-                       rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-
-  TileDrawQuad* tile_quad = this->CreateAndAppendDrawQuad<TileDrawQuad>();
-  tile_quad->SetNew(shared_state2,
-                    rect,
-                    opaque_rect,
-                    visible_rect,
-                    resource4,
-                    gfx::RectF(0, 0, 100, 100),
-                    gfx::Size(100, 100),
-                    false,
-                    false);
-
-  ResourceProvider::ResourceId plane_resources[4];
-  for (int i = 0; i < 4; ++i) {
-    plane_resources[i] = resource_provider->CreateResource(
-        gfx::Size(20, 12), GL_CLAMP_TO_EDGE,
-        ResourceProvider::TEXTURE_HINT_IMMUTABLE,
-        resource_provider->best_texture_format());
-    resource_provider->AllocateForTesting(plane_resources[i]);
-  }
-  YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601;
-  YUVVideoDrawQuad* yuv_quad =
-      this->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
-  yuv_quad->SetNew(shared_state2, rect, opaque_rect, visible_rect,
-                   gfx::RectF(0, 0, 100, 100), gfx::Size(100, 100),
-                   plane_resources[0], plane_resources[1], plane_resources[2],
-                   plane_resources[3], color_space);
-}
-
-}  // namespace cc
diff --git a/cc/test/render_pass_test_common.h b/cc/test/render_pass_test_common.h
deleted file mode 100644
index 0fd325f..0000000
--- a/cc/test/render_pass_test_common.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_TEST_RENDER_PASS_TEST_COMMON_H_
-#define CC_TEST_RENDER_PASS_TEST_COMMON_H_
-
-#include "cc/quads/render_pass.h"
-
-namespace cc {
-class ResourceProvider;
-}
-
-namespace cc {
-
-class TestRenderPass : public RenderPass {
- public:
-  static scoped_ptr<TestRenderPass> Create() {
-    return make_scoped_ptr(new TestRenderPass);
-  }
-
-  static const unsigned int kSyncPointForMailboxTextureQuad = 30;
-
-  void AppendOneOfEveryQuadType(ResourceProvider* resource_provider,
-                                RenderPassId child_pass);
-
- protected:
-  TestRenderPass() : RenderPass() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_RENDER_PASS_TEST_COMMON_H_
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
deleted file mode 100644
index f9def0f..0000000
--- a/cc/test/render_pass_test_utils.cc
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/render_pass_test_utils.h"
-
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/test/render_pass_test_common.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "third_party/skia/include/core/SkImageFilter.h"
-#include "ui/gfx/geometry/rect.h"
-
-namespace cc {
-
-TestRenderPass* AddRenderPass(RenderPassList* pass_list,
-                              RenderPassId id,
-                              const gfx::Rect& output_rect,
-                              const gfx::Transform& root_transform) {
-  scoped_ptr<TestRenderPass> pass(TestRenderPass::Create());
-  pass->SetNew(id, output_rect, output_rect, root_transform);
-  TestRenderPass* saved = pass.get();
-  pass_list->push_back(pass.Pass());
-  return saved;
-}
-
-SolidColorDrawQuad* AddQuad(TestRenderPass* pass,
-                            const gfx::Rect& rect,
-                            SkColor color) {
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       rect.size(),
-                       rect,
-                       rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-  SolidColorDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  quad->SetNew(shared_state, rect, rect, color, false);
-  return quad;
-}
-
-SolidColorDrawQuad* AddClippedQuad(TestRenderPass* pass,
-                                   const gfx::Rect& rect,
-                                   SkColor color) {
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       rect.size(),
-                       rect,
-                       rect,
-                       true,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-  SolidColorDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  quad->SetNew(shared_state, rect, rect, color, false);
-  return quad;
-}
-
-SolidColorDrawQuad* AddTransformedQuad(TestRenderPass* pass,
-                                       const gfx::Rect& rect,
-                                       SkColor color,
-                                       const gfx::Transform& transform) {
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(transform,
-                       rect.size(),
-                       rect,
-                       rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-  SolidColorDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  quad->SetNew(shared_state, rect, rect, color, false);
-  return quad;
-}
-
-void AddRenderPassQuad(TestRenderPass* to_pass,
-                       TestRenderPass* contributing_pass) {
-  gfx::Rect output_rect = contributing_pass->output_rect;
-  SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(),
-                       output_rect.size(),
-                       output_rect,
-                       output_rect,
-                       false,
-                       1,
-                       SkXfermode::kSrcOver_Mode,
-                       0);
-  RenderPassDrawQuad* quad =
-      to_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  quad->SetNew(shared_state,
-               output_rect,
-               output_rect,
-               contributing_pass->id,
-               0,
-               gfx::Vector2dF(),
-               gfx::Size(),
-               FilterOperations(),
-               gfx::Vector2dF(),
-               FilterOperations());
-}
-
-void AddRenderPassQuad(TestRenderPass* to_pass,
-                       TestRenderPass* contributing_pass,
-                       ResourceProvider::ResourceId mask_resource_id,
-                       const FilterOperations& filters,
-                       gfx::Transform transform,
-                       SkXfermode::Mode blend_mode) {
-  gfx::Rect output_rect = contributing_pass->output_rect;
-  SharedQuadState* shared_state = to_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(transform,
-                       output_rect.size(),
-                       output_rect,
-                       output_rect,
-                       false,
-                       1,
-                       blend_mode,
-                       0);
-  RenderPassDrawQuad* quad =
-      to_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  gfx::Size arbitrary_nonzero_size(1, 1);
-  quad->SetNew(shared_state,
-               output_rect,
-               output_rect,
-               contributing_pass->id,
-               mask_resource_id,
-               gfx::Vector2dF(1.f, 1.f),
-               arbitrary_nonzero_size,
-               filters,
-               gfx::Vector2dF(),
-               FilterOperations());
-}
-
-}  // namespace cc
diff --git a/cc/test/render_pass_test_utils.h b/cc/test/render_pass_test_utils.h
deleted file mode 100644
index 49ea113..0000000
--- a/cc/test/render_pass_test_utils.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_TEST_RENDER_PASS_TEST_UTILS_H_
-#define CC_TEST_RENDER_PASS_TEST_UTILS_H_
-
-#include "cc/base/scoped_ptr_vector.h"
-#include "cc/output/filter_operations.h"
-#include "cc/quads/render_pass.h"
-#include "cc/resources/resource_provider.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace gfx {
-class Rect;
-class Transform;
-}
-
-namespace cc {
-
-class SolidColorDrawQuad;
-class TestRenderPass;
-
-// Adds a new render pass with the provided properties to the given
-// render pass list.
-TestRenderPass* AddRenderPass(RenderPassList* pass_list,
-                              RenderPassId id,
-                              const gfx::Rect& output_rect,
-                              const gfx::Transform& root_transform);
-
-// Adds a solid quad to a given render pass.
-SolidColorDrawQuad* AddQuad(TestRenderPass* pass,
-                            const gfx::Rect& rect,
-                            SkColor color);
-
-// Adds a solid quad to a given render pass and sets is_clipped=true.
-SolidColorDrawQuad* AddClippedQuad(TestRenderPass* pass,
-                                   const gfx::Rect& rect,
-                                   SkColor color);
-
-// Adds a solid quad with a transform to a given render pass.
-SolidColorDrawQuad* AddTransformedQuad(TestRenderPass* pass,
-                                       const gfx::Rect& rect,
-                                       SkColor color,
-                                       const gfx::Transform& transform);
-
-// Adds a render pass quad to an existing render pass.
-void AddRenderPassQuad(TestRenderPass* to_pass,
-                       TestRenderPass* contributing_pass);
-
-// Adds a render pass quad with the given mask resource, filter, and transform.
-void AddRenderPassQuad(TestRenderPass* toPass,
-                       TestRenderPass* contributing_pass,
-                       ResourceProvider::ResourceId mask_resource_id,
-                       const FilterOperations& filters,
-                       gfx::Transform transform,
-                       SkXfermode::Mode blend_mode);
-
-}  // namespace cc
-
-#endif  // CC_TEST_RENDER_PASS_TEST_UTILS_H_
diff --git a/cc/test/run_all_perftests.cc b/cc/test/run_all_perftests.cc
deleted file mode 100644
index e2dfbcf..0000000
--- a/cc/test/run_all_perftests.cc
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2013 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.
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "cc/test/cc_test_suite.h"
-
-int main(int argc, char** argv) {
-  cc::CCTestSuite test_suite(argc, argv);
-
-  // Always run the perf tests serially, to avoid distorting
-  // perf measurements with randomness resulting from running
-  // in parallel.
-  return base::LaunchUnitTestsSerially(
-      argc, argv, base::Bind(&cc::CCTestSuite::Run,
-                             base::Unretained(&test_suite)));
-}
diff --git a/cc/test/run_all_unittests.cc b/cc/test/run_all_unittests.cc
deleted file mode 100644
index 6d18d8d..0000000
--- a/cc/test/run_all_unittests.cc
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright (c) 2012 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.
-
-#include "base/bind.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "cc/test/cc_test_suite.h"
-
-int main(int argc, char** argv) {
-  cc::CCTestSuite test_suite(argc, argv);
-
-  return base::LaunchUnitTests(
-      argc,
-      argv,
-      base::Bind(&cc::CCTestSuite::Run, base::Unretained(&test_suite)));
-}
diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc
deleted file mode 100644
index f25d6eb..0000000
--- a/cc/test/scheduler_test_common.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/scheduler_test_common.h"
-
-#include <string>
-
-#include "base/logging.h"
-
-namespace cc {
-
-void FakeTimeSourceClient::OnTimerTick() {
-  tick_called_ = true;
-}
-
-base::TimeTicks FakeDelayBasedTimeSource::Now() const { return now_; }
-
-TestDelayBasedTimeSource::TestDelayBasedTimeSource(
-    scoped_refptr<TestNowSource> now_src,
-    base::TimeDelta interval,
-    OrderedSimpleTaskRunner* task_runner)
-    : DelayBasedTimeSource(interval, task_runner), now_src_(now_src) {
-}
-
-base::TimeTicks TestDelayBasedTimeSource::Now() const {
-  return now_src_->Now();
-}
-
-std::string TestDelayBasedTimeSource::TypeString() const {
-  return "TestDelayBasedTimeSource";
-}
-
-TestDelayBasedTimeSource::~TestDelayBasedTimeSource() {
-}
-
-void FakeBeginFrameSource::DidFinishFrame(size_t remaining_frames) {
-  remaining_frames_ = remaining_frames;
-}
-void FakeBeginFrameSource::AsValueInto(
-    base::trace_event::TracedValue* dict) const {
-  dict->SetString("type", "FakeBeginFrameSource");
-  BeginFrameSourceMixIn::AsValueInto(dict);
-}
-
-TestBackToBackBeginFrameSource::TestBackToBackBeginFrameSource(
-    scoped_refptr<TestNowSource> now_src,
-    base::SingleThreadTaskRunner* task_runner)
-    : BackToBackBeginFrameSource(task_runner), now_src_(now_src) {
-}
-
-TestBackToBackBeginFrameSource::~TestBackToBackBeginFrameSource() {
-}
-
-base::TimeTicks TestBackToBackBeginFrameSource::Now() {
-  return now_src_->Now();
-}
-
-TestSyntheticBeginFrameSource::TestSyntheticBeginFrameSource(
-    scoped_refptr<DelayBasedTimeSource> time_source)
-    : SyntheticBeginFrameSource(time_source) {
-}
-
-TestSyntheticBeginFrameSource::~TestSyntheticBeginFrameSource() {
-}
-
-TestSchedulerFrameSourcesConstructor::TestSchedulerFrameSourcesConstructor(
-    OrderedSimpleTaskRunner* test_task_runner,
-    TestNowSource* now_src)
-    : test_task_runner_(test_task_runner), now_src_(now_src) {
-}
-TestSchedulerFrameSourcesConstructor::~TestSchedulerFrameSourcesConstructor() {
-}
-
-BeginFrameSource*
-TestSchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
-    Scheduler* scheduler) {
-  if (scheduler->settings_.use_external_begin_frame_source) {
-    return SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
-        scheduler);
-  } else {
-    TRACE_EVENT1(
-        "cc",
-        "TestSchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource",
-        "source",
-        "TestSyntheticBeginFrameSource");
-    scoped_ptr<TestSyntheticBeginFrameSource> synthetic_source =
-        TestSyntheticBeginFrameSource::Create(
-            now_src_, test_task_runner_, BeginFrameArgs::DefaultInterval());
-
-    DCHECK(!scheduler->vsync_observer_);
-    scheduler->vsync_observer_ = synthetic_source.get();
-
-    DCHECK(!scheduler->primary_frame_source_internal_);
-    scheduler->primary_frame_source_internal_ = synthetic_source.Pass();
-    return scheduler->primary_frame_source_internal_.get();
-  }
-}
-
-BeginFrameSource*
-TestSchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource(
-    Scheduler* scheduler) {
-  TRACE_EVENT1(
-      "cc",
-      "TestSchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource",
-      "source",
-      "TestSyntheticBeginFrameSource");
-  DCHECK(!(scheduler->background_frame_source_internal_));
-  scheduler->background_frame_source_internal_ =
-      TestSyntheticBeginFrameSource::Create(
-          now_src_, test_task_runner_, base::TimeDelta::FromSeconds(1));
-  return scheduler->background_frame_source_internal_.get();
-}
-
-BeginFrameSource*
-TestSchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource(
-    Scheduler* scheduler) {
-  TRACE_EVENT1(
-      "cc",
-      "TestSchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource",
-      "source", "TestBackToBackBeginFrameSource");
-  DCHECK(!scheduler->unthrottled_frame_source_internal_);
-  scheduler->unthrottled_frame_source_internal_ =
-      TestBackToBackBeginFrameSource::Create(now_src_, test_task_runner_);
-  return scheduler->unthrottled_frame_source_internal_.get();
-}
-
-TestScheduler::TestScheduler(
-    scoped_refptr<TestNowSource> now_src,
-    SchedulerClient* client,
-    const SchedulerSettings& scheduler_settings,
-    int layer_tree_host_id,
-    const scoped_refptr<OrderedSimpleTaskRunner>& test_task_runner,
-    TestSchedulerFrameSourcesConstructor* frame_sources_constructor,
-    scoped_ptr<BeginFrameSource> external_begin_frame_source)
-    : Scheduler(client,
-                scheduler_settings,
-                layer_tree_host_id,
-                test_task_runner,
-                external_begin_frame_source.Pass(),
-                frame_sources_constructor),
-      now_src_(now_src) {
-}
-
-base::TimeTicks TestScheduler::Now() const {
-  return now_src_->Now();
-}
-
-TestScheduler::~TestScheduler() {
-}
-
-}  // namespace cc
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h
deleted file mode 100644
index 763ccc8..0000000
--- a/cc/test/scheduler_test_common.h
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2011 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.
-
-#ifndef CC_TEST_SCHEDULER_TEST_COMMON_H_
-#define CC_TEST_SCHEDULER_TEST_COMMON_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "cc/scheduler/delay_based_time_source.h"
-#include "cc/scheduler/scheduler.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-
-class FakeTimeSourceClient : public TimeSourceClient {
- public:
-  FakeTimeSourceClient() : tick_called_(false) {}
-  void Reset() { tick_called_ = false; }
-  bool TickCalled() const { return tick_called_; }
-
-  // TimeSourceClient implementation.
-  void OnTimerTick() override;
-
- protected:
-  bool tick_called_;
-};
-
-class FakeDelayBasedTimeSource : public DelayBasedTimeSource {
- public:
-  static scoped_refptr<FakeDelayBasedTimeSource> Create(
-      base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) {
-    return make_scoped_refptr(new FakeDelayBasedTimeSource(interval,
-                                                           task_runner));
-  }
-
-  void SetNow(base::TimeTicks time) { now_ = time; }
-  base::TimeTicks Now() const override;
-
- protected:
-  FakeDelayBasedTimeSource(base::TimeDelta interval,
-                           base::SingleThreadTaskRunner* task_runner)
-      : DelayBasedTimeSource(interval, task_runner) {}
-  ~FakeDelayBasedTimeSource() override {}
-
-  base::TimeTicks now_;
-};
-
-class TestDelayBasedTimeSource : public DelayBasedTimeSource {
- public:
-  static scoped_refptr<TestDelayBasedTimeSource> Create(
-      scoped_refptr<TestNowSource> now_src,
-      base::TimeDelta interval,
-      OrderedSimpleTaskRunner* task_runner) {
-    return make_scoped_refptr(
-        new TestDelayBasedTimeSource(now_src, interval, task_runner));
-  }
-
- protected:
-  TestDelayBasedTimeSource(scoped_refptr<TestNowSource> now_src,
-                           base::TimeDelta interval,
-                           OrderedSimpleTaskRunner* task_runner);
-
-  // Overridden from DelayBasedTimeSource
-  ~TestDelayBasedTimeSource() override;
-  base::TimeTicks Now() const override;
-  std::string TypeString() const override;
-
-  scoped_refptr<TestNowSource> now_src_;
-};
-
-struct FakeBeginFrameSource : public BeginFrameSourceMixIn {
-  bool remaining_frames_ = false;
-
-  BeginFrameObserver* GetObserver() { return observer_; }
-
-  BeginFrameArgs TestLastUsedBeginFrameArgs() {
-    if (observer_) {
-      return observer_->LastUsedBeginFrameArgs();
-    }
-    return BeginFrameArgs();
-  }
-  void TestOnBeginFrame(const BeginFrameArgs& args) {
-    return CallOnBeginFrame(args);
-  }
-
-  // BeginFrameSource
-  void DidFinishFrame(size_t remaining_frames) override;
-  void AsValueInto(base::trace_event::TracedValue* dict) const override;
-
-  ~FakeBeginFrameSource() override {}
-};
-
-class TestBackToBackBeginFrameSource : public BackToBackBeginFrameSource {
- public:
-  ~TestBackToBackBeginFrameSource() override;
-
-  static scoped_ptr<TestBackToBackBeginFrameSource> Create(
-      scoped_refptr<TestNowSource> now_src,
-      base::SingleThreadTaskRunner* task_runner) {
-    return make_scoped_ptr(
-        new TestBackToBackBeginFrameSource(now_src, task_runner));
-  }
-
- protected:
-  TestBackToBackBeginFrameSource(scoped_refptr<TestNowSource> now_src,
-                                 base::SingleThreadTaskRunner* task_runner);
-
-  base::TimeTicks Now() override;
-
-  scoped_refptr<TestNowSource> now_src_;
-};
-
-class TestSyntheticBeginFrameSource : public SyntheticBeginFrameSource {
- public:
-  ~TestSyntheticBeginFrameSource() override;
-
-  static scoped_ptr<TestSyntheticBeginFrameSource> Create(
-      scoped_refptr<TestNowSource> now_src,
-      OrderedSimpleTaskRunner* task_runner,
-      base::TimeDelta initial_interval) {
-    return make_scoped_ptr(
-        new TestSyntheticBeginFrameSource(TestDelayBasedTimeSource::Create(
-            now_src, initial_interval, task_runner)));
-  }
-
- protected:
-  TestSyntheticBeginFrameSource(
-      scoped_refptr<DelayBasedTimeSource> time_source);
-};
-
-class TestScheduler;
-class TestSchedulerFrameSourcesConstructor
-    : public SchedulerFrameSourcesConstructor {
- public:
-  ~TestSchedulerFrameSourcesConstructor() override;
-
- protected:
-  BeginFrameSource* ConstructPrimaryFrameSource(Scheduler* scheduler) override;
-  BeginFrameSource* ConstructBackgroundFrameSource(
-      Scheduler* scheduler) override;
-  BeginFrameSource* ConstructUnthrottledFrameSource(
-      Scheduler* scheduler) override;
-
-  OrderedSimpleTaskRunner* test_task_runner_;
-  TestNowSource* now_src_;
-
- protected:
-  explicit TestSchedulerFrameSourcesConstructor(
-      OrderedSimpleTaskRunner* test_task_runner,
-      TestNowSource* now_src);
-  friend class TestScheduler;
-};
-
-class TestScheduler : public Scheduler {
- public:
-  static scoped_ptr<TestScheduler> Create(
-      scoped_refptr<TestNowSource> now_src,
-      SchedulerClient* client,
-      const SchedulerSettings& scheduler_settings,
-      int layer_tree_host_id,
-      const scoped_refptr<OrderedSimpleTaskRunner>& task_runner,
-      scoped_ptr<BeginFrameSource> external_begin_frame_source) {
-    TestSchedulerFrameSourcesConstructor frame_sources_constructor(
-        task_runner.get(), now_src.get());
-    return make_scoped_ptr(new TestScheduler(
-                                   now_src,
-                                   client,
-                                   scheduler_settings,
-                                   layer_tree_host_id,
-                                   task_runner,
-                                   &frame_sources_constructor,
-                                   external_begin_frame_source.Pass()));
-  }
-
-  // Extra test helper functionality
-  bool IsBeginRetroFrameArgsEmpty() const {
-    return begin_retro_frame_args_.empty();
-  }
-
-  bool CanStart() const { return state_machine_.CanStartForTesting(); }
-
-  BeginFrameSource& frame_source() { return *frame_source_; }
-  bool FrameProductionThrottled() { return throttle_frame_production_; }
-
-  ~TestScheduler() override;
-
-  void NotifyReadyToCommitThenActivateIfNeeded() {
-    NotifyReadyToCommit();
-    if (settings_.impl_side_painting) {
-      NotifyReadyToActivate();
-    }
-  }
-
- protected:
-  // Overridden from Scheduler.
-  base::TimeTicks Now() const override;
-
- private:
-  TestScheduler(
-      scoped_refptr<TestNowSource> now_src,
-      SchedulerClient* client,
-      const SchedulerSettings& scheduler_settings,
-      int layer_tree_host_id,
-      const scoped_refptr<OrderedSimpleTaskRunner>& test_task_runner,
-      TestSchedulerFrameSourcesConstructor* frame_sources_constructor,
-      scoped_ptr<BeginFrameSource> external_begin_frame_source);
-
-  scoped_refptr<TestNowSource> now_src_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_SCHEDULER_TEST_COMMON_H_
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc
deleted file mode 100644
index ef61e21..0000000
--- a/cc/test/skia_common.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 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.
-
-#include "cc/test/skia_common.h"
-
-#include "cc/resources/display_item_list.h"
-#include "cc/resources/picture.h"
-#include "skia/ext/refptr.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/skia_util.h"
-
-namespace cc {
-
-void DrawPicture(unsigned char* buffer,
-                 const gfx::Rect& layer_rect,
-                 scoped_refptr<Picture> picture) {
-  SkImageInfo info =
-      SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
-  SkBitmap bitmap;
-  bitmap.installPixels(info, buffer, info.minRowBytes());
-  SkCanvas canvas(bitmap);
-  canvas.clipRect(gfx::RectToSkRect(layer_rect));
-  // We're drawing the entire canvas, so the negated content region is empty.
-  gfx::Rect negated_content_region;
-  picture->Raster(&canvas, NULL, negated_content_region, 1.0f);
-}
-
-void DrawDisplayList(unsigned char* buffer,
-                     const gfx::Rect& layer_rect,
-                     scoped_refptr<DisplayItemList> list) {
-  SkImageInfo info =
-      SkImageInfo::MakeN32Premul(layer_rect.width(), layer_rect.height());
-  SkBitmap bitmap;
-  bitmap.installPixels(info, buffer, info.minRowBytes());
-  SkCanvas canvas(bitmap);
-  canvas.clipRect(gfx::RectToSkRect(layer_rect));
-  list->Raster(&canvas, NULL, 1.0f);
-}
-
-void CreateBitmap(const gfx::Size& size, const char* uri, SkBitmap* bitmap) {
-  SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
-
-  bitmap->allocPixels(info);
-  bitmap->pixelRef()->setImmutable();
-  bitmap->pixelRef()->setURI(uri);
-}
-
-}  // namespace cc
diff --git a/cc/test/skia_common.h b/cc/test/skia_common.h
deleted file mode 100644
index 51ebcc5..0000000
--- a/cc/test/skia_common.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2012 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.
-
-#ifndef CC_TEST_SKIA_COMMON_H_
-#define CC_TEST_SKIA_COMMON_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkFlattenable.h"
-#include "third_party/skia/include/core/SkPixelRef.h"
-
-namespace gfx {
-class Rect;
-class Size;
-}
-
-namespace cc {
-class Picture;
-class DisplayItemList;
-
-void DrawPicture(unsigned char* buffer,
-                 const gfx::Rect& layer_rect,
-                 scoped_refptr<Picture> picture);
-
-void DrawDisplayList(unsigned char* buffer,
-                     const gfx::Rect& layer_rect,
-                     scoped_refptr<DisplayItemList> list);
-
-void CreateBitmap(const gfx::Size& size, const char* uri, SkBitmap* bitmap);
-
-}  // namespace cc
-
-#endif  // CC_TEST_SKIA_COMMON_H_
diff --git a/cc/test/test_context_provider.cc b/cc/test/test_context_provider.cc
deleted file mode 100644
index 90df22a..0000000
--- a/cc/test/test_context_provider.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_context_provider.h"
-
-#include <set>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback_helpers.h"
-#include "base/logging.h"
-#include "cc/test/test_gles2_interface.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/gl/SkNullGLContext.h"
-
-namespace cc {
-
-// static
-scoped_refptr<TestContextProvider> TestContextProvider::Create() {
-  return Create(TestWebGraphicsContext3D::Create().Pass());
-}
-
-// static
-scoped_refptr<TestContextProvider> TestContextProvider::Create(
-    scoped_ptr<TestWebGraphicsContext3D> context) {
-  if (!context)
-    return NULL;
-  return new TestContextProvider(context.Pass());
-}
-
-TestContextProvider::TestContextProvider(
-    scoped_ptr<TestWebGraphicsContext3D> context)
-    : context3d_(context.Pass()),
-      context_gl_(new TestGLES2Interface(context3d_.get())),
-      bound_(false),
-      destroyed_(false),
-      weak_ptr_factory_(this) {
-  DCHECK(main_thread_checker_.CalledOnValidThread());
-  DCHECK(context3d_);
-  context_thread_checker_.DetachFromThread();
-  context3d_->set_test_support(&support_);
-}
-
-TestContextProvider::~TestContextProvider() {
-  DCHECK(main_thread_checker_.CalledOnValidThread() ||
-         context_thread_checker_.CalledOnValidThread());
-}
-
-bool TestContextProvider::BindToCurrentThread() {
-  // This is called on the thread the context will be used.
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  if (bound_)
-    return true;
-
-  if (context3d_->isContextLost()) {
-    base::AutoLock lock(destroyed_lock_);
-    destroyed_ = true;
-    return false;
-  }
-  bound_ = true;
-
-  context3d_->set_context_lost_callback(
-      base::Bind(&TestContextProvider::OnLostContext,
-                 base::Unretained(this)));
-
-  return true;
-}
-
-void TestContextProvider::DetachFromThread() {
-  context_thread_checker_.DetachFromThread();
-}
-
-ContextProvider::Capabilities TestContextProvider::ContextCapabilities() {
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  return context3d_->test_capabilities();
-}
-
-gpu::gles2::GLES2Interface* TestContextProvider::ContextGL() {
-  DCHECK(context3d_);
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  return context_gl_.get();
-}
-
-gpu::ContextSupport* TestContextProvider::ContextSupport() {
-  return &support_;
-}
-
-class GrContext* TestContextProvider::GrContext() {
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  if (gr_context_)
-    return gr_context_.get();
-
-  skia::RefPtr<class SkGLContext> gl_context =
-      skia::AdoptRef(SkNullGLContext::Create(kNone_GrGLStandard));
-  gl_context->makeCurrent();
-  gr_context_ = skia::AdoptRef(GrContext::Create(
-      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(gl_context->gl())));
-
-  // If GlContext is already lost, also abandon the new GrContext.
-  if (IsContextLost())
-    gr_context_->abandonContext();
-
-  return gr_context_.get();
-}
-
-void TestContextProvider::SetupLock() {
-}
-
-base::Lock* TestContextProvider::GetLock() {
-  return &context_lock_;
-}
-
-bool TestContextProvider::IsContextLost() {
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  return context3d_->isContextLost();
-}
-
-void TestContextProvider::VerifyContexts() {
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  if (context3d_->isContextLost()) {
-    base::AutoLock lock(destroyed_lock_);
-    destroyed_ = true;
-  }
-}
-
-void TestContextProvider::DeleteCachedResources() {
-}
-
-bool TestContextProvider::DestroyedOnMainThread() {
-  DCHECK(main_thread_checker_.CalledOnValidThread());
-
-  base::AutoLock lock(destroyed_lock_);
-  return destroyed_;
-}
-
-void TestContextProvider::OnLostContext() {
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-  {
-    base::AutoLock lock(destroyed_lock_);
-    if (destroyed_)
-      return;
-    destroyed_ = true;
-  }
-  if (!lost_context_callback_.is_null())
-    base::ResetAndReturn(&lost_context_callback_).Run();
-  if (gr_context_)
-    gr_context_->abandonContext();
-}
-
-TestWebGraphicsContext3D* TestContextProvider::TestContext3d() {
-  DCHECK(bound_);
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-
-  return context3d_.get();
-}
-
-TestWebGraphicsContext3D* TestContextProvider::UnboundTestContext3d() {
-  return context3d_.get();
-}
-
-void TestContextProvider::SetMemoryAllocation(
-    const ManagedMemoryPolicy& policy) {
-  if (memory_policy_changed_callback_.is_null())
-    return;
-  memory_policy_changed_callback_.Run(policy);
-}
-
-void TestContextProvider::SetLostContextCallback(
-    const LostContextCallback& cb) {
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-  DCHECK(lost_context_callback_.is_null() || cb.is_null());
-  lost_context_callback_ = cb;
-}
-
-void TestContextProvider::SetMemoryPolicyChangedCallback(
-    const MemoryPolicyChangedCallback& cb) {
-  DCHECK(context_thread_checker_.CalledOnValidThread());
-  DCHECK(memory_policy_changed_callback_.is_null() || cb.is_null());
-  memory_policy_changed_callback_ = cb;
-}
-
-void TestContextProvider::SetMaxTransferBufferUsageBytes(
-    size_t max_transfer_buffer_usage_bytes) {
-  context3d_->SetMaxTransferBufferUsageBytes(max_transfer_buffer_usage_bytes);
-}
-
-}  // namespace cc
diff --git a/cc/test/test_context_provider.h b/cc/test/test_context_provider.h
deleted file mode 100644
index 9dd7b62..0000000
--- a/cc/test/test_context_provider.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_CONTEXT_PROVIDER_H_
-#define CC_TEST_TEST_CONTEXT_PROVIDER_H_
-
-#include "base/callback.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/synchronization/lock.h"
-#include "base/threading/thread_checker.h"
-#include "cc/output/context_provider.h"
-#include "cc/test/test_context_support.h"
-#include "gpu/command_buffer/client/gles2_interface_stub.h"
-#include "skia/ext/refptr.h"
-
-namespace cc {
-class TestWebGraphicsContext3D;
-class TestGLES2Interface;
-
-class TestContextProvider : public ContextProvider {
- public:
-  typedef base::Callback<scoped_ptr<TestWebGraphicsContext3D>(void)>
-    CreateCallback;
-
-  static scoped_refptr<TestContextProvider> Create();
-  static scoped_refptr<TestContextProvider> Create(
-      scoped_ptr<TestWebGraphicsContext3D> context);
-
-  bool BindToCurrentThread() override;
-  void DetachFromThread() override;
-  Capabilities ContextCapabilities() override;
-  gpu::gles2::GLES2Interface* ContextGL() override;
-  gpu::ContextSupport* ContextSupport() override;
-  class GrContext* GrContext() override;
-  void SetupLock() override;
-  base::Lock* GetLock() override;
-  bool IsContextLost() override;
-  void VerifyContexts() override;
-  void DeleteCachedResources() override;
-  bool DestroyedOnMainThread() override;
-  void SetLostContextCallback(const LostContextCallback& cb) override;
-  void SetMemoryPolicyChangedCallback(
-      const MemoryPolicyChangedCallback& cb) override;
-
-  TestWebGraphicsContext3D* TestContext3d();
-
-  // This returns the TestWebGraphicsContext3D but is valid to call
-  // before the context is bound to a thread. This is needed to set up
-  // state on the test context before binding. Don't call
-  // InitializeOnCurrentThread on the context returned from this method.
-  TestWebGraphicsContext3D* UnboundTestContext3d();
-
-  TestContextSupport* support() { return &support_; }
-
-  void SetMemoryAllocation(const ManagedMemoryPolicy& policy);
-
-  void SetMaxTransferBufferUsageBytes(size_t max_transfer_buffer_usage_bytes);
-
- protected:
-  explicit TestContextProvider(scoped_ptr<TestWebGraphicsContext3D> context);
-  ~TestContextProvider() override;
-
- private:
-  void OnLostContext();
-
-  TestContextSupport support_;
-
-  scoped_ptr<TestWebGraphicsContext3D> context3d_;
-  scoped_ptr<TestGLES2Interface> context_gl_;
-  bool bound_;
-
-  base::ThreadChecker main_thread_checker_;
-  base::ThreadChecker context_thread_checker_;
-
-  base::Lock destroyed_lock_;
-  bool destroyed_;
-
-  base::Lock context_lock_;
-
-  LostContextCallback lost_context_callback_;
-  MemoryPolicyChangedCallback memory_policy_changed_callback_;
-  skia::RefPtr<class GrContext> gr_context_;
-
-  base::WeakPtrFactory<TestContextProvider> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestContextProvider);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_CONTEXT_PROVIDER_H_
-
diff --git a/cc/test/test_context_support.cc b/cc/test/test_context_support.cc
deleted file mode 100644
index f74f692..0000000
--- a/cc/test/test_context_support.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_context_support.h"
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-
-namespace cc {
-
-TestContextSupport::TestContextSupport()
-    : weak_ptr_factory_(this) {
-}
-
-TestContextSupport::~TestContextSupport() {}
-
-void TestContextSupport::SignalSyncPoint(uint32 sync_point,
-                                         const base::Closure& callback) {
-  sync_point_callbacks_.push_back(callback);
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&TestContextSupport::CallAllSyncPointCallbacks,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-void TestContextSupport::SignalQuery(uint32 query,
-                                     const base::Closure& callback) {
-  sync_point_callbacks_.push_back(callback);
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE,
-      base::Bind(&TestContextSupport::CallAllSyncPointCallbacks,
-                 weak_ptr_factory_.GetWeakPtr()));
-}
-
-void TestContextSupport::SetSurfaceVisible(bool visible) {
-  if (!set_visible_callback_.is_null()) {
-    set_visible_callback_.Run(visible);
-  }
-}
-
-void TestContextSupport::CallAllSyncPointCallbacks() {
-  for (size_t i = 0; i < sync_point_callbacks_.size(); ++i) {
-    base::MessageLoop::current()->PostTask(
-        FROM_HERE, sync_point_callbacks_[i]);
-  }
-  sync_point_callbacks_.clear();
-}
-
-void TestContextSupport::SetSurfaceVisibleCallback(
-    const SurfaceVisibleCallback& set_visible_callback) {
-  set_visible_callback_ = set_visible_callback;
-}
-
-void TestContextSupport::SetScheduleOverlayPlaneCallback(
-    const ScheduleOverlayPlaneCallback& schedule_overlay_plane_callback) {
-  schedule_overlay_plane_callback_ = schedule_overlay_plane_callback;
-}
-
-void TestContextSupport::Swap() {
-}
-
-uint32 TestContextSupport::InsertFutureSyncPointCHROMIUM() {
-  NOTIMPLEMENTED();
-  return 0;
-}
-
-void TestContextSupport::RetireSyncPointCHROMIUM(uint32 sync_point) {
-  NOTIMPLEMENTED();
-}
-
-void TestContextSupport::PartialSwapBuffers(const gfx::Rect& sub_buffer) {
-}
-
-void TestContextSupport::ScheduleOverlayPlane(
-    int plane_z_order,
-    gfx::OverlayTransform plane_transform,
-    unsigned overlay_texture_id,
-    const gfx::Rect& display_bounds,
-    const gfx::RectF& uv_rect) {
-  if (!schedule_overlay_plane_callback_.is_null()) {
-    schedule_overlay_plane_callback_.Run(plane_z_order,
-                                         plane_transform,
-                                         overlay_texture_id,
-                                         display_bounds,
-                                         uv_rect);
-  }
-}
-
-}  // namespace cc
diff --git a/cc/test/test_context_support.h b/cc/test/test_context_support.h
deleted file mode 100644
index 307b881..0000000
--- a/cc/test/test_context_support.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_CONTEXT_SUPPORT_H_
-#define CC_TEST_TEST_CONTEXT_SUPPORT_H_
-
-#include <vector>
-
-#include "base/memory/weak_ptr.h"
-#include "gpu/command_buffer/client/context_support.h"
-
-namespace cc {
-
-class TestContextSupport : public gpu::ContextSupport {
- public:
-  TestContextSupport();
-  ~TestContextSupport() override;
-
-  // gpu::ContextSupport implementation.
-  void SignalSyncPoint(uint32 sync_point,
-                       const base::Closure& callback) override;
-  void SignalQuery(uint32 query, const base::Closure& callback) override;
-  void SetSurfaceVisible(bool visible) override;
-  void Swap() override;
-  void PartialSwapBuffers(const gfx::Rect& sub_buffer) override;
-  uint32 InsertFutureSyncPointCHROMIUM() override;
-  void RetireSyncPointCHROMIUM(uint32 sync_point) override;
-  void ScheduleOverlayPlane(int plane_z_order,
-                            gfx::OverlayTransform plane_transform,
-                            unsigned overlay_texture_id,
-                            const gfx::Rect& display_bounds,
-                            const gfx::RectF& uv_rect) override;
-
-  void CallAllSyncPointCallbacks();
-
-  typedef base::Callback<void(bool visible)> SurfaceVisibleCallback;
-  void SetSurfaceVisibleCallback(
-      const SurfaceVisibleCallback& set_visible_callback);
-
-  typedef base::Callback<void(int plane_z_order,
-                              gfx::OverlayTransform plane_transform,
-                              unsigned overlay_texture_id,
-                              const gfx::Rect& display_bounds,
-                              const gfx::RectF& crop_rect)>
-      ScheduleOverlayPlaneCallback;
-  void SetScheduleOverlayPlaneCallback(
-      const ScheduleOverlayPlaneCallback& schedule_overlay_plane_callback);
-
- private:
-  std::vector<base::Closure> sync_point_callbacks_;
-  SurfaceVisibleCallback set_visible_callback_;
-  ScheduleOverlayPlaneCallback schedule_overlay_plane_callback_;
-
-  base::WeakPtrFactory<TestContextSupport> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestContextSupport);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_CONTEXT_SUPPORT_H_
diff --git a/cc/test/test_gles2_interface.cc b/cc/test/test_gles2_interface.cc
deleted file mode 100644
index 38ada98..0000000
--- a/cc/test/test_gles2_interface.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_gles2_interface.h"
-
-#include "base/logging.h"
-#include "cc/test/test_web_graphics_context_3d.h"
-
-namespace cc {
-
-TestGLES2Interface::TestGLES2Interface(TestWebGraphicsContext3D* test_context)
-    : test_context_(test_context) {
-  DCHECK(test_context_);
-}
-
-TestGLES2Interface::~TestGLES2Interface() {}
-
-void TestGLES2Interface::GenTextures(GLsizei n, GLuint* textures) {
-  for (GLsizei i = 0; i < n; ++i) {
-    textures[i] = test_context_->createTexture();
-  }
-}
-
-void TestGLES2Interface::GenBuffers(GLsizei n, GLuint* buffers) {
-  for (GLsizei i = 0; i < n; ++i) {
-    buffers[i] = test_context_->createBuffer();
-  }
-}
-
-void TestGLES2Interface::GenFramebuffers(GLsizei n, GLuint* framebuffers) {
-  for (GLsizei i = 0; i < n; ++i) {
-    framebuffers[i] = test_context_->createFramebuffer();
-  }
-}
-
-void TestGLES2Interface::GenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
-  for (GLsizei i = 0; i < n; ++i) {
-    renderbuffers[i] = test_context_->createRenderbuffer();
-  }
-}
-
-void TestGLES2Interface::GenQueriesEXT(GLsizei n, GLuint* queries) {
-  for (GLsizei i = 0; i < n; ++i) {
-    queries[i] = test_context_->createQueryEXT();
-  }
-}
-
-void TestGLES2Interface::DeleteTextures(GLsizei n, const GLuint* textures) {
-  for (GLsizei i = 0; i < n; ++i) {
-    test_context_->deleteTexture(textures[i]);
-  }
-}
-
-void TestGLES2Interface::DeleteBuffers(GLsizei n, const GLuint* buffers) {
-  for (GLsizei i = 0; i < n; ++i) {
-    test_context_->deleteBuffer(buffers[i]);
-  }
-}
-
-void TestGLES2Interface::DeleteFramebuffers(GLsizei n,
-                                            const GLuint* framebuffers) {
-  for (GLsizei i = 0; i < n; ++i) {
-    test_context_->deleteFramebuffer(framebuffers[i]);
-  }
-}
-
-void TestGLES2Interface::DeleteQueriesEXT(GLsizei n, const GLuint* queries) {
-  for (GLsizei i = 0; i < n; ++i) {
-    test_context_->deleteQueryEXT(queries[i]);
-  }
-}
-
-GLuint TestGLES2Interface::CreateShader(GLenum type) {
-  return test_context_->createShader(type);
-}
-
-GLuint TestGLES2Interface::CreateProgram() {
-  return test_context_->createProgram();
-}
-
-void TestGLES2Interface::BindTexture(GLenum target, GLuint texture) {
-  test_context_->bindTexture(target, texture);
-}
-
-void TestGLES2Interface::GetIntegerv(GLenum pname, GLint* params) {
-  test_context_->getIntegerv(pname, params);
-}
-
-void TestGLES2Interface::GetShaderiv(GLuint shader,
-                                     GLenum pname,
-                                     GLint* params) {
-  test_context_->getShaderiv(shader, pname, params);
-}
-
-void TestGLES2Interface::GetProgramiv(GLuint program,
-                                      GLenum pname,
-                                      GLint* params) {
-  test_context_->getProgramiv(program, pname, params);
-}
-
-void TestGLES2Interface::GetShaderPrecisionFormat(GLenum shadertype,
-                                                  GLenum precisiontype,
-                                                  GLint* range,
-                                                  GLint* precision) {
-  test_context_->getShaderPrecisionFormat(
-      shadertype, precisiontype, range, precision);
-}
-
-void TestGLES2Interface::Viewport(GLint x,
-                                  GLint y,
-                                  GLsizei width,
-                                  GLsizei height) {
-  test_context_->viewport(x, y, width, height);
-}
-
-void TestGLES2Interface::ActiveTexture(GLenum target) {
-  test_context_->activeTexture(target);
-}
-
-void TestGLES2Interface::UseProgram(GLuint program) {
-  test_context_->useProgram(program);
-}
-
-GLenum TestGLES2Interface::CheckFramebufferStatus(GLenum target) {
-  return test_context_->checkFramebufferStatus(target);
-}
-
-void TestGLES2Interface::Scissor(GLint x,
-                                 GLint y,
-                                 GLsizei width,
-                                 GLsizei height) {
-  test_context_->scissor(x, y, width, height);
-}
-
-void TestGLES2Interface::DrawElements(GLenum mode,
-                                      GLsizei count,
-                                      GLenum type,
-                                      const void* indices) {
-  test_context_->drawElements(
-      mode, count, type, reinterpret_cast<intptr_t>(indices));
-}
-
-void TestGLES2Interface::ClearColor(GLclampf red,
-                                    GLclampf green,
-                                    GLclampf blue,
-                                    GLclampf alpha) {
-  test_context_->clearColor(red, green, blue, alpha);
-}
-
-void TestGLES2Interface::ClearStencil(GLint s) {
-  test_context_->clearStencil(s);
-}
-
-void TestGLES2Interface::Clear(GLbitfield mask) { test_context_->clear(mask); }
-
-void TestGLES2Interface::Flush() { test_context_->flush(); }
-
-void TestGLES2Interface::Finish() { test_context_->finish(); }
-
-void TestGLES2Interface::ShallowFlushCHROMIUM() {
-  test_context_->shallowFlushCHROMIUM();
-}
-
-void TestGLES2Interface::Enable(GLenum cap) { test_context_->enable(cap); }
-
-void TestGLES2Interface::Disable(GLenum cap) { test_context_->disable(cap); }
-
-void TestGLES2Interface::BindRenderbuffer(GLenum target, GLuint buffer) {
-  test_context_->bindRenderbuffer(target, buffer);
-}
-
-void TestGLES2Interface::BindFramebuffer(GLenum target, GLuint buffer) {
-  test_context_->bindFramebuffer(target, buffer);
-}
-
-void TestGLES2Interface::BindBuffer(GLenum target, GLuint buffer) {
-  test_context_->bindBuffer(target, buffer);
-}
-
-void TestGLES2Interface::PixelStorei(GLenum pname, GLint param) {
-  test_context_->pixelStorei(pname, param);
-}
-
-void TestGLES2Interface::TexImage2D(GLenum target,
-                                    GLint level,
-                                    GLint internalformat,
-                                    GLsizei width,
-                                    GLsizei height,
-                                    GLint border,
-                                    GLenum format,
-                                    GLenum type,
-                                    const void* pixels) {
-  test_context_->texImage2D(target,
-                            level,
-                            internalformat,
-                            width,
-                            height,
-                            border,
-                            format,
-                            type,
-                            pixels);
-}
-
-void TestGLES2Interface::TexSubImage2D(GLenum target,
-                                       GLint level,
-                                       GLint xoffset,
-                                       GLint yoffset,
-                                       GLsizei width,
-                                       GLsizei height,
-                                       GLenum format,
-                                       GLenum type,
-                                       const void* pixels) {
-  test_context_->texSubImage2D(
-      target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void TestGLES2Interface::TexStorage2DEXT(GLenum target,
-                                         GLsizei levels,
-                                         GLenum internalformat,
-                                         GLsizei width,
-                                         GLsizei height) {
-  test_context_->texStorage2DEXT(target, levels, internalformat, width, height);
-}
-
-void TestGLES2Interface::TexImageIOSurface2DCHROMIUM(GLenum target,
-                                                     GLsizei width,
-                                                     GLsizei height,
-                                                     GLuint io_surface_id,
-                                                     GLuint plane) {
-  test_context_->texImageIOSurface2DCHROMIUM(
-      target, width, height, io_surface_id, plane);
-}
-
-void TestGLES2Interface::TexParameteri(GLenum target,
-                                       GLenum pname,
-                                       GLint param) {
-  test_context_->texParameteri(target, pname, param);
-}
-
-void TestGLES2Interface::FramebufferRenderbuffer(GLenum target,
-                                                 GLenum attachment,
-                                                 GLenum renderbuffertarget,
-                                                 GLuint renderbuffer) {
-  test_context_->framebufferRenderbuffer(
-      target, attachment, renderbuffertarget, renderbuffer);
-}
-void TestGLES2Interface::FramebufferTexture2D(GLenum target,
-                                              GLenum attachment,
-                                              GLenum textarget,
-                                              GLuint texture,
-                                              GLint level) {
-  test_context_->framebufferTexture2D(
-      target, attachment, textarget, texture, level);
-}
-
-void TestGLES2Interface::RenderbufferStorage(GLenum target,
-                                             GLenum internalformat,
-                                             GLsizei width,
-                                             GLsizei height) {
-  test_context_->renderbufferStorage(target, internalformat, width, height);
-}
-
-void TestGLES2Interface::AsyncTexImage2DCHROMIUM(GLenum target,
-                                                 GLint level,
-                                                 GLenum internalformat,
-                                                 GLsizei width,
-                                                 GLsizei height,
-                                                 GLint border,
-                                                 GLenum format,
-                                                 GLenum type,
-                                                 const void* pixels) {
-  test_context_->asyncTexImage2DCHROMIUM(target,
-                                         level,
-                                         internalformat,
-                                         width,
-                                         height,
-                                         border,
-                                         format,
-                                         type,
-                                         pixels);
-}
-
-void TestGLES2Interface::AsyncTexSubImage2DCHROMIUM(GLenum target,
-                                                    GLint level,
-                                                    GLint xoffset,
-                                                    GLint yoffset,
-                                                    GLsizei width,
-                                                    GLsizei height,
-                                                    GLenum format,
-                                                    GLenum type,
-                                                    const void* pixels) {
-  test_context_->asyncTexSubImage2DCHROMIUM(
-      target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void TestGLES2Interface::CompressedTexImage2D(GLenum target,
-                                              GLint level,
-                                              GLenum internalformat,
-                                              GLsizei width,
-                                              GLsizei height,
-                                              GLint border,
-                                              GLsizei image_size,
-                                              const void* data) {
-  test_context_->compressedTexImage2D(
-      target, level, internalformat, width, height, border, image_size, data);
-}
-
-void TestGLES2Interface::WaitAsyncTexImage2DCHROMIUM(GLenum target) {
-  test_context_->waitAsyncTexImage2DCHROMIUM(target);
-}
-
-GLuint TestGLES2Interface::CreateImageCHROMIUM(ClientBuffer buffer,
-                                               GLsizei width,
-                                               GLsizei height,
-                                               GLenum internalformat) {
-  return test_context_->createImageCHROMIUM(
-      buffer, width, height, internalformat);
-}
-
-void TestGLES2Interface::DestroyImageCHROMIUM(GLuint image_id) {
-  test_context_->destroyImageCHROMIUM(image_id);
-}
-
-GLuint TestGLES2Interface::CreateGpuMemoryBufferImageCHROMIUM(
-    GLsizei width,
-    GLsizei height,
-    GLenum internalformat,
-    GLenum usage) {
-  return test_context_->createGpuMemoryBufferImageCHROMIUM(
-      width, height, internalformat, usage);
-}
-
-void TestGLES2Interface::BindTexImage2DCHROMIUM(GLenum target, GLint image_id) {
-  test_context_->bindTexImage2DCHROMIUM(target, image_id);
-}
-
-void TestGLES2Interface::ReleaseTexImage2DCHROMIUM(GLenum target,
-                                                   GLint image_id) {
-  test_context_->releaseTexImage2DCHROMIUM(target, image_id);
-}
-
-void* TestGLES2Interface::MapBufferCHROMIUM(GLuint target, GLenum access) {
-  return test_context_->mapBufferCHROMIUM(target, access);
-}
-
-GLboolean TestGLES2Interface::UnmapBufferCHROMIUM(GLuint target) {
-  return test_context_->unmapBufferCHROMIUM(target);
-}
-
-void TestGLES2Interface::BufferData(GLenum target,
-                                    GLsizeiptr size,
-                                    const void* data,
-                                    GLenum usage) {
-  test_context_->bufferData(target, size, data, usage);
-}
-
-void TestGLES2Interface::WaitSyncPointCHROMIUM(GLuint sync_point) {
-  test_context_->waitSyncPoint(sync_point);
-}
-
-GLuint TestGLES2Interface::InsertSyncPointCHROMIUM() {
-  return test_context_->insertSyncPoint();
-}
-
-void TestGLES2Interface::BeginQueryEXT(GLenum target, GLuint id) {
-  test_context_->beginQueryEXT(target, id);
-}
-
-void TestGLES2Interface::EndQueryEXT(GLenum target) {
-  test_context_->endQueryEXT(target);
-}
-
-void TestGLES2Interface::GetQueryObjectuivEXT(GLuint id,
-                                              GLenum pname,
-                                              GLuint* params) {
-  test_context_->getQueryObjectuivEXT(id, pname, params);
-}
-
-void TestGLES2Interface::DiscardFramebufferEXT(GLenum target,
-                                               GLsizei count,
-                                               const GLenum* attachments) {
-  test_context_->discardFramebufferEXT(target, count, attachments);
-}
-
-void TestGLES2Interface::GenMailboxCHROMIUM(GLbyte* mailbox) {
-  test_context_->genMailboxCHROMIUM(mailbox);
-}
-
-void TestGLES2Interface::ProduceTextureCHROMIUM(GLenum target,
-                                                const GLbyte* mailbox) {
-  test_context_->produceTextureCHROMIUM(target, mailbox);
-}
-
-void TestGLES2Interface::ProduceTextureDirectCHROMIUM(GLuint texture,
-                                                      GLenum target,
-                                                      const GLbyte* mailbox) {
-  test_context_->produceTextureDirectCHROMIUM(texture, target, mailbox);
-}
-
-void TestGLES2Interface::ConsumeTextureCHROMIUM(GLenum target,
-                                                const GLbyte* mailbox) {
-  test_context_->consumeTextureCHROMIUM(target, mailbox);
-}
-
-GLuint TestGLES2Interface::CreateAndConsumeTextureCHROMIUM(
-    GLenum target,
-    const GLbyte* mailbox) {
-  return test_context_->createAndConsumeTextureCHROMIUM(target, mailbox);
-}
-
-void TestGLES2Interface::ResizeCHROMIUM(GLuint width,
-                                        GLuint height,
-                                        float device_scale) {
-  test_context_->reshapeWithScaleFactor(width, height, device_scale);
-}
-
-void TestGLES2Interface::LoseContextCHROMIUM(GLenum current, GLenum other) {
-  test_context_->loseContextCHROMIUM(current, other);
-}
-
-}  // namespace cc
diff --git a/cc/test/test_gles2_interface.h b/cc/test/test_gles2_interface.h
deleted file mode 100644
index 3a174af..0000000
--- a/cc/test/test_gles2_interface.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_GLES2_INTERFACE_H_
-#define CC_TEST_TEST_GLES2_INTERFACE_H_
-
-#include "gpu/command_buffer/client/gles2_interface_stub.h"
-
-namespace cc {
-class TestWebGraphicsContext3D;
-
-class TestGLES2Interface : public gpu::gles2::GLES2InterfaceStub {
- public:
-  explicit TestGLES2Interface(TestWebGraphicsContext3D* test_context);
-  ~TestGLES2Interface() override;
-
-  void GenTextures(GLsizei n, GLuint* textures) override;
-  void GenBuffers(GLsizei n, GLuint* buffers) override;
-  void GenFramebuffers(GLsizei n, GLuint* framebuffers) override;
-  void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) override;
-  void GenQueriesEXT(GLsizei n, GLuint* queries) override;
-
-  void DeleteTextures(GLsizei n, const GLuint* textures) override;
-  void DeleteBuffers(GLsizei n, const GLuint* buffers) override;
-  void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) override;
-  void DeleteQueriesEXT(GLsizei n, const GLuint* queries) override;
-
-  GLuint CreateShader(GLenum type) override;
-  GLuint CreateProgram() override;
-
-  void BindTexture(GLenum target, GLuint texture) override;
-
-  void GetIntegerv(GLenum pname, GLint* params) override;
-  void GetShaderiv(GLuint shader, GLenum pname, GLint* params) override;
-  void GetProgramiv(GLuint program, GLenum pname, GLint* params) override;
-  void GetShaderPrecisionFormat(GLenum shadertype,
-                                GLenum precisiontype,
-                                GLint* range,
-                                GLint* precision) override;
-  GLenum CheckFramebufferStatus(GLenum target) override;
-
-  void ActiveTexture(GLenum target) override;
-  void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) override;
-  void UseProgram(GLuint program) override;
-  void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) override;
-  void DrawElements(GLenum mode,
-                    GLsizei count,
-                    GLenum type,
-                    const void* indices) override;
-  void ClearColor(GLclampf red,
-                  GLclampf green,
-                  GLclampf blue,
-                  GLclampf alpha) override;
-  void ClearStencil(GLint s) override;
-  void Clear(GLbitfield mask) override;
-  void Flush() override;
-  void Finish() override;
-  void ShallowFlushCHROMIUM() override;
-  void Enable(GLenum cap) override;
-  void Disable(GLenum cap) override;
-
-  void BindBuffer(GLenum target, GLuint buffer) override;
-  void BindRenderbuffer(GLenum target, GLuint buffer) override;
-  void BindFramebuffer(GLenum target, GLuint buffer) override;
-
-  void PixelStorei(GLenum pname, GLint param) override;
-
-  void TexImage2D(GLenum target,
-                  GLint level,
-                  GLint internalformat,
-                  GLsizei width,
-                  GLsizei height,
-                  GLint border,
-                  GLenum format,
-                  GLenum type,
-                  const void* pixels) override;
-  void TexSubImage2D(GLenum target,
-                     GLint level,
-                     GLint xoffset,
-                     GLint yoffset,
-                     GLsizei width,
-                     GLsizei height,
-                     GLenum format,
-                     GLenum type,
-                     const void* pixels) override;
-  void TexStorage2DEXT(GLenum target,
-                       GLsizei levels,
-                       GLenum internalformat,
-                       GLsizei width,
-                       GLsizei height) override;
-  void TexImageIOSurface2DCHROMIUM(GLenum target,
-                                   GLsizei width,
-                                   GLsizei height,
-                                   GLuint io_surface_id,
-                                   GLuint plane) override;
-  void TexParameteri(GLenum target, GLenum pname, GLint param) override;
-
-  void AsyncTexImage2DCHROMIUM(GLenum target,
-                               GLint level,
-                               GLenum internalformat,
-                               GLsizei width,
-                               GLsizei height,
-                               GLint border,
-                               GLenum format,
-                               GLenum type,
-                               const void* pixels) override;
-  void AsyncTexSubImage2DCHROMIUM(GLenum target,
-                                  GLint level,
-                                  GLint xoffset,
-                                  GLint yoffset,
-                                  GLsizei width,
-                                  GLsizei height,
-                                  GLenum format,
-                                  GLenum type,
-                                  const void* pixels) override;
-  void CompressedTexImage2D(GLenum target,
-                            GLint level,
-                            GLenum internalformat,
-                            GLsizei width,
-                            GLsizei height,
-                            GLint border,
-                            GLsizei image_size,
-                            const void* data) override;
-  void WaitAsyncTexImage2DCHROMIUM(GLenum target) override;
-  GLuint CreateImageCHROMIUM(ClientBuffer buffer,
-                             GLsizei width,
-                             GLsizei height,
-                             GLenum internalformat) override;
-  void DestroyImageCHROMIUM(GLuint image_id) override;
-  GLuint CreateGpuMemoryBufferImageCHROMIUM(GLsizei width,
-                                            GLsizei height,
-                                            GLenum internalformat,
-                                            GLenum usage) override;
-  void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) override;
-  void ReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id) override;
-  void FramebufferRenderbuffer(GLenum target,
-                               GLenum attachment,
-                               GLenum renderbuffertarget,
-                               GLuint renderbuffer) override;
-  void FramebufferTexture2D(GLenum target,
-                            GLenum attachment,
-                            GLenum textarget,
-                            GLuint texture,
-                            GLint level) override;
-  void RenderbufferStorage(GLenum target,
-                           GLenum internalformat,
-                           GLsizei width,
-                           GLsizei height) override;
-
-  void* MapBufferCHROMIUM(GLuint target, GLenum access) override;
-  GLboolean UnmapBufferCHROMIUM(GLuint target) override;
-  void BufferData(GLenum target,
-                  GLsizeiptr size,
-                  const void* data,
-                  GLenum usage) override;
-
-  void WaitSyncPointCHROMIUM(GLuint sync_point) override;
-  GLuint InsertSyncPointCHROMIUM() override;
-
-  void BeginQueryEXT(GLenum target, GLuint id) override;
-  void EndQueryEXT(GLenum target) override;
-  void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) override;
-
-  void DiscardFramebufferEXT(GLenum target,
-                             GLsizei count,
-                             const GLenum* attachments) override;
-  void GenMailboxCHROMIUM(GLbyte* mailbox) override;
-  void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
-  void ProduceTextureDirectCHROMIUM(GLuint texture,
-                                    GLenum target,
-                                    const GLbyte* mailbox) override;
-  void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) override;
-  GLuint CreateAndConsumeTextureCHROMIUM(GLenum target,
-                                         const GLbyte* mailbox) override;
-
-  void ResizeCHROMIUM(GLuint width, GLuint height, float device_scale) override;
-  void LoseContextCHROMIUM(GLenum current, GLenum other) override;
-
- private:
-  TestWebGraphicsContext3D* test_context_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_GLES2_INTERFACE_H_
diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc
deleted file mode 100644
index b43cd76..0000000
--- a/cc/test/test_gpu_memory_buffer_manager.cc
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/test_gpu_memory_buffer_manager.h"
-
-#include "base/logging.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace cc {
-namespace {
-
-size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
-  switch (format) {
-    case gfx::GpuMemoryBuffer::ATCIA:
-    case gfx::GpuMemoryBuffer::DXT5:
-      return width;
-    case gfx::GpuMemoryBuffer::ATC:
-    case gfx::GpuMemoryBuffer::DXT1:
-    case gfx::GpuMemoryBuffer::ETC1:
-      DCHECK_EQ(width % 2, 0U);
-      return width / 2;
-    case gfx::GpuMemoryBuffer::RGBA_8888:
-    case gfx::GpuMemoryBuffer::RGBX_8888:
-    case gfx::GpuMemoryBuffer::BGRA_8888:
-      return width * 4;
-  }
-
-  NOTREACHED();
-  return 0;
-}
-
-class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer {
- public:
-  GpuMemoryBufferImpl(const gfx::Size& size,
-                      Format format,
-                      scoped_ptr<base::SharedMemory> shared_memory)
-      : size_(size),
-        format_(format),
-        shared_memory_(shared_memory.Pass()),
-        mapped_(false) {}
-
-  // Overridden from gfx::GpuMemoryBuffer:
-  bool Map(void** data) override {
-    DCHECK(!mapped_);
-    if (!shared_memory_->Map(StrideInBytes(size_.width(), format_) *
-                             size_.height()))
-      return false;
-    mapped_ = true;
-    *data = shared_memory_->memory();
-    return true;
-  }
-  void Unmap() override {
-    DCHECK(mapped_);
-    shared_memory_->Unmap();
-    mapped_ = false;
-  }
-  bool IsMapped() const override { return mapped_; }
-  Format GetFormat() const override { return format_; }
-  void GetStride(uint32* stride) const override {
-    *stride = StrideInBytes(size_.width(), format_);
-  }
-  gfx::GpuMemoryBufferHandle GetHandle() const override {
-    gfx::GpuMemoryBufferHandle handle;
-    handle.type = gfx::SHARED_MEMORY_BUFFER;
-    handle.handle = shared_memory_->handle();
-    return handle;
-  }
-  ClientBuffer AsClientBuffer() override {
-    return reinterpret_cast<ClientBuffer>(this);
-  }
-
- private:
-  const gfx::Size size_;
-  gfx::GpuMemoryBuffer::Format format_;
-  scoped_ptr<base::SharedMemory> shared_memory_;
-  bool mapped_;
-};
-
-}  // namespace
-
-TestGpuMemoryBufferManager::TestGpuMemoryBufferManager() {
-}
-
-TestGpuMemoryBufferManager::~TestGpuMemoryBufferManager() {
-}
-
-scoped_ptr<gfx::GpuMemoryBuffer>
-TestGpuMemoryBufferManager::AllocateGpuMemoryBuffer(
-    const gfx::Size& size,
-    gfx::GpuMemoryBuffer::Format format,
-    gfx::GpuMemoryBuffer::Usage usage) {
-  scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
-  if (!shared_memory->CreateAnonymous(StrideInBytes(size.width(), format) *
-                                      size.height()))
-    return nullptr;
-  return make_scoped_ptr<gfx::GpuMemoryBuffer>(
-      new GpuMemoryBufferImpl(size, format, shared_memory.Pass()));
-}
-
-gfx::GpuMemoryBuffer*
-TestGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
-    ClientBuffer buffer) {
-  return reinterpret_cast<gfx::GpuMemoryBuffer*>(buffer);
-}
-
-void TestGpuMemoryBufferManager::SetDestructionSyncPoint(
-    gfx::GpuMemoryBuffer* buffer,
-    uint32 sync_point) {
-}
-
-}  // namespace cc
diff --git a/cc/test/test_gpu_memory_buffer_manager.h b/cc/test/test_gpu_memory_buffer_manager.h
deleted file mode 100644
index d084436..0000000
--- a/cc/test/test_gpu_memory_buffer_manager.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_TEST_GPU_MEMORY_BUFFER_MANAGER_H_
-#define CC_TEST_TEST_GPU_MEMORY_BUFFER_MANAGER_H_
-
-#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h"
-
-namespace cc {
-
-class TestGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager {
- public:
-  TestGpuMemoryBufferManager();
-  ~TestGpuMemoryBufferManager() override;
-
-  // Overridden from gpu::GpuMemoryBufferManager:
-  scoped_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer(
-      const gfx::Size& size,
-      gfx::GpuMemoryBuffer::Format format,
-      gfx::GpuMemoryBuffer::Usage usage) override;
-  gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer(
-      ClientBuffer buffer) override;
-  void SetDestructionSyncPoint(gfx::GpuMemoryBuffer* buffer,
-                               uint32 sync_point) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestGpuMemoryBufferManager);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_GPU_MEMORY_BUFFER_MANAGER_H_
diff --git a/cc/test/test_image_factory.cc b/cc/test/test_image_factory.cc
deleted file mode 100644
index 42e3502..0000000
--- a/cc/test/test_image_factory.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/test_image_factory.h"
-
-#include "ui/gl/gl_image_shared_memory.h"
-
-namespace cc {
-
-TestImageFactory::TestImageFactory() {
-}
-
-TestImageFactory::~TestImageFactory() {
-}
-
-scoped_refptr<gfx::GLImage> TestImageFactory::CreateImageForGpuMemoryBuffer(
-    const gfx::GpuMemoryBufferHandle& handle,
-    const gfx::Size& size,
-    gfx::GpuMemoryBuffer::Format format,
-    unsigned internalformat,
-    int client_id) {
-  DCHECK_EQ(handle.type, gfx::SHARED_MEMORY_BUFFER);
-
-  scoped_refptr<gfx::GLImageSharedMemory> image(
-      new gfx::GLImageSharedMemory(size, internalformat));
-  if (!image->Initialize(handle, format))
-    return nullptr;
-
-  return image;
-}
-
-}  // namespace cc
diff --git a/cc/test/test_image_factory.h b/cc/test/test_image_factory.h
deleted file mode 100644
index fcef390..0000000
--- a/cc/test/test_image_factory.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_TEST_IMAGE_FACTORY_H_
-#define CC_TEST_TEST_IMAGE_FACTORY_H_
-
-#include "gpu/command_buffer/service/image_factory.h"
-
-namespace cc {
-
-class TestImageFactory : public gpu::ImageFactory {
- public:
-  TestImageFactory();
-  ~TestImageFactory() override;
-
-  // Overridden from gpu::ImageFactory:
-  scoped_refptr<gfx::GLImage> CreateImageForGpuMemoryBuffer(
-      const gfx::GpuMemoryBufferHandle& handle,
-      const gfx::Size& size,
-      gfx::GpuMemoryBuffer::Format format,
-      unsigned internalformat,
-      int client_id) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestImageFactory);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_IMAGE_FACTORY_H_
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc
deleted file mode 100644
index 3539bd2..0000000
--- a/cc/test/test_in_process_context_provider.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_in_process_context_provider.h"
-
-#include "base/lazy_instance.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "gpu/command_buffer/client/gl_in_process_context.h"
-#include "gpu/command_buffer/client/gles2_implementation.h"
-#include "gpu/command_buffer/client/gles2_lib.h"
-#include "gpu/command_buffer/common/gles2_cmd_utils.h"
-#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-#include "third_party/skia/include/gpu/GrContext.h"
-#include "third_party/skia/include/gpu/gl/GrGLInterface.h"
-#include "ui/gfx/native_widget_types.h"
-
-namespace cc {
-
-// static
-scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext(
-    TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
-    TestImageFactory* image_factory) {
-  const bool is_offscreen = true;
-  const bool share_resources = true;
-  gpu::gles2::ContextCreationAttribHelper attribs;
-  attribs.alpha_size = 8;
-  attribs.blue_size = 8;
-  attribs.green_size = 8;
-  attribs.red_size = 8;
-  attribs.depth_size = 24;
-  attribs.stencil_size = 8;
-  attribs.samples = 0;
-  attribs.sample_buffers = 0;
-  attribs.fail_if_major_perf_caveat = false;
-  attribs.bind_generates_resource = false;
-  gfx::GpuPreference gpu_preference = gfx::PreferDiscreteGpu;
-
-  scoped_ptr<gpu::GLInProcessContext> context =
-      make_scoped_ptr(gpu::GLInProcessContext::Create(
-          NULL,
-          NULL,
-          is_offscreen,
-          gfx::kNullAcceleratedWidget,
-          gfx::Size(1, 1),
-          NULL,
-          share_resources,
-          attribs,
-          gpu_preference,
-          gpu::GLInProcessContextSharedMemoryLimits(),
-          gpu_memory_buffer_manager,
-          image_factory));
-
-  DCHECK(context);
-  return context.Pass();
-}
-
-scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext() {
-  return CreateTestInProcessContext(nullptr, nullptr);
-}
-
-TestInProcessContextProvider::TestInProcessContextProvider()
-    : context_(CreateTestInProcessContext(&gpu_memory_buffer_manager_,
-                                          &image_factory_)) {
-}
-
-TestInProcessContextProvider::~TestInProcessContextProvider() {
-}
-
-bool TestInProcessContextProvider::BindToCurrentThread() { return true; }
-
-gpu::gles2::GLES2Interface* TestInProcessContextProvider::ContextGL() {
-  return context_->GetImplementation();
-}
-
-gpu::ContextSupport* TestInProcessContextProvider::ContextSupport() {
-  return context_->GetImplementation();
-}
-
-namespace {
-
-// Singleton used to initialize and terminate the gles2 library.
-class GLES2Initializer {
- public:
-  GLES2Initializer() { ::gles2::Initialize(); }
-
-  ~GLES2Initializer() { ::gles2::Terminate(); }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GLES2Initializer);
-};
-
-static base::LazyInstance<GLES2Initializer> g_gles2_initializer =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-static void BindGrContextCallback(const GrGLInterface* interface) {
-  TestInProcessContextProvider* context_provider =
-      reinterpret_cast<TestInProcessContextProvider*>(interface->fCallbackData);
-
-  gles2::SetGLContext(context_provider->ContextGL());
-}
-
-class GrContext* TestInProcessContextProvider::GrContext() {
-  if (gr_context_)
-    return gr_context_.get();
-
-  // The GrGLInterface factory will make GL calls using the C GLES2 interface.
-  // Make sure the gles2 library is initialized first on exactly one thread.
-  g_gles2_initializer.Get();
-  gles2::SetGLContext(ContextGL());
-
-  skia::RefPtr<GrGLInterface> interface =
-      skia::AdoptRef(skia_bindings::CreateCommandBufferSkiaGLBinding());
-  interface->fCallback = BindGrContextCallback;
-  interface->fCallbackData = reinterpret_cast<GrGLInterfaceCallbackData>(this);
-
-  gr_context_ = skia::AdoptRef(GrContext::Create(
-      kOpenGL_GrBackend, reinterpret_cast<GrBackendContext>(interface.get())));
-
-  return gr_context_.get();
-}
-
-void TestInProcessContextProvider::SetupLock() {
-}
-
-base::Lock* TestInProcessContextProvider::GetLock() {
-  return &context_lock_;
-}
-
-ContextProvider::Capabilities
-TestInProcessContextProvider::ContextCapabilities() {
-  ContextProvider::Capabilities capabilities;
-  capabilities.gpu.image = true;
-  capabilities.gpu.texture_rectangle = true;
-
-  return capabilities;
-}
-
-bool TestInProcessContextProvider::IsContextLost() { return false; }
-
-void TestInProcessContextProvider::VerifyContexts() {}
-
-void TestInProcessContextProvider::DeleteCachedResources() {
-  if (gr_context_)
-    gr_context_->freeGpuResources();
-}
-
-bool TestInProcessContextProvider::DestroyedOnMainThread() { return false; }
-
-void TestInProcessContextProvider::SetLostContextCallback(
-    const LostContextCallback& lost_context_callback) {}
-
-void TestInProcessContextProvider::SetMemoryPolicyChangedCallback(
-    const MemoryPolicyChangedCallback& memory_policy_changed_callback) {}
-
-}  // namespace cc
diff --git a/cc/test/test_in_process_context_provider.h b/cc/test/test_in_process_context_provider.h
deleted file mode 100644
index 9fa77b7..0000000
--- a/cc/test/test_in_process_context_provider.h
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_IN_PROCESS_CONTEXT_PROVIDER_H_
-#define CC_TEST_TEST_IN_PROCESS_CONTEXT_PROVIDER_H_
-
-#include "base/synchronization/lock.h"
-#include "cc/output/context_provider.h"
-#include "cc/test/test_gpu_memory_buffer_manager.h"
-#include "cc/test/test_image_factory.h"
-#include "skia/ext/refptr.h"
-
-class GrContext;
-
-namespace gpu {
-class GLInProcessContext;
-}
-
-namespace cc {
-
-scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext();
-scoped_ptr<gpu::GLInProcessContext> CreateTestInProcessContext(
-    TestGpuMemoryBufferManager* gpu_memory_buffer_manager,
-    TestImageFactory* image_factory);
-
-class TestInProcessContextProvider : public ContextProvider {
- public:
-  TestInProcessContextProvider();
-
-  bool BindToCurrentThread() override;
-  gpu::gles2::GLES2Interface* ContextGL() override;
-  gpu::ContextSupport* ContextSupport() override;
-  class GrContext* GrContext() override;
-  void SetupLock() override;
-  base::Lock* GetLock() override;
-  Capabilities ContextCapabilities() override;
-  bool IsContextLost() override;
-  void VerifyContexts() override;
-  void DeleteCachedResources() override;
-  bool DestroyedOnMainThread() override;
-  void SetLostContextCallback(
-      const LostContextCallback& lost_context_callback) override;
-  void SetMemoryPolicyChangedCallback(
-      const MemoryPolicyChangedCallback& memory_policy_changed_callback)
-      override;
-
- protected:
-  friend class base::RefCountedThreadSafe<TestInProcessContextProvider>;
-  ~TestInProcessContextProvider() override;
-
- private:
-  TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
-  TestImageFactory image_factory_;
-  scoped_ptr<gpu::GLInProcessContext> context_;
-  skia::RefPtr<class GrContext> gr_context_;
-  base::Lock context_lock_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_IN_PROCESS_CONTEXT_PROVIDER_H_
diff --git a/cc/test/test_now_source.cc b/cc/test/test_now_source.cc
deleted file mode 100644
index e1a633f..0000000
--- a/cc/test/test_now_source.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2014 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.
-
-#include <limits>
-#include <string>
-
-#include "cc/test/test_now_source.h"
-
-namespace cc {
-
-// TestNowSource::Constructors
-scoped_refptr<TestNowSource> TestNowSource::Create() {
-  return make_scoped_refptr(new TestNowSource());
-}
-
-scoped_refptr<TestNowSource> TestNowSource::Create(base::TimeTicks initial) {
-  return make_scoped_refptr(new TestNowSource(initial));
-}
-
-scoped_refptr<TestNowSource> TestNowSource::Create(int64_t initial) {
-  return make_scoped_refptr(new TestNowSource(initial));
-}
-
-TestNowSource::TestNowSource()
-    : initial_(base::TimeTicks::FromInternalValue(10000)),
-      now_(),
-      num_now_calls_(0) {
-  Reset();
-}
-
-TestNowSource::TestNowSource(base::TimeTicks initial)
-    : initial_(initial), now_(), num_now_calls_(0) {
-  Reset();
-}
-
-TestNowSource::TestNowSource(int64_t initial)
-    : initial_(base::TimeTicks::FromInternalValue(initial)),
-      now_(),
-      num_now_calls_(0) {
-  Reset();
-}
-
-TestNowSource::~TestNowSource() {
-}
-
-// TestNowSource actual functionality
-void TestNowSource::Reset() {
-  TRACE_EVENT_INSTANT2("cc",
-                       "TestNowSource::Reset",
-                       TRACE_EVENT_SCOPE_THREAD,
-                       "previous",
-                       now_,
-                       "initial",
-                       initial_);
-  now_ = initial_;
-}
-
-base::TimeTicks TestNowSource::Now() const {
-  num_now_calls_++;
-  return now_;
-}
-
-void TestNowSource::SetNow(base::TimeTicks time) {
-  TRACE_EVENT_INSTANT2("cc",
-                       "TestNowSource::SetNow",
-                       TRACE_EVENT_SCOPE_THREAD,
-                       "previous",
-                       now_,
-                       "new",
-                       time);
-  DCHECK(time >= now_);  // Time should always go forward.
-  now_ = time;
-}
-
-void TestNowSource::AdvanceNow(base::TimeDelta period) {
-  TRACE_EVENT_INSTANT2("cc",
-                       "TestNowSource::AdvanceNow",
-                       TRACE_EVENT_SCOPE_THREAD,
-                       "previous",
-                       now_,
-                       "by",
-                       period.ToInternalValue());
-  DCHECK(now_ != kAbsoluteMaxNow);
-  DCHECK(period >= base::TimeDelta());  // Time should always go forward.
-  now_ += period;
-}
-
-const base::TimeTicks TestNowSource::kAbsoluteMaxNow =
-    base::TimeTicks::FromInternalValue(std::numeric_limits<int64_t>::max());
-
-// TestNowSource::Convenience functions
-void TestNowSource::AdvanceNowMicroseconds(int64_t period_in_microseconds) {
-  AdvanceNow(base::TimeDelta::FromMicroseconds(period_in_microseconds));
-}
-void TestNowSource::SetNowMicroseconds(int64_t time_in_microseconds) {
-  SetNow(base::TimeTicks::FromInternalValue(time_in_microseconds));
-}
-
-// TestNowSource::Tracing functions
-void TestNowSource::AsValueInto(base::trace_event::TracedValue* state) const {
-  state->SetInteger("now_in_microseconds", now_.ToInternalValue());
-}
-
-scoped_refptr<base::trace_event::ConvertableToTraceFormat>
-TestNowSource::AsValue() const {
-  scoped_refptr<base::trace_event::TracedValue> state =
-      new base::trace_event::TracedValue();
-  AsValueInto(state.get());
-  return state;
-}
-
-// TestNowSource::Pretty printing functions
-std::string TestNowSource::ToString() const {
-  std::string output("TestNowSource(");
-  AsValue()->AppendAsTraceFormat(&output);
-  output += ")";
-  return output;
-}
-
-::std::ostream& operator<<(::std::ostream& os,
-                           const scoped_refptr<TestNowSource>& src) {
-  os << src->ToString();
-  return os;
-}
-void PrintTo(const scoped_refptr<TestNowSource>& src, ::std::ostream* os) {
-  *os << src;
-}
-
-}  // namespace cc
diff --git a/cc/test/test_now_source.h b/cc/test/test_now_source.h
deleted file mode 100644
index 9b46bbe..0000000
--- a/cc/test/test_now_source.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_TEST_NOW_SOURCE_H_
-#define CC_TEST_TEST_NOW_SOURCE_H_
-
-#include <string>
-
-#include "base/basictypes.h"
-#include "base/logging.h"
-#include "base/trace_event/trace_event.h"
-#include "base/trace_event/trace_event_argument.h"
-
-namespace cc {
-
-class TestNowSource : public base::RefCounted<TestNowSource> {
- public:
-  static scoped_refptr<TestNowSource> Create();
-  static scoped_refptr<TestNowSource> Create(int64_t initial);
-  static scoped_refptr<TestNowSource> Create(base::TimeTicks initial);
-
-  virtual void Reset();
-  virtual base::TimeTicks Now() const;
-  virtual void SetNow(base::TimeTicks time);
-  virtual void AdvanceNow(base::TimeDelta period);
-
-  // Convenience functions to make it the now source easier to use in unit
-  // tests.
-  void AdvanceNowMicroseconds(int64_t period_in_microseconds);
-  void SetNowMicroseconds(int64_t time_in_microseconds);
-
-  static const base::TimeTicks kAbsoluteMaxNow;
-
-  // Tracing functions
-  scoped_refptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-  void AsValueInto(base::trace_event::TracedValue* state) const;
-  std::string ToString() const;
-
-  int NumNowCalls() const { return num_now_calls_; }
-
- protected:
-  TestNowSource();
-  explicit TestNowSource(int64_t initial);
-  explicit TestNowSource(base::TimeTicks initial);
-
-  base::TimeTicks initial_;
-  base::TimeTicks now_;
-  mutable int num_now_calls_;
-
- private:
-  friend class base::RefCounted<TestNowSource>;
-  virtual ~TestNowSource();
-};
-
-// gtest pretty printing functions
-void PrintTo(const scoped_refptr<TestNowSource>& src, ::std::ostream* os);
-::std::ostream& operator<<(::std::ostream& os,
-                           const scoped_refptr<TestNowSource>& src);
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_NOW_SOURCE_H_
diff --git a/cc/test/test_occlusion_tracker.h b/cc/test/test_occlusion_tracker.h
deleted file mode 100644
index ca8a664..0000000
--- a/cc/test/test_occlusion_tracker.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_TEST_OCCLUSION_TRACKER_H_
-#define CC_TEST_TEST_OCCLUSION_TRACKER_H_
-
-#include "cc/layers/render_surface.h"
-#include "cc/layers/render_surface_impl.h"
-#include "cc/trees/occlusion_tracker.h"
-
-namespace cc {
-
-// A subclass to expose the total current occlusion.
-template <typename LayerType>
-class TestOcclusionTracker : public OcclusionTracker<LayerType> {
- public:
-  explicit TestOcclusionTracker(const gfx::Rect& screen_scissor_rect)
-      : OcclusionTracker<LayerType>(screen_scissor_rect) {}
-
-  SimpleEnclosedRegion occlusion_from_inside_target() const {
-    return OcclusionTracker<LayerType>::stack_.back()
-        .occlusion_from_inside_target;
-  }
-  SimpleEnclosedRegion occlusion_from_outside_target() const {
-    return OcclusionTracker<LayerType>::stack_.back()
-        .occlusion_from_outside_target;
-  }
-
-  SimpleEnclosedRegion occlusion_on_contributing_surface_from_inside_target()
-      const {
-    size_t stack_size = OcclusionTracker<LayerType>::stack_.size();
-    if (stack_size < 2)
-      return SimpleEnclosedRegion();
-    return OcclusionTracker<LayerType>::stack_[stack_size - 2]
-        .occlusion_from_inside_target;
-  }
-  SimpleEnclosedRegion occlusion_on_contributing_surface_from_outside_target()
-      const {
-    size_t stack_size = OcclusionTracker<LayerType>::stack_.size();
-    if (stack_size < 2)
-      return SimpleEnclosedRegion();
-    return OcclusionTracker<LayerType>::stack_[stack_size - 2]
-        .occlusion_from_outside_target;
-  }
-
-  void set_occlusion_from_outside_target(const SimpleEnclosedRegion& region) {
-    OcclusionTracker<LayerType>::stack_.back().occlusion_from_outside_target =
-        region;
-  }
-  void set_occlusion_from_inside_target(const SimpleEnclosedRegion& region) {
-    OcclusionTracker<LayerType>::stack_.back().occlusion_from_inside_target =
-        region;
-  }
-
-  void set_occlusion_on_contributing_surface_from_outside_target(
-      const SimpleEnclosedRegion& region) {
-    size_t stack_size = OcclusionTracker<LayerType>::stack_.size();
-    DCHECK_GE(stack_size, 2u);
-    OcclusionTracker<LayerType>::stack_[stack_size - 2]
-        .occlusion_from_outside_target = region;
-  }
-  void set_occlusion_on_contributing_surface_from_inside_target(
-      const SimpleEnclosedRegion& region) {
-    size_t stack_size = OcclusionTracker<LayerType>::stack_.size();
-    DCHECK_GE(stack_size, 2u);
-    OcclusionTracker<LayerType>::stack_[stack_size - 2]
-        .occlusion_from_inside_target = region;
-  }
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_OCCLUSION_TRACKER_H_
diff --git a/cc/test/test_shared_bitmap_manager.cc b/cc/test/test_shared_bitmap_manager.cc
deleted file mode 100644
index 7e14b2f..0000000
--- a/cc/test/test_shared_bitmap_manager.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 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.
-
-#include "cc/test/test_shared_bitmap_manager.h"
-
-#include "base/memory/shared_memory.h"
-
-namespace cc {
-
-namespace {
-class OwnedSharedBitmap : public SharedBitmap {
- public:
-  OwnedSharedBitmap(scoped_ptr<base::SharedMemory> shared_memory,
-                    const SharedBitmapId& id)
-      : SharedBitmap(static_cast<uint8*>(shared_memory->memory()), id),
-        shared_memory_(shared_memory.Pass()) {}
-
-  ~OwnedSharedBitmap() override {}
-
- private:
-  scoped_ptr<base::SharedMemory> shared_memory_;
-};
-
-}  // namespace
-
-TestSharedBitmapManager::TestSharedBitmapManager() {}
-
-TestSharedBitmapManager::~TestSharedBitmapManager() {}
-
-scoped_ptr<SharedBitmap> TestSharedBitmapManager::AllocateSharedBitmap(
-    const gfx::Size& size) {
-  base::AutoLock lock(lock_);
-  scoped_ptr<base::SharedMemory> memory(new base::SharedMemory);
-  memory->CreateAndMapAnonymous(size.GetArea() * 4);
-  SharedBitmapId id = SharedBitmap::GenerateId();
-  bitmap_map_[id] = memory.get();
-  return make_scoped_ptr(new OwnedSharedBitmap(memory.Pass(), id));
-}
-
-scoped_ptr<SharedBitmap> TestSharedBitmapManager::GetSharedBitmapFromId(
-    const gfx::Size&,
-    const SharedBitmapId& id) {
-  base::AutoLock lock(lock_);
-  if (bitmap_map_.find(id) == bitmap_map_.end())
-    return nullptr;
-  uint8* pixels = static_cast<uint8*>(bitmap_map_[id]->memory());
-  return make_scoped_ptr(new SharedBitmap(pixels, id));
-}
-
-}  // namespace cc
diff --git a/cc/test/test_shared_bitmap_manager.h b/cc/test/test_shared_bitmap_manager.h
deleted file mode 100644
index acba096..0000000
--- a/cc/test/test_shared_bitmap_manager.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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.
-
-#ifndef CC_TEST_TEST_SHARED_BITMAP_MANAGER_H_
-#define CC_TEST_TEST_SHARED_BITMAP_MANAGER_H_
-
-#include <map>
-
-#include "base/synchronization/lock.h"
-#include "cc/resources/shared_bitmap_manager.h"
-
-namespace base {
-class SharedMemory;
-}  // namespace base
-
-namespace cc {
-
-class TestSharedBitmapManager : public SharedBitmapManager {
- public:
-  TestSharedBitmapManager();
-  ~TestSharedBitmapManager() override;
-
-  scoped_ptr<SharedBitmap> AllocateSharedBitmap(const gfx::Size& size) override;
-
-  scoped_ptr<SharedBitmap> GetSharedBitmapFromId(
-      const gfx::Size&,
-      const SharedBitmapId& id) override;
-
- private:
-  base::Lock lock_;
-  std::map<SharedBitmapId, base::SharedMemory*> bitmap_map_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_SHARED_BITMAP_MANAGER_H_
diff --git a/cc/test/test_task_graph_runner.cc b/cc/test/test_task_graph_runner.cc
deleted file mode 100644
index fe9734e..0000000
--- a/cc/test/test_task_graph_runner.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// 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.
-
-#include "cc/test/test_task_graph_runner.h"
-
-namespace cc {
-
-TestTaskGraphRunner::TestTaskGraphRunner()
-    : worker_thread_(this, "CompositorWorker") {
-  worker_thread_.Start();
-}
-
-TestTaskGraphRunner::~TestTaskGraphRunner() {
-  TaskGraphRunner::Shutdown();
-  worker_thread_.Join();
-}
-
-void TestTaskGraphRunner::Run() {
-  TaskGraphRunner::Run();
-}
-
-}  // namespace cc
diff --git a/cc/test/test_task_graph_runner.h b/cc/test/test_task_graph_runner.h
deleted file mode 100644
index 8314e11..0000000
--- a/cc/test/test_task_graph_runner.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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.
-
-#ifndef CC_TEST_TEST_TASK_GRAPH_RUNNER_H_
-#define CC_TEST_TEST_TASK_GRAPH_RUNNER_H_
-
-#include "base/threading/simple_thread.h"
-#include "cc/resources/task_graph_runner.h"
-
-namespace cc {
-
-class TestTaskGraphRunner : public TaskGraphRunner,
-                            public base::DelegateSimpleThread::Delegate {
- public:
-  TestTaskGraphRunner();
-  ~TestTaskGraphRunner() override;
-
-  // Overridden from base::DelegateSimpleThread::Delegate:
-  void Run() override;
-
- private:
-  base::DelegateSimpleThread worker_thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestTaskGraphRunner);
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_TASK_GRAPH_RUNNER_H_
diff --git a/cc/test/test_texture.cc b/cc/test/test_texture.cc
deleted file mode 100644
index 8addc79..0000000
--- a/cc/test/test_texture.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_texture.h"
-
-#include "gpu/GLES2/gl2extchromium.h"
-#include "third_party/khronos/GLES2/gl2ext.h"
-
-namespace cc {
-
-size_t TextureSizeBytes(const gfx::Size& size, ResourceFormat format) {
-  unsigned int components_per_pixel = 4;
-  unsigned int bytes_per_component = 1;
-  return size.width() * size.height() * components_per_pixel *
-         bytes_per_component;
-}
-
-TestTexture::TestTexture() : format(RGBA_8888) {
-  // Initialize default parameter values.
-  params[GL_TEXTURE_MAG_FILTER] = GL_LINEAR;
-  params[GL_TEXTURE_MIN_FILTER] = GL_NEAREST_MIPMAP_LINEAR;
-  params[GL_TEXTURE_WRAP_S] = GL_REPEAT;
-  params[GL_TEXTURE_WRAP_T] = GL_REPEAT;
-  params[GL_TEXTURE_POOL_CHROMIUM] = GL_TEXTURE_POOL_UNMANAGED_CHROMIUM;
-  params[GL_TEXTURE_USAGE_ANGLE] = GL_NONE;
-}
-
-TestTexture::~TestTexture() {}
-
-void TestTexture::Reallocate(const gfx::Size& size, ResourceFormat format) {
-  this->size = size;
-  this->format = format;
-  this->data.reset(new uint8_t[TextureSizeBytes(size, format)]);
-}
-
-bool TestTexture::IsValidParameter(GLenum pname) {
-  return params.find(pname) != params.end();
-}
-
-}  // namespace cc
diff --git a/cc/test/test_texture.h b/cc/test/test_texture.h
deleted file mode 100644
index 9265589..0000000
--- a/cc/test/test_texture.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_TEXTURE_H_
-#define CC_TEST_TEST_TEXTURE_H_
-
-#include "base/containers/hash_tables.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_ptr.h"
-#include "cc/resources/resource_format.h"
-#include "third_party/khronos/GLES2/gl2.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-size_t TextureSizeBytes(const gfx::Size& size, ResourceFormat format);
-
-struct TestTexture : public base::RefCounted<TestTexture> {
-  TestTexture();
-
-  void Reallocate(const gfx::Size& size, ResourceFormat format);
-  bool IsValidParameter(GLenum pname);
-
-  gfx::Size size;
-  ResourceFormat format;
-  scoped_ptr<uint8_t[]> data;
-
-  typedef base::hash_map<GLenum, GLint>
-      TextureParametersMap;
-  TextureParametersMap params;
-
- private:
-  friend class base::RefCounted<TestTexture>;
-  ~TestTexture();
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_TEXTURE_H_
diff --git a/cc/test/test_tile_priorities.cc b/cc/test/test_tile_priorities.cc
deleted file mode 100644
index 2748e6c..0000000
--- a/cc/test/test_tile_priorities.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2013 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.
-
-#include "cc/test/test_tile_priorities.h"
-
-namespace cc {
-
-TilePriorityForSoonBin::TilePriorityForSoonBin()
-    : TilePriority(HIGH_RESOLUTION, SOON, 300.0) {}
-
-TilePriorityForEventualBin::TilePriorityForEventualBin()
-    : TilePriority(HIGH_RESOLUTION, EVENTUALLY, 315.0) {}
-
-TilePriorityForNowBin::TilePriorityForNowBin()
-    : TilePriority(HIGH_RESOLUTION, NOW, 0) {}
-
-TilePriorityLowRes::TilePriorityLowRes()
-    : TilePriority(LOW_RESOLUTION, NOW, 0) {}
-
-}  // namespace cc
diff --git a/cc/test/test_tile_priorities.h b/cc/test/test_tile_priorities.h
deleted file mode 100644
index 60738e4..0000000
--- a/cc/test/test_tile_priorities.h
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef CC_TEST_TEST_TILE_PRIORITIES_H_
-#define CC_TEST_TEST_TILE_PRIORITIES_H_
-
-#include "cc/resources/tile_priority.h"
-
-namespace cc {
-
-class TilePriorityForSoonBin : public TilePriority {
- public:
-  TilePriorityForSoonBin();
-};
-
-class TilePriorityForEventualBin : public TilePriority {
- public:
-  TilePriorityForEventualBin();
-};
-
-class TilePriorityForNowBin : public TilePriority {
- public:
-  TilePriorityForNowBin();
-};
-
-class TilePriorityLowRes : public TilePriority {
- public:
-  TilePriorityLowRes();
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_TILE_PRIORITIES_H_
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index 89ef514..3fc4a96 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -453,9 +453,9 @@
     sources += [ "ext/platform_device_linux.cc" ]
     set_sources_assignment_filter(sources_assignment_filter)
     deps += [
+      "//third_party/android_tools:cpu_features",
       "//third_party/expat",
       "//third_party/freetype-android:freetype",
-      "//third_party/android_tools:cpu_features",
     ]
   }
 
@@ -544,7 +544,6 @@
     ":skia",
     "//base",
     "//base/test:run_all_unittests",
-    "//cc:test_support",  # TODO: Fix this test to not depend on cc.
     "//testing/gtest",
     "//ui/gfx",
     "//ui/gfx/geometry",
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index fcb16da..5fd8455 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -27,15 +27,15 @@
     "//base",
     "//skia",
     "//ui/events",
-    "//ui/events/platform",
     "//ui/events:events_base",
+    "//ui/events/platform",
     "//ui/gfx",
     "//ui/gfx/geometry",
   ]
   deps = [
-    "//base/third_party/dynamic_annotations",
     "//base:base_static",
     "//base:i18n",
+    "//base/third_party/dynamic_annotations",
     "//third_party/icu",
     "//url",
   ]
@@ -52,10 +52,7 @@
   }
 
   if (is_android) {
-    deps += [
-      ":ui_base_jni_headers",
-      "//cc",
-    ]
+    deps += [ ":ui_base_jni_headers" ]
 
     libs += [ "jnigraphics" ]
   }
