diff --git a/BUILD.gn b/BUILD.gn
index 2892e385c..48b7396 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -481,6 +481,7 @@
   if (is_chromeos) {
     deps += [
       "//chromeos:chromeos_unittests",
+      "//chromeos/components:chromeos_components_unittests",
       "//components/session_manager/core",
       "//ui/arc:ui_arc_unittests",
       "//ui/chromeos:ui_chromeos_unittests",
diff --git a/DEPS b/DEPS
index 5bf01f6..bf34581 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '6e549d18dc7be260986cc9e8de7eb7d20a32bce0',
+  'v8_revision': 'cd7151a28dd271f7ebca6a668df1438c5f556829',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': 'ca719be61d3204f1d4b7e4ed1f8130b840d5cc96',
+  'catapult_revision': '627b0d9726b50a0cbd92ddb741d31ba5c184a2e5',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -188,7 +188,7 @@
     Var('chromium_git') + '/external/bidichecker/lib.git' + '@' + '97f2aa645b74c28c57eca56992235c79850fa9e0',
 
   'src/third_party/webgl/src':
-    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '4b93f826500ab7ddb341ae182e6ecbde331ab93e',
+    Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '3e235f7e8495092ac4ad11eec8f226c7accc9a33',
 
   'src/third_party/webdriver/pylib':
     Var('chromium_git') + '/external/selenium/py.git' + '@' + '5fd78261a75fe08d27ca4835fb6c5ce4b42275bd',
diff --git a/ash/common/accelerators/debug_commands.cc b/ash/common/accelerators/debug_commands.cc
index fc5270b..b3ea038 100644
--- a/ash/common/accelerators/debug_commands.cc
+++ b/ash/common/accelerators/debug_commands.cc
@@ -128,7 +128,11 @@
 
 void HandleToggleTouchscreen() {
   base::RecordAction(base::UserMetricsAction("Accel_Toggle_Touchscreen"));
-  ash::WmShell::Get()->delegate()->ToggleTouchscreen();
+  ShellDelegate* delegate = WmShell::Get()->delegate();
+  delegate->SetTouchscreenEnabledInPrefs(
+      !delegate->IsTouchscreenEnabledInPrefs(false /* use_local_state */),
+      false /* use_local_state */);
+  delegate->UpdateTouchscreenStatusFromPrefs();
 }
 
 void HandleToggleTouchView() {
diff --git a/ash/common/shell_delegate.h b/ash/common/shell_delegate.h
index 27d59cf..d95f49ac 100644
--- a/ash/common/shell_delegate.h
+++ b/ash/common/shell_delegate.h
@@ -133,9 +133,21 @@
 
   virtual gfx::Image GetDeprecatedAcceleratorImage() const = 0;
 
-  // Toggles the status of the touchpad / touchscreen on or off.
+  // If |use_local_state| is true, returns the touchscreen status from local
+  // state, otherwise from user prefs.
+  virtual bool IsTouchscreenEnabledInPrefs(bool use_local_state) const = 0;
+
+  // Sets the status of touchscreen to |enabled| in prefs. If |use_local_state|,
+  // pref is set in local state, otherwise in user prefs.
+  virtual void SetTouchscreenEnabledInPrefs(bool enabled,
+                                            bool use_local_state) = 0;
+
+  // Updates the enabled/disabled status of the touchscreen from prefs. Enabled
+  // if both local state and user prefs are enabled, otherwise disabled.
+  virtual void UpdateTouchscreenStatusFromPrefs() = 0;
+
+  // Toggles the status of touchpad between enabled and disabled.
   virtual void ToggleTouchpad() {}
-  virtual void ToggleTouchscreen() {}
 };
 
 }  // namespace ash
diff --git a/ash/mus/shell_delegate_mus.cc b/ash/mus/shell_delegate_mus.cc
index 3e2dc1c6..054100e 100644
--- a/ash/mus/shell_delegate_mus.cc
+++ b/ash/mus/shell_delegate_mus.cc
@@ -231,4 +231,18 @@
   return gfx::Image();
 }
 
+bool ShellDelegateMus::IsTouchscreenEnabledInPrefs(bool use_local_state) const {
+  NOTIMPLEMENTED();
+  return true;
+}
+
+void ShellDelegateMus::SetTouchscreenEnabledInPrefs(bool enabled,
+                                                    bool use_local_state) {
+  NOTIMPLEMENTED();
+}
+
+void ShellDelegateMus::UpdateTouchscreenStatusFromPrefs() {
+  NOTIMPLEMENTED();
+}
+
 }  // namespace ash
diff --git a/ash/mus/shell_delegate_mus.h b/ash/mus/shell_delegate_mus.h
index dd88827..81e6701 100644
--- a/ash/mus/shell_delegate_mus.h
+++ b/ash/mus/shell_delegate_mus.h
@@ -47,6 +47,10 @@
   GPUSupport* CreateGPUSupport() override;
   base::string16 GetProductName() const override;
   gfx::Image GetDeprecatedAcceleratorImage() const override;
+  bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override;
+  void SetTouchscreenEnabledInPrefs(bool enabled,
+                                    bool use_local_state) override;
+  void UpdateTouchscreenStatusFromPrefs() override;
 
  private:
   service_manager::Connector* connector_;
diff --git a/ash/shell/shell_delegate_impl.cc b/ash/shell/shell_delegate_impl.cc
index 76e340fa..b9c7c01 100644
--- a/ash/shell/shell_delegate_impl.cc
+++ b/ash/shell/shell_delegate_impl.cc
@@ -265,5 +265,15 @@
   return gfx::Image();
 }
 
+bool ShellDelegateImpl::IsTouchscreenEnabledInPrefs(
+    bool use_local_state) const {
+  return true;
+}
+
+void ShellDelegateImpl::SetTouchscreenEnabledInPrefs(bool enabled,
+                                                     bool use_local_state) {}
+
+void ShellDelegateImpl::UpdateTouchscreenStatusFromPrefs() {}
+
 }  // namespace shell
 }  // namespace ash
diff --git a/ash/shell/shell_delegate_impl.h b/ash/shell/shell_delegate_impl.h
index 073d366..590da66 100644
--- a/ash/shell/shell_delegate_impl.h
+++ b/ash/shell/shell_delegate_impl.h
@@ -53,6 +53,10 @@
   GPUSupport* CreateGPUSupport() override;
   base::string16 GetProductName() const override;
   gfx::Image GetDeprecatedAcceleratorImage() const override;
+  bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override;
+  void SetTouchscreenEnabledInPrefs(bool enabled,
+                                    bool use_local_state) override;
+  void UpdateTouchscreenStatusFromPrefs() override;
 
  private:
   ShelfDelegate* shelf_delegate_;
diff --git a/ash/system/chromeos/power/tablet_power_button_controller.cc b/ash/system/chromeos/power/tablet_power_button_controller.cc
index bd52b98..66841d16 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller.cc
@@ -6,6 +6,7 @@
 
 #include "ash/common/accessibility_delegate.h"
 #include "ash/common/session/session_state_delegate.h"
+#include "ash/common/shell_delegate.h"
 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h"
 #include "ash/common/wm_shell.h"
 #include "ash/shell.h"
@@ -96,24 +97,27 @@
   // backlight has been turned back on before seeing the power button events
   // that woke the system. Ignore events just after resuming to ensure that we
   // don't turn the screen off in response to the events.
+  //
+  // TODO(warx): pressing power button should also StartShutdownTimer() in this
+  // case. Reorganize the code to support that.
   if (timestamp - last_resume_time_ <=
       base::TimeDelta::FromMilliseconds(kIgnorePowerButtonAfterResumeMs)) {
     // If backlights are forced off, stop forcing off because resuming system
     // doesn't handle this.
     if (down && backlights_forced_off_)
-      SetBacklightsForcedOff(false);
+      SetDisplayForcedOff(false);
     return;
   }
 
   if (down) {
     screen_off_when_power_button_down_ = brightness_level_is_zero_;
-    SetBacklightsForcedOff(false);
+    SetDisplayForcedOff(false);
     StartShutdownTimer();
   } else {
     if (shutdown_timer_.IsRunning()) {
       shutdown_timer_.Stop();
       if (!screen_off_when_power_button_down_) {
-        SetBacklightsForcedOff(true);
+        SetDisplayForcedOff(true);
         LockScreenIfRequired();
       }
     }
@@ -149,7 +153,7 @@
     return;
 
   if (!IsTabletModeActive() && backlights_forced_off_)
-    SetBacklightsForcedOff(false);
+    SetDisplayForcedOff(false);
 }
 
 void TabletPowerButtonController::OnMouseEvent(ui::MouseEvent* event) {
@@ -161,13 +165,13 @@
   }
 
   if (!IsTabletModeActive() && backlights_forced_off_)
-    SetBacklightsForcedOff(false);
+    SetDisplayForcedOff(false);
 }
 
 void TabletPowerButtonController::OnStylusStateChanged(ui::StylusState state) {
   if (IsTabletModeSupported() && state == ui::StylusState::REMOVED &&
       backlights_forced_off_) {
-    SetBacklightsForcedOff(false);
+    SetDisplayForcedOff(false);
   }
 }
 
@@ -177,15 +181,21 @@
   tick_clock_ = std::move(tick_clock);
 }
 
-void TabletPowerButtonController::SetBacklightsForcedOff(bool forced_off) {
+void TabletPowerButtonController::SetDisplayForcedOff(bool forced_off) {
   if (backlights_forced_off_ == forced_off)
     return;
 
+  // Set the display and keyboard backlights (if present) to |forced_off|.
   chromeos::DBusThreadManager::Get()
       ->GetPowerManagerClient()
       ->SetBacklightsForcedOff(forced_off);
   backlights_forced_off_ = forced_off;
 
+  ShellDelegate* delegate = WmShell::Get()->delegate();
+  delegate->SetTouchscreenEnabledInPrefs(!forced_off,
+                                         true /* use_local_state */);
+  delegate->UpdateTouchscreenStatusFromPrefs();
+
   // Send an a11y alert.
   WmShell::Get()->accessibility_delegate()->TriggerAccessibilityAlert(
       forced_off ? A11Y_ALERT_SCREEN_OFF : A11Y_ALERT_SCREEN_ON);
diff --git a/ash/system/chromeos/power/tablet_power_button_controller.h b/ash/system/chromeos/power/tablet_power_button_controller.h
index 66a5b61d..f59749d 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller.h
+++ b/ash/system/chromeos/power/tablet_power_button_controller.h
@@ -72,8 +72,10 @@
   void SetTickClockForTesting(std::unique_ptr<base::TickClock> tick_clock);
 
  private:
-  // Set backlights to |forced_off| if they aren't already.
-  void SetBacklightsForcedOff(bool forced_off);
+  // Updates the power manager's backlights-forced-off state and enables or
+  // disables the touchscreen. No-op if |backlights_forced_off_| already equals
+  // |forced_off|.
+  void SetDisplayForcedOff(bool forced_off);
 
   // Sends a request to powerd to get the backlights forced off state so that
   // |backlights_forced_off_| can be initialized.
diff --git a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
index 4633032a5..a27af600 100644
--- a/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
+++ b/ash/system/chromeos/power/tablet_power_button_controller_unittest.cc
@@ -13,6 +13,7 @@
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/lock_state_controller_test_api.h"
+#include "ash/test/test_shell_delegate.h"
 #include "ash/wm/lock_state_controller.h"
 #include "ash/wm/power_button_controller.h"
 #include "base/command_line.h"
@@ -64,6 +65,8 @@
     tick_clock_ = new base::SimpleTestTickClock;
     tablet_controller_->SetTickClockForTesting(
         std::unique_ptr<base::TickClock>(tick_clock_));
+    shell_delegate_ =
+        static_cast<TestShellDelegate*>(WmShell::Get()->delegate());
     generator_ = &AshTestBase::GetEventGenerator();
     power_manager_client_->SendBrightnessChanged(kNonZeroBrightness, false);
     EXPECT_FALSE(GetBacklightsForcedOff());
@@ -119,6 +122,7 @@
   TabletPowerButtonController* tablet_controller_;  // Not owned.
   std::unique_ptr<TabletPowerButtonController::TestApi> test_api_;
   base::SimpleTestTickClock* tick_clock_;  // Not owned.
+  TestShellDelegate* shell_delegate_;      // Not owned.
   ui::test::EventGenerator* generator_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(TabletPowerButtonControllerTest);
@@ -356,5 +360,43 @@
   EXPECT_EQ(1, power_manager_client_->num_set_backlights_forced_off_calls());
 }
 
+// Tests that under (1) tablet power button pressed/released, (2) keyboard/mouse
+// events on laptop mode when screen is off, requesting/stopping backlights
+// forced off should also set corresponding touch screen state in local pref.
+TEST_F(TabletPowerButtonControllerTest, TouchScreenState) {
+  // Tests tablet power button.
+  EXPECT_TRUE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+  PressPowerButton();
+  ReleasePowerButton();
+  power_manager_client_->SendBrightnessChanged(0, false);
+  EXPECT_FALSE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+
+  PressPowerButton();
+  power_manager_client_->SendBrightnessChanged(kNonZeroBrightness, false);
+  ReleasePowerButton();
+  EXPECT_TRUE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+
+  EnableMaximizeMode(false);
+  // KeyEvent on laptop mode when screen is off.
+  PressPowerButton();
+  ReleasePowerButton();
+  power_manager_client_->SendBrightnessChanged(0, false);
+  EXPECT_TRUE(GetBacklightsForcedOff());
+  EXPECT_FALSE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+  generator_->PressKey(ui::VKEY_L, ui::EF_NONE);
+  power_manager_client_->SendBrightnessChanged(kNonZeroBrightness, false);
+  EXPECT_TRUE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+
+  // MouseEvent on laptop mode when screen is off.
+  PressPowerButton();
+  ReleasePowerButton();
+  power_manager_client_->SendBrightnessChanged(0, false);
+  EXPECT_TRUE(GetBacklightsForcedOff());
+  EXPECT_FALSE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+  generator_->MoveMouseBy(1, 1);
+  power_manager_client_->SendBrightnessChanged(kNonZeroBrightness, false);
+  EXPECT_TRUE(shell_delegate_->IsTouchscreenEnabledInPrefs(true));
+}
+
 }  // namespace test
 }  // namespace ash
diff --git a/ash/test/test_shell_delegate.cc b/ash/test/test_shell_delegate.cc
index 8e2fcea..d91c644 100644
--- a/ash/test/test_shell_delegate.cc
+++ b/ash/test/test_shell_delegate.cc
@@ -86,6 +86,7 @@
     : num_exit_requests_(0),
       multi_profiles_enabled_(false),
       force_maximize_on_first_run_(false),
+      touchscreen_enabled_in_local_pref_(true),
       app_list_presenter_delegate_factory_(new AppListPresenterDelegateFactory(
           base::WrapUnique(new AppListViewDelegateFactoryImpl))) {}
 
@@ -184,6 +185,19 @@
   return gfx::Image();
 }
 
+bool TestShellDelegate::IsTouchscreenEnabledInPrefs(
+    bool use_local_state) const {
+  return use_local_state ? touchscreen_enabled_in_local_pref_ : true;
+}
+
+void TestShellDelegate::SetTouchscreenEnabledInPrefs(bool enabled,
+                                                     bool use_local_state) {
+  if (use_local_state)
+    touchscreen_enabled_in_local_pref_ = enabled;
+}
+
+void TestShellDelegate::UpdateTouchscreenStatusFromPrefs() {}
+
 void TestShellDelegate::SetMediaCaptureState(MediaCaptureState state) {
 #if defined(OS_CHROMEOS)
   static_cast<MediaDelegateImpl*>(WmShell::Get()->media_delegate())
diff --git a/ash/test/test_shell_delegate.h b/ash/test/test_shell_delegate.h
index 143fa14..b3aee0c5 100644
--- a/ash/test/test_shell_delegate.h
+++ b/ash/test/test_shell_delegate.h
@@ -60,6 +60,11 @@
   base::string16 GetProductName() const override;
   gfx::Image GetDeprecatedAcceleratorImage() const override;
 
+  bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override;
+  void SetTouchscreenEnabledInPrefs(bool enabled,
+                                    bool use_local_state) override;
+  void UpdateTouchscreenStatusFromPrefs() override;
+
   int num_exit_requests() const { return num_exit_requests_; }
 
   app_list::AppListPresenterImpl* app_list_presenter() {
@@ -75,6 +80,7 @@
   int num_exit_requests_;
   bool multi_profiles_enabled_;
   bool force_maximize_on_first_run_;
+  bool touchscreen_enabled_in_local_pref_;
 
   std::unique_ptr<app_list::AppListPresenterDelegateFactory>
       app_list_presenter_delegate_factory_;
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc
index 0095ac96a..f1c118d 100644
--- a/cc/layers/video_layer_impl.cc
+++ b/cc/layers/video_layer_impl.cc
@@ -191,10 +191,15 @@
 
   // Pixels for macroblocked formats. To prevent sampling outside the visible
   // rect, stretch the video if needed.
+  gfx::Rect visible_sample_rect = frame_->visible_rect();
+  if (visible_rect.width() < coded_size.width() && visible_rect.width() > 1)
+    visible_sample_rect.set_width(visible_rect.width() - 1);
+  if (visible_rect.height() < coded_size.height() && visible_rect.height() > 1)
+    visible_sample_rect.set_height(visible_rect.height() - 1);
   const float tex_width_scale =
-      static_cast<float>(visible_rect.width()) / coded_size.width();
+      static_cast<float>(visible_sample_rect.width()) / coded_size.width();
   const float tex_height_scale =
-      static_cast<float>(visible_rect.height()) / coded_size.height();
+      static_cast<float>(visible_sample_rect.height()) / coded_size.height();
 
   switch (frame_resource_type_) {
     // TODO(danakj): Remove this, hide it in the hardware path.
@@ -260,12 +265,12 @@
           static_cast<float>(ya_tex_size.width()) / uv_tex_size.width();
       float uv_subsampling_factor_y =
           static_cast<float>(ya_tex_size.height()) / uv_tex_size.height();
-      gfx::RectF ya_tex_coord_rect(visible_rect);
+      gfx::RectF ya_tex_coord_rect(visible_sample_rect);
       gfx::RectF uv_tex_coord_rect(
-          visible_rect.x() / uv_subsampling_factor_x,
-          visible_rect.y() / uv_subsampling_factor_y,
-          visible_rect.width() / uv_subsampling_factor_x,
-          visible_rect.height() / uv_subsampling_factor_y);
+          visible_sample_rect.x() / uv_subsampling_factor_x,
+          visible_sample_rect.y() / uv_subsampling_factor_y,
+          visible_sample_rect.width() / uv_subsampling_factor_x,
+          visible_sample_rect.height() / uv_subsampling_factor_y);
 
       YUVVideoDrawQuad* yuv_video_quad =
           render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index e441c9b5..002f32c 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -81,20 +81,6 @@
   return xform;
 }
 
-Float4 UVClampRect(gfx::RectF uv_clamp_rect,
-                   const gfx::Size& texture_size,
-                   SamplerType sampler) {
-  gfx::SizeF half_texel(0.5f, 0.5f);
-  if (sampler != SAMPLER_TYPE_2D_RECT) {
-    half_texel.Scale(1.f / texture_size.width(), 1.f / texture_size.height());
-  } else {
-    uv_clamp_rect.Scale(texture_size.width(), texture_size.height());
-  }
-  uv_clamp_rect.Inset(half_texel.width(), half_texel.height());
-  return {{uv_clamp_rect.x(), uv_clamp_rect.y(), uv_clamp_rect.right(),
-           uv_clamp_rect.bottom()}};
-}
-
 Float4 PremultipliedColor(SkColor color) {
   const float factor = 1.0f / 255.0f;
   const float alpha = SkColorGetA(color) * factor;
@@ -2497,15 +2483,8 @@
 
   gl_->Uniform1i(program->fragment_shader().sampler_location(), 0);
 
-  gfx::Size texture_size = lock.size();
-  gfx::Vector2dF uv = quad->matrix.Scale2d();
-  gfx::RectF uv_clamp_rect(0, 0, uv.x(), uv.y());
-  const SamplerType sampler = SamplerTypeFromTextureTarget(lock.target());
-  Float4 tex_clamp_rect = UVClampRect(uv_clamp_rect, texture_size, sampler);
-  gl_->Uniform4f(program->fragment_shader().tex_clamp_rect_location(),
-                 tex_clamp_rect.data[0], tex_clamp_rect.data[1],
-                 tex_clamp_rect.data[2], tex_clamp_rect.data[3]);
-
+  SetShaderOpacity(quad->shared_quad_state->opacity,
+                   program->fragment_shader().alpha_location());
   if (!clip_region) {
     DrawQuadGeometry(frame->projection_matrix,
                      quad->shared_quad_state->quad_to_target_transform,
@@ -2548,12 +2527,9 @@
     tex_transform_location = program->vertex_shader().tex_transform_location();
     vertex_opacity_location =
         program->vertex_shader().vertex_opacity_location();
-    tex_clamp_rect_location =
-        program->fragment_shader().tex_clamp_rect_location();
   }
   int tex_transform_location;
   int vertex_opacity_location;
-  int tex_clamp_rect_location;
 };
 
 void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
@@ -2594,13 +2570,6 @@
                   static_cast<int>(draw_cache_.uv_xform_data.size()),
                   reinterpret_cast<float*>(&draw_cache_.uv_xform_data.front()));
 
-  if (draw_cache_.tex_clamp_rect_location != -1) {
-    gl_->Uniform4fv(
-        draw_cache_.tex_clamp_rect_location,
-        static_cast<int>(draw_cache_.tex_clamp_rect_data.size()),
-        reinterpret_cast<float*>(&draw_cache_.tex_clamp_rect_data.front()));
-  }
-
   if (draw_cache_.background_color != SK_ColorTRANSPARENT) {
     Float4 background_color = PremultipliedColor(draw_cache_.background_color);
     gl_->Uniform4fv(draw_cache_.background_color_location, 1,
@@ -2644,7 +2613,6 @@
   // Clear the cache.
   draw_cache_.program_id = -1;
   draw_cache_.uv_xform_data.resize(0);
-  draw_cache_.tex_clamp_rect_data.resize(0);
   draw_cache_.vertex_opacity_data.resize(0);
   draw_cache_.matrix_data.resize(0);
 
@@ -2709,7 +2677,6 @@
     draw_cache_.background_color = quad->background_color;
 
     draw_cache_.uv_xform_location = binding.tex_transform_location;
-    draw_cache_.tex_clamp_rect_location = binding.tex_clamp_rect_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;
@@ -2730,23 +2697,6 @@
   }
   draw_cache_.uv_xform_data.push_back(uv_transform);
 
-  if (draw_cache_.tex_clamp_rect_location != -1) {
-    // VideoLayerImpl always set background color to transparent.
-    DCHECK(quad->background_color == SK_ColorTRANSPARENT);
-    gfx::Size texture_size = lock.size();
-    if (texture_size.IsEmpty()) {
-      // TODO(dshwang): correct all code coming to here. crbug.com/615325
-      texture_size = quad->rect.size();
-    }
-    gfx::RectF uv_clamp_rect(quad->uv_top_left.x(), quad->uv_top_left.y(),
-                             quad->uv_bottom_right.x() - quad->uv_top_left.x(),
-                             quad->uv_bottom_right.y() - quad->uv_top_left.y());
-    Float4 tex_clamp_rect = UVClampRect(uv_clamp_rect, texture_size, sampler);
-    draw_cache_.tex_clamp_rect_data.push_back(tex_clamp_rect);
-    DCHECK_EQ(draw_cache_.uv_xform_data.size(),
-              draw_cache_.tex_clamp_rect_data.size());
-  }
-
   // Generate the vertex opacity
   const float opacity = quad->shared_quad_state->opacity;
   draw_cache_.vertex_opacity_data.push_back(quad->vertex_opacity[0] * opacity);
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 73ba62de..8aa00d2 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -304,10 +304,9 @@
 
   // Texture shaders.
   typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexClampVaryingAlpha>
-      TextureProgram;
+                         FragmentShaderRGBATexVaryingAlpha> TextureProgram;
   typedef ProgramBinding<VertexShaderPosTexTransform,
-                         FragmentShaderRGBATexClampPremultiplyAlpha>
+                         FragmentShaderRGBATexPremultiplyAlpha>
       NonPremultipliedTextureProgram;
   typedef ProgramBinding<VertexShaderPosTexTransform,
                          FragmentShaderTexBackgroundVaryingAlpha>
@@ -340,7 +339,7 @@
       RenderPassMaskColorMatrixProgram;
 
   // Video shaders.
-  typedef ProgramBinding<VertexShaderVideoTransform, FragmentShaderRGBATexClamp>
+  typedef ProgramBinding<VertexShaderVideoTransform, FragmentShaderRGBATex>
       VideoStreamTextureProgram;
   typedef ProgramBinding<VertexShaderPosTexYUVStretchOffset,
                          FragmentShaderYUVVideo> VideoYUVProgram;
diff --git a/cc/output/gl_renderer_draw_cache.h b/cc/output/gl_renderer_draw_cache.h
index b083ff0..e02b73b 100644
--- a/cc/output/gl_renderer_draw_cache.h
+++ b/cc/output/gl_renderer_draw_cache.h
@@ -38,7 +38,6 @@
 
   // Information about the program binding that is required to draw.
   int uv_xform_location;
-  int tex_clamp_rect_location = -1;
   int background_color_location;
   int vertex_opacity_location;
   int matrix_location;
@@ -46,7 +45,6 @@
 
   // A cache for the coalesced quad data.
   std::vector<Float4> uv_xform_data;
-  std::vector<Float4> tex_clamp_rect_data;
   std::vector<float> vertex_opacity_data;
   std::vector<Float16> matrix_data;
 
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index e485a1b..ffd204a9 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -7,7 +7,6 @@
 #include <memory>
 
 #include "base/message_loop/message_loop.h"
-#include "base/strings/string_split.h"
 #include "cc/base/math_util.h"
 #include "cc/output/gl_renderer.h"
 #include "cc/quads/draw_quad.h"
@@ -17,7 +16,6 @@
 #include "cc/test/fake_raster_source.h"
 #include "cc/test/fake_recording_source.h"
 #include "cc/test/pixel_test.h"
-#include "cc/test/test_in_process_context_provider.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "media/base/video_frame.h"
 #include "third_party/skia/include/core/SkColorPriv.h"
@@ -219,85 +217,72 @@
                video_frame->rows(media::VideoFrame::kAPlane));
   }
 
-  VideoFrameExternalResources external_resources =
+  VideoFrameExternalResources resources =
       video_resource_updater->CreateExternalResourcesFromVideoFrame(
           video_frame);
 
-  ResourceProvider::ResourceIdArray resource_ids;
-  resource_ids.reserve(external_resources.mailboxes.size());
-  for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) {
-    ResourceId resource_id =
-        resource_provider->CreateResourceFromTextureMailbox(
-            external_resources.mailboxes[i],
-            SingleReleaseCallbackImpl::Create(
-                external_resources.release_callbacks[i]),
-            external_resources.read_lock_fences_enabled);
-    resource_ids.push_back(resource_id);
+  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());
+
+  ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox(
+      resources.mailboxes[media::VideoFrame::kYPlane],
+      SingleReleaseCallbackImpl::Create(
+          resources.release_callbacks[media::VideoFrame::kYPlane]));
+  ResourceId u_resource = resource_provider->CreateResourceFromTextureMailbox(
+      resources.mailboxes[media::VideoFrame::kUPlane],
+      SingleReleaseCallbackImpl::Create(
+          resources.release_callbacks[media::VideoFrame::kUPlane]));
+  ResourceId v_resource = resource_provider->CreateResourceFromTextureMailbox(
+      resources.mailboxes[media::VideoFrame::kVPlane],
+      SingleReleaseCallbackImpl::Create(
+          resources.release_callbacks[media::VideoFrame::kVPlane]));
+  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]));
   }
 
-  switch (external_resources.type) {
-    case VideoFrameExternalResources::YUV_RESOURCE: {
-      EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
-                external_resources.mailboxes.size());
-      EXPECT_EQ(media::VideoFrame::NumPlanes(video_frame->format()),
-                external_resources.release_callbacks.size());
-      const gfx::Size ya_tex_size = video_frame->coded_size();
-      const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
-          video_frame->format(), media::VideoFrame::kUPlane,
-          video_frame->coded_size());
-      DCHECK(uv_tex_size ==
-             media::VideoFrame::PlaneSize(video_frame->format(),
-                                          media::VideoFrame::kVPlane,
-                                          video_frame->coded_size()));
-      if (with_alpha) {
-        DCHECK(ya_tex_size ==
-               media::VideoFrame::PlaneSize(video_frame->format(),
-                                            media::VideoFrame::kAPlane,
-                                            video_frame->coded_size()));
-      }
-      gfx::RectF ya_tex_coord_rect(
-          tex_coord_rect.x() * ya_tex_size.width(),
-          tex_coord_rect.y() * ya_tex_size.height(),
-          tex_coord_rect.width() * ya_tex_size.width(),
-          tex_coord_rect.height() * ya_tex_size.height());
-      gfx::RectF uv_tex_coord_rect(
-          tex_coord_rect.x() * uv_tex_size.width(),
-          tex_coord_rect.y() * uv_tex_size.height(),
-          tex_coord_rect.width() * uv_tex_size.width(),
-          tex_coord_rect.height() * uv_tex_size.height());
-
-      YUVVideoDrawQuad* yuv_quad =
-          render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
-      yuv_quad->SetNew(
-          shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect,
-          uv_tex_coord_rect, ya_tex_size, uv_tex_size, resource_ids[0],
-          resource_ids[1],
-          resource_ids.size() > 2 ? resource_ids[2] : resource_ids[1],
-          resource_ids.size() > 3 ? resource_ids[3] : 0, color_space,
-          video_color_space, external_resources.offset,
-          external_resources.multiplier, external_resources.bits_per_channel);
-      break;
-    }
-    case VideoFrameExternalResources::RGBA_RESOURCE: {
-      EXPECT_EQ(1u, external_resources.mailboxes.size());
-      EXPECT_EQ(1u, external_resources.release_callbacks.size());
-      float opacity[] = {1.0f, 1.0f, 1.0f, 1.0f};
-      TextureDrawQuad* texture_quad =
-          render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-      texture_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
-                           resource_ids[0], false, tex_coord_rect.origin(),
-                           tex_coord_rect.bottom_right(), SK_ColorTRANSPARENT,
-                           opacity, false, false, false);
-      break;
-    }
-    case VideoFrameExternalResources::NONE:
-    case VideoFrameExternalResources::RGB_RESOURCE:
-    case VideoFrameExternalResources::RGBA_PREMULTIPLIED_RESOURCE:
-    case VideoFrameExternalResources::STREAM_TEXTURE_RESOURCE:
-    case VideoFrameExternalResources::SOFTWARE_RESOURCE:
-      NOTREACHED();
-      break;
+  const gfx::Size ya_tex_size = video_frame->coded_size();
+  const gfx::Size uv_tex_size = media::VideoFrame::PlaneSize(
+      video_frame->format(), media::VideoFrame::kUPlane,
+      video_frame->coded_size());
+  DCHECK(uv_tex_size == media::VideoFrame::PlaneSize(
+                            video_frame->format(), media::VideoFrame::kVPlane,
+                            video_frame->coded_size()));
+  if (with_alpha) {
+    DCHECK(ya_tex_size == media::VideoFrame::PlaneSize(
+                              video_frame->format(), media::VideoFrame::kAPlane,
+                              video_frame->coded_size()));
   }
+
+  gfx::RectF ya_tex_coord_rect(tex_coord_rect.x() * ya_tex_size.width(),
+                               tex_coord_rect.y() * ya_tex_size.height(),
+                               tex_coord_rect.width() * ya_tex_size.width(),
+                               tex_coord_rect.height() * ya_tex_size.height());
+  gfx::RectF uv_tex_coord_rect(tex_coord_rect.x() * uv_tex_size.width(),
+                               tex_coord_rect.y() * uv_tex_size.height(),
+                               tex_coord_rect.width() * uv_tex_size.width(),
+                               tex_coord_rect.height() * uv_tex_size.height());
+
+  YUVVideoDrawQuad* yuv_quad =
+      render_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>();
+  uint32_t bits_per_channel = 8;
+  if (video_frame->format() == media::PIXEL_FORMAT_YUV420P10 ||
+      video_frame->format() == media::PIXEL_FORMAT_YUV422P10 ||
+      video_frame->format() == media::PIXEL_FORMAT_YUV444P10) {
+    bits_per_channel = 10;
+  }
+
+  yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect,
+                   ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size,
+                   uv_tex_size, y_resource, u_resource, v_resource, a_resource,
+                   color_space, video_color_space, 0.0f, 1.0f,
+                   bits_per_channel);
 }
 
 void CreateTestY16TextureDrawQuad_FromVideoFrame(
@@ -324,7 +309,7 @@
   TextureDrawQuad* quad =
       render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
   float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-  quad->SetNew(shared_state, rect, gfx::Rect(), visible_rect, y_resource, false,
+  quad->SetNew(shared_state, rect, gfx::Rect(), rect, y_resource, false,
                tex_coord_rect.origin(), tex_coord_rect.bottom_right(),
                SK_ColorBLACK, vertex_opacity, false, false, false);
 }
@@ -387,8 +372,6 @@
     ResourceProvider* resource_provider) {
   scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame(
       format, rect.size(), rect, rect.size(), base::TimeDelta());
-  video_frame->metadata()->SetInteger(media::VideoFrameMetadata::COLOR_SPACE,
-                                      media::COLOR_SPACE_JPEG);
 
   // YUV values representing a striped pattern, for validating texture
   // coordinates for sampling.
@@ -532,7 +515,6 @@
 void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state,
                                      media::ColorSpace video_frame_color_space,
                                      const gfx::ColorSpace& video_color_space,
-                                     ResourceFormat y_format,
                                      const gfx::RectF& tex_coord_rect,
                                      uint8_t y,
                                      uint8_t u,
@@ -552,8 +534,8 @@
       media::PIXEL_FORMAT_NV12, media::VideoFrame::kUVPlane, rect.size());
 
   ResourceId y_resource = resource_provider->CreateResource(
-      rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, y_format,
-      gfx::ColorSpace());
+      rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT,
+      resource_provider->YuvResourceFormat(8), gfx::ColorSpace());
   ResourceId u_resource = resource_provider->CreateResource(
       uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888,
       gfx::ColorSpace());
@@ -1213,71 +1195,12 @@
         output_surface_->context_provider(), resource_provider_.get()));
   }
 
-  void DisableOneComponentTextures() {
-    TestInProcessContextProvider* context_provider =
-        GetTestInProcessContextProvider();
-    context_provider->SetDisableOneComponentTextures(true);
-  }
-
   std::unique_ptr<VideoResourceUpdater> video_resource_updater_;
-
- protected:
-  TestInProcessContextProvider* GetTestInProcessContextProvider() {
-    return static_cast<TestInProcessContextProvider*>(
-        output_surface_->context_provider());
-  }
-};
-
-enum class HighbitTexture {
-  Y8,
-  RGBA_8888,
-  LUMINANCE_F16,  // need --use-gpu-in-tests
 };
 
 class VideoGLRendererPixelHiLoTest
     : public VideoGLRendererPixelTest,
-      public ::testing::WithParamInterface<
-          ::testing::tuple<bool, HighbitTexture>> {
- public:
-  void SetSupportHighbitTexture(HighbitTexture texture) {
-    TestInProcessContextProvider* context_provider =
-        GetTestInProcessContextProvider();
-    switch (texture) {
-      case HighbitTexture::Y8:
-        context_provider->SetDisableOneComponentTextures(false);
-        context_provider->SetSupportTextureHalfFloatLinear(false);
-        break;
-      case HighbitTexture::RGBA_8888:
-        context_provider->SetDisableOneComponentTextures(true);
-        context_provider->SetSupportTextureHalfFloatLinear(false);
-        break;
-      case HighbitTexture::LUMINANCE_F16:
-        context_provider->SetDisableOneComponentTextures(false);
-        context_provider->SetSupportTextureHalfFloatLinear(true);
-        break;
-    }
-  }
-
-  bool IsHalfFloatLinearSupported() {
-    if (extensions_.empty())
-      InitializeExtensions();
-
-    return extensions_.find("GL_OES_texture_half_float_linear") !=
-           extensions_.end();
-  }
-
- private:
-  void InitializeExtensions() {
-    std::string extensions = GetTestInProcessContextProvider()
-                                 ->ContextGL()
-                                 ->GetRequestableExtensionsCHROMIUM();
-    std::vector<std::string> tokens = base::SplitString(
-        extensions, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
-    extensions_.insert(tokens.begin(), tokens.end());
-  }
-
-  std::set<std::string> extensions_;
-};
+      public ::testing::WithParamInterface<bool> {};
 
 TEST_P(VideoGLRendererPixelHiLoTest, SimpleYUVRect) {
   gfx::Rect rect(this->device_viewport_size_);
@@ -1288,12 +1211,7 @@
   SharedQuadState* shared_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
 
-  const bool highbit = testing::get<0>(GetParam());
-  const HighbitTexture format = testing::get<1>(GetParam());
-  if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
-    return;
-
-  SetSupportHighbitTexture(format);
+  bool highbit = GetParam();
   CreateTestYUVVideoDrawQuad_Striped(
       shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
@@ -1302,19 +1220,10 @@
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
 
-  base::FilePath file_path =
-      base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png"));
-  // TODO(dshwang): investigate why results per configuraion are so different.
-  // crbug.com/622133
-  if (format == HighbitTexture::RGBA_8888) {
-    // Color space is so different, because this path doesn't respect video
-    // color profile.
-    file_path = base::FilePath(FILE_PATH_LITERAL("yuv_stripes_rgba.png"));
-  }
-  EXPECT_TRUE(this->RunPixelTest(
-      &pass_list, file_path,
-      // All pixels can be off by two, but any more than that is an error.
-      FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
+  EXPECT_TRUE(
+      this->RunPixelTest(&pass_list,
+                         base::FilePath(FILE_PATH_LITERAL("yuv_stripes.png")),
+                         FuzzyPixelOffByOneComparator(true)));
 }
 
 TEST_P(VideoGLRendererPixelHiLoTest, ClippedYUVRect) {
@@ -1328,12 +1237,7 @@
   SharedQuadState* shared_state =
       CreateTestSharedQuadState(gfx::Transform(), viewport, pass.get());
 
-  const bool highbit = testing::get<0>(GetParam());
-  const HighbitTexture format = testing::get<1>(GetParam());
-  if (format == HighbitTexture::LUMINANCE_F16 && !IsHalfFloatLinearSupported())
-    return;
-
-  SetSupportHighbitTexture(format);
+  bool highbit = GetParam();
   CreateTestYUVVideoDrawQuad_Striped(
       shared_state, media::PIXEL_FORMAT_YV12, false, highbit,
       gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), pass.get(),
@@ -1342,16 +1246,9 @@
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
 
-  base::FilePath file_path =
-      base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png"));
-  if (format == HighbitTexture::RGBA_8888) {
-    file_path =
-        base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped_rgba.png"));
-  }
   EXPECT_TRUE(this->RunPixelTest(
-      &pass_list, file_path,
-      // All pixels can be off by two, but any more than that is an error.
-      FuzzyPixelComparator(true, 100.f, 0.f, 2.f, 2, 0)));
+      &pass_list, base::FilePath(FILE_PATH_LITERAL("yuv_stripes_clipped.png")),
+      FuzzyPixelOffByOneComparator(true)));
 }
 
 TEST_F(VideoGLRendererPixelHiLoTest, OffsetYUVRect) {
@@ -1403,13 +1300,7 @@
 }
 
 // First argument (test case prefix) is intentionally left empty.
-INSTANTIATE_TEST_CASE_P(
-    ,
-    VideoGLRendererPixelHiLoTest,
-    ::testing::Combine(::testing::Bool(),
-                       ::testing::Values(HighbitTexture::Y8,
-                                         HighbitTexture::LUMINANCE_F16,
-                                         HighbitTexture::RGBA_8888)));
+INSTANTIATE_TEST_CASE_P(, VideoGLRendererPixelHiLoTest, ::testing::Bool());
 
 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRect) {
   gfx::Rect rect(this->device_viewport_size_);
@@ -1443,14 +1334,11 @@
   SharedQuadState* shared_state =
       CreateTestSharedQuadState(gfx::Transform(), rect, pass.get());
 
-  ResourceFormat y_format =
-      video_resource_updater_->YuvResourceFormat(8, media::PIXEL_FORMAT_NV12);
-
   // YUV of (149,43,21) should be green (0,255,0) in RGB.
   CreateTestYUVVideoDrawQuad_NV12(
       shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(),
-      y_format, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(),
-      rect, rect, resource_provider_.get());
+      gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect,
+      resource_provider_.get());
 
   RenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -1480,18 +1368,6 @@
                                  FuzzyPixelOffByOneComparator(true)));
 }
 
-TEST_F(VideoGLRendererPixelTest, TextureQuadEdgeBleed) {
-  // VideoResourceUpdater::CreateForSoftwarePlanes() converts YUV frame to RGBA
-  // texture.
-  DisableOneComponentTextures();
-  RenderPassList pass_list;
-  CreateEdgeBleedPass(media::PIXEL_FORMAT_YV12, media::COLOR_SPACE_JPEG,
-                      &pass_list);
-  EXPECT_TRUE(this->RunPixelTest(&pass_list,
-                                 base::FilePath(FILE_PATH_LITERAL("green.png")),
-                                 FuzzyPixelOffByOneComparator(true)));
-}
-
 TEST_F(VideoGLRendererPixelTest, SimpleYUVJRectGrey) {
   gfx::Rect rect(this->device_viewport_size_);
 
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index 9965ec2..b283692a 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -351,7 +351,6 @@
     uniform TexCoordPrecision vec4 texTransform[NUM_STATIC_QUADS];
     uniform float opacity[NUM_STATIC_QUADS * 4];
     varying TexCoordPrecision vec2 v_texCoord;
-    varying float v_index;
     varying float v_alpha;
   });
 }
@@ -360,7 +359,6 @@
   return SHADER0([]() {
     void main() {
       int quad_index = int(a_index * 0.25);  // NOLINT
-      v_index = float(quad_index);
       gl_Position = matrix[quad_index] * a_position;
       TexCoordPrecision vec4 texTrans = texTransform[quad_index];
       v_texCoord = a_texCoord * texTrans.zw + texTrans.xy;
@@ -1218,124 +1216,58 @@
   locations->backdrop_rect = backdrop_rect_location();
 }
 
-int FragmentTexQuadBase::background_color_location() const {
-  return -1;
-}
-
-int FragmentTexQuadBase::tex_clamp_rect_location() const {
-  return -1;
-}
-
-void FragmentTexClampBinding::Init(GLES2Interface* context,
-                                   unsigned program,
-                                   int* base_uniform_index) {
-  static const char* uniforms[] = {
-      "s_texture", "tex_clamp_rect",
-  };
-  int locations[arraysize(uniforms)];
-
-  GetProgramUniformLocations(context, program, arraysize(uniforms), uniforms,
-                             locations, base_uniform_index);
-
-  sampler_location_ = locations[0];
-  DCHECK_NE(sampler_location_, -1);
-
-  tex_clamp_rect_location_ = locations[1];
-  DCHECK_NE(tex_clamp_rect_location_, -1);
-}
-
-int FragmentTexClampBinding::tex_clamp_rect_location() const {
-  return tex_clamp_rect_location_;
-}
-
-std::string FragmentShaderRGBATexClampVaryingAlpha::GetShaderString(
+std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString(
     TexCoordPrecision precision,
     SamplerType sampler) const {
   return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
 }
 
-std::string FragmentShaderRGBATexClampVaryingAlpha::GetShaderHead() {
-  return base::StringPrintf("#define NUM_STATIC_QUADS %d\n",
-                            StaticGeometryBinding::NUM_QUADS) +
-         SHADER0([]() {
-           precision mediump float;
-           varying TexCoordPrecision vec2 v_texCoord;
-           varying float v_index;
-           varying float v_alpha;
-           uniform SamplerType s_texture;
-           uniform vec4 tex_clamp_rect[NUM_STATIC_QUADS];
-         });
+std::string FragmentShaderRGBATexVaryingAlpha::GetShaderHead() {
+  return SHADER0([]() {
+    precision mediump float;
+    varying TexCoordPrecision vec2 v_texCoord;
+    varying float v_alpha;
+    uniform SamplerType s_texture;
+  });
 }
 
-std::string FragmentShaderRGBATexClampVaryingAlpha::GetShaderBody() {
+std::string FragmentShaderRGBATexVaryingAlpha::GetShaderBody() {
   return SHADER0([]() {
     void main() {
-      vec2 tex_clamped = max(tex_clamp_rect[int(v_index)].xy,
-                             min(tex_clamp_rect[int(v_index)].zw, v_texCoord));
-      vec4 texColor = TextureLookup(s_texture, tex_clamped);
+      vec4 texColor = TextureLookup(s_texture, v_texCoord);
       gl_FragColor = texColor * v_alpha;
     }
   });
 }
 
-std::string FragmentShaderRGBATexClampPremultiplyAlpha::GetShaderString(
+std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderString(
     TexCoordPrecision precision,
     SamplerType sampler) const {
   return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
 }
 
-std::string FragmentShaderRGBATexClampPremultiplyAlpha::GetShaderHead() {
-  return base::StringPrintf("#define NUM_STATIC_QUADS %d\n",
-                            StaticGeometryBinding::NUM_QUADS) +
-         SHADER0([]() {
-           precision mediump float;
-           varying TexCoordPrecision vec2 v_texCoord;
-           varying float v_index;
-           varying float v_alpha;
-           uniform SamplerType s_texture;
-           uniform vec4 tex_clamp_rect[NUM_STATIC_QUADS];
-         });
+std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderHead() {
+  return SHADER0([]() {
+    precision mediump float;
+    varying TexCoordPrecision vec2 v_texCoord;
+    varying float v_alpha;
+    uniform SamplerType s_texture;
+  });
 }
 
-std::string FragmentShaderRGBATexClampPremultiplyAlpha::GetShaderBody() {
+std::string FragmentShaderRGBATexPremultiplyAlpha::GetShaderBody() {
   return SHADER0([]() {
     void main() {
-      vec2 tex_clamped = max(tex_clamp_rect[int(v_index)].xy,
-                             min(tex_clamp_rect[int(v_index)].zw, v_texCoord));
-      vec4 texColor = TextureLookup(s_texture, tex_clamped);
+      vec4 texColor = TextureLookup(s_texture, v_texCoord);
       texColor.rgb *= texColor.a;
       gl_FragColor = texColor * v_alpha;
     }
   });
 }
 
-std::string FragmentShaderRGBATexClamp::GetShaderString(
-    TexCoordPrecision precision,
-    SamplerType sampler) const {
-  return FRAGMENT_SHADER(GetShaderHead(), GetShaderBody());
-}
-
-std::string FragmentShaderRGBATexClamp::GetShaderHead() {
-  return SHADER0([]() {
-    precision mediump float;
-    varying TexCoordPrecision vec2 v_texCoord;
-    uniform SamplerType s_texture;
-    uniform vec4 tex_clamp_rect;
-  });
-}
-
-std::string FragmentShaderRGBATexClamp::GetShaderBody() {
-  return SHADER0([]() {
-    void main() {
-      vec2 tex_clamped =
-          max(tex_clamp_rect.xy, min(tex_clamp_rect.zw, v_texCoord));
-      gl_FragColor = TextureLookup(s_texture, tex_clamped);
-    }
-  });
-}
-
 FragmentTexBackgroundBinding::FragmentTexBackgroundBinding()
-    : background_color_location_(-1) {}
+    : background_color_location_(-1), sampler_location_(-1) {
+}
 
 void FragmentTexBackgroundBinding::Init(GLES2Interface* context,
                                         unsigned program,
@@ -1359,10 +1291,6 @@
   DCHECK_NE(background_color_location_, -1);
 }
 
-int FragmentTexBackgroundBinding::background_color_location() const {
-  return background_color_location_;
-}
-
 std::string FragmentShaderTexBackgroundVaryingAlpha::GetShaderString(
     TexCoordPrecision precision,
     SamplerType sampler) const {
@@ -1439,6 +1367,25 @@
   });
 }
 
+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 {
diff --git a/cc/output/shader.h b/cc/output/shader.h
index ea61c91..21b4a70 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -424,53 +424,42 @@
     int color_offset_location_;
 };
 
-class FragmentTexQuadBase : public FragmentTexBlendMode {
+class FragmentTexOpaqueBinding : public FragmentTexBlendMode {
  public:
-  FragmentTexQuadBase() = default;
-  virtual ~FragmentTexQuadBase() = default;
-
-  int sampler_location() const { return sampler_location_; }
-  virtual int background_color_location() const;
-  virtual int tex_clamp_rect_location() const;
-
- protected:
-  int sampler_location_ = -1;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexQuadBase);
-};
-
-class FragmentTexClampBinding : public FragmentTexQuadBase {
- public:
-  FragmentTexClampBinding() = default;
+  FragmentTexOpaqueBinding();
 
   void Init(gpu::gles2::GLES2Interface* context,
             unsigned program,
             int* base_uniform_index);
-  int tex_clamp_rect_location() const final;
+  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 tex_clamp_rect_location_ = -1;
+  int sampler_location_;
 
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexClampBinding);
+  DISALLOW_COPY_AND_ASSIGN(FragmentTexOpaqueBinding);
 };
 
-class FragmentTexBackgroundBinding : public FragmentTexQuadBase {
+class FragmentTexBackgroundBinding : public FragmentTexBlendMode {
  public:
   FragmentTexBackgroundBinding();
 
   void Init(gpu::gles2::GLES2Interface* context,
             unsigned program,
             int* base_uniform_index);
-  int background_color_location() const final;
+  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 FragmentShaderRGBATexClampVaryingAlpha : public FragmentTexClampBinding {
+class FragmentShaderRGBATexVaryingAlpha : public FragmentTexOpaqueBinding {
  public:
   std::string GetShaderString(
       TexCoordPrecision precision, SamplerType sampler) const;
@@ -478,16 +467,7 @@
   static std::string GetShaderBody();
 };
 
-class FragmentShaderRGBATexClampPremultiplyAlpha
-    : public FragmentTexClampBinding {
- public:
-  std::string GetShaderString(TexCoordPrecision precision,
-                              SamplerType sampler) const;
-  static std::string GetShaderHead();
-  static std::string GetShaderBody();
-};
-
-class FragmentShaderRGBATexClamp : public FragmentTexClampBinding {
+class FragmentShaderRGBATexPremultiplyAlpha : public FragmentTexOpaqueBinding {
  public:
   std::string GetShaderString(
       TexCoordPrecision precision, SamplerType sampler) const;
@@ -532,24 +512,15 @@
   void FillLocations(ShaderLocations* locations) const;
 };
 
-class FragmentTexOpaqueBinding : public FragmentTexBlendMode {
+class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding {
  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 sampler_location() const { return sampler_location_; }
-
- private:
-  int sampler_location_;
-
-  DISALLOW_COPY_AND_ASSIGN(FragmentTexOpaqueBinding);
+  std::string GetShaderString(
+      TexCoordPrecision precision, SamplerType sampler) const;
+  static std::string GetShaderHead();
+  static std::string GetShaderBody();
 };
 
-class FragmentShaderRGBATexOpaque : public FragmentTexOpaqueBinding {
+class FragmentShaderRGBATex : public FragmentTexOpaqueBinding {
  public:
   std::string GetShaderString(
       TexCoordPrecision precision, SamplerType sampler) const;
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
index 89ec99e..1be0b13 100644
--- a/cc/resources/resource_provider.cc
+++ b/cc/resources/resource_provider.cc
@@ -411,6 +411,7 @@
       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),
       best_render_buffer_format_(RGBA_8888),
@@ -448,6 +449,15 @@
   use_texture_format_bgra_ = caps.texture_format_bgra8888;
   use_texture_usage_hint_ = caps.texture_usage;
   use_compressed_texture_etc1_ = caps.texture_format_etc1;
+
+  if (caps.disable_one_component_textures) {
+    yuv_resource_format_ = yuv_highbit_resource_format_ = RGBA_8888;
+  } else {
+    yuv_resource_format_ = caps.texture_rg ? RED_8 : LUMINANCE_8;
+    yuv_highbit_resource_format_ =
+        caps.texture_half_float_linear ? LUMINANCE_F16 : yuv_resource_format_;
+  }
+
   use_sync_query_ = caps.sync_query;
 
   GLES2Interface* gl = ContextGL();
@@ -539,6 +549,14 @@
   resource->lost = true;
 }
 
+ResourceFormat ResourceProvider::YuvResourceFormat(int bits) const {
+  if (bits > 8) {
+    return yuv_highbit_resource_format_;
+  } else {
+    return yuv_resource_format_;
+  }
+}
+
 ResourceId ResourceProvider::CreateResource(
     const gfx::Size& size,
     TextureHint hint,
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h
index ef83e64..38d086d 100644
--- a/cc/resources/resource_provider.h
+++ b/cc/resources/resource_provider.h
@@ -101,6 +101,7 @@
   ResourceFormat best_render_buffer_format() const {
     return best_render_buffer_format_;
   }
+  ResourceFormat YuvResourceFormat(int bits) const;
   bool use_sync_query() const { return use_sync_query_; }
   gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() {
     return gpu_memory_buffer_manager_;
@@ -689,6 +690,8 @@
   bool use_texture_format_bgra_;
   bool use_texture_usage_hint_;
   bool use_compressed_texture_etc1_;
+  ResourceFormat yuv_resource_format_;
+  ResourceFormat yuv_highbit_resource_format_;
   int max_texture_size_;
   ResourceFormat best_texture_format_;
   ResourceFormat best_render_buffer_format_;
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc
index e713c5d5..2ea3f469 100644
--- a/cc/resources/video_resource_updater.cc
+++ b/cc/resources/video_resource_updater.cc
@@ -379,32 +379,6 @@
   }
 }
 
-ResourceFormat VideoResourceUpdater::YuvResourceFormat(
-    int bits,
-    media::VideoPixelFormat format) const {
-  if (!context_provider_)
-    return RGBA_8888;
-
-  if (format == media::PIXEL_FORMAT_Y16) {
-    // Unable to display directly as yuv planes so convert it to RGBA for
-    // compositing.
-    return RGBA_8888;
-  }
-
-  const auto caps = context_provider_->ContextCapabilities();
-  if (caps.disable_one_component_textures)
-    return RGBA_8888;
-
-  ResourceFormat yuv_resource_format = caps.texture_rg ? RED_8 : LUMINANCE_8;
-  if (bits <= 8)
-    return yuv_resource_format;
-
-  if (caps.texture_half_float_linear)
-    return LUMINANCE_F16;
-
-  return yuv_resource_format;
-}
-
 VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes(
     scoped_refptr<media::VideoFrame> video_frame) {
   TRACE_EVENT0("cc", "VideoResourceUpdater::CreateForSoftwarePlanes");
@@ -458,23 +432,26 @@
   DCHECK(media::IsYuvPlanar(input_frame_format) ||
          input_frame_format == media::PIXEL_FORMAT_Y16);
 
-  const bool software_compositor = context_provider_ == nullptr;
-  bool disable_one_component_textures = true;
-  if (!software_compositor) {
-    const auto caps = context_provider_->ContextCapabilities();
-    disable_one_component_textures = caps.disable_one_component_textures;
-  }
+  const bool software_compositor = context_provider_ == NULL;
 
-  ResourceFormat output_resource_format =
-      YuvResourceFormat(bits_per_channel, input_frame_format);
+  ResourceFormat output_resource_format;
+  if (input_frame_format == media::PIXEL_FORMAT_Y16) {
+    // Unable to display directly as yuv planes so convert it to RGBA for
+    // compositing.
+    output_resource_format = RGBA_8888;
+  } else {
+    // Can be composited directly from yuv planes.
+    output_resource_format =
+        resource_provider_->YuvResourceFormat(bits_per_channel);
+  }
 
   // If GPU compositing is enabled, but the output resource format
   // returned by the resource provider is RGBA_8888, then a GPU driver
   // bug workaround requires that YUV frames must be converted to RGB
   // before texture upload.
   bool texture_needs_rgb_conversion =
-      (!software_compositor && disable_one_component_textures) ||
-      input_frame_format == media::PIXEL_FORMAT_Y16;
+      !software_compositor &&
+      output_resource_format == ResourceFormat::RGBA_8888;
   size_t output_plane_count = media::VideoFrame::NumPlanes(input_frame_format);
 
   // TODO(skaslev): If we're in software compositing mode, we do the YUV -> RGB
@@ -482,7 +459,7 @@
   // Obviously, this is suboptimal and should be addressed once ubercompositor
   // starts shaping up.
   if (software_compositor || texture_needs_rgb_conversion) {
-    DCHECK_EQ(output_resource_format, kRGBResourceFormat);
+    output_resource_format = kRGBResourceFormat;
     output_plane_count = 1;
     bits_per_channel = 8;
   }
@@ -550,9 +527,7 @@
           upload_pixels_.resize(needed_size);
 
         media::SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
-            video_frame.get(),
-            media::SkCanvasVideoRenderer::ConvertingSize::CODED,
-            &upload_pixels_[0], bytes_per_row);
+            video_frame.get(), &upload_pixels_[0], bytes_per_row);
 
         resource_provider_->CopyToResource(plane_resource.resource_id(),
                                            &upload_pixels_[0],
@@ -572,8 +547,7 @@
       // a sync token is not required.
       TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(),
                              resource_provider_->GetResourceTextureTarget(
-                                 plane_resource.resource_id()),
-                             plane_resource.resource_size(), false, false);
+                                 plane_resource.resource_id()));
       mailbox.set_color_space(video_frame->ColorSpace());
       external_resources.mailboxes.push_back(mailbox);
       external_resources.release_callbacks.push_back(base::Bind(
@@ -584,7 +558,7 @@
   }
 
   std::unique_ptr<HalfFloatMaker> half_float_maker;
-  if (YuvResourceFormat(bits_per_channel, input_frame_format) ==
+  if (resource_provider_->YuvResourceFormat(bits_per_channel) ==
       LUMINANCE_F16) {
     half_float_maker = NewHalfFloatMaker(bits_per_channel);
     external_resources.offset = half_float_maker->Offset();
@@ -595,7 +569,7 @@
     PlaneResource& plane_resource = *plane_resources[i];
     // Update each plane's resource id with its content.
     DCHECK_EQ(plane_resource.resource_format(),
-              YuvResourceFormat(bits_per_channel, input_frame_format));
+              resource_provider_->YuvResourceFormat(bits_per_channel));
 
     if (!plane_resource.Matches(video_frame->unique_id(), i)) {
       // TODO(hubbe): Move all conversion (and upload?) code to media/.
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h
index a5a4059..b9b5b95c 100644
--- a/cc/resources/video_resource_updater.h
+++ b/cc/resources/video_resource_updater.h
@@ -20,7 +20,6 @@
 #include "cc/resources/release_callback_impl.h"
 #include "cc/resources/resource_format.h"
 #include "cc/resources/texture_mailbox.h"
-#include "media/base/video_types.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace media {
@@ -104,9 +103,6 @@
   static std::unique_ptr<HalfFloatMaker> NewHalfFloatMaker(
       int bits_per_channel);
 
-  ResourceFormat YuvResourceFormat(int bits,
-                                   media::VideoPixelFormat format) const;
-
  private:
   class PlaneResource {
    public:
diff --git a/cc/test/data/yuv_stripes.png b/cc/test/data/yuv_stripes.png
index a35e12d..1e64aa3 100644
--- a/cc/test/data/yuv_stripes.png
+++ b/cc/test/data/yuv_stripes.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_alpha.png b/cc/test/data/yuv_stripes_alpha.png
index a78586d..90ef195 100644
--- a/cc/test/data/yuv_stripes_alpha.png
+++ b/cc/test/data/yuv_stripes_alpha.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_clipped.png b/cc/test/data/yuv_stripes_clipped.png
index 841b29e..e6459b3 100644
--- a/cc/test/data/yuv_stripes_clipped.png
+++ b/cc/test/data/yuv_stripes_clipped.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_clipped_rgba.png b/cc/test/data/yuv_stripes_clipped_rgba.png
deleted file mode 100644
index 0c69992..0000000
--- a/cc/test/data/yuv_stripes_clipped_rgba.png
+++ /dev/null
Binary files differ
diff --git a/cc/test/data/yuv_stripes_offset.png b/cc/test/data/yuv_stripes_offset.png
index d080515..4a12555 100644
--- a/cc/test/data/yuv_stripes_offset.png
+++ b/cc/test/data/yuv_stripes_offset.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_rgba.png b/cc/test/data/yuv_stripes_rgba.png
deleted file mode 100644
index fddf58ae..0000000
--- a/cc/test/data/yuv_stripes_rgba.png
+++ /dev/null
Binary files differ
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
index 3b6bdc0..f54217d 100644
--- a/cc/test/render_pass_test_utils.cc
+++ b/cc/test/render_pass_test_utils.cc
@@ -160,8 +160,7 @@
   memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1);
   std::unique_ptr<SingleReleaseCallbackImpl> callback =
       SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback));
-  TextureMailbox mailbox(gpu_mailbox, kSyncTokenForMailboxTextureQuad, target,
-                         rect.size(), false, false);
+  TextureMailbox mailbox(gpu_mailbox, kSyncTokenForMailboxTextureQuad, target);
   ResourceId resource8 = resource_provider->CreateResourceFromTextureMailbox(
       mailbox, std::move(callback));
   resource_provider->AllocateForTesting(resource8);
diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc
index 0aa0644..042be7c 100644
--- a/cc/test/test_in_process_context_provider.cc
+++ b/cc/test/test_in_process_context_provider.cc
@@ -109,10 +109,6 @@
   gpu::Capabilities capabilities;
   capabilities.texture_rectangle = true;
   capabilities.sync_query = true;
-  capabilities.disable_one_component_textures =
-      capabilities_disable_one_component_textures_;
-  capabilities.texture_half_float_linear =
-      capabilities_texture_half_float_linear_;
   switch (PlatformColor::Format()) {
     case PlatformColor::SOURCE_FORMAT_RGBA8:
       capabilities.texture_format_bgra8888 = false;
diff --git a/cc/test/test_in_process_context_provider.h b/cc/test/test_in_process_context_provider.h
index b6bd6cb5..0b8ea12 100644
--- a/cc/test/test_in_process_context_provider.h
+++ b/cc/test/test_in_process_context_provider.h
@@ -50,13 +50,6 @@
   void SetLostContextCallback(
       const LostContextCallback& lost_context_callback) override;
 
-  void SetDisableOneComponentTextures(bool disable) {
-    capabilities_disable_one_component_textures_ = disable;
-  }
-  void SetSupportTextureHalfFloatLinear(bool support) {
-    capabilities_texture_half_float_linear_ = support;
-  }
-
  protected:
   friend class base::RefCountedThreadSafe<TestInProcessContextProvider>;
   ~TestInProcessContextProvider() override;
@@ -68,9 +61,6 @@
   std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_;
   std::unique_ptr<ContextCacheController> cache_controller_;
   base::Lock context_lock_;
-
-  bool capabilities_disable_one_component_textures_ = false;
-  bool capabilities_texture_half_float_linear_ = false;
 };
 
 }  // namespace cc
diff --git a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
index bfc1d752..2bea5ce 100644
--- a/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
+++ b/chrome/browser/chromeos/chrome_browser_main_chromeos.cc
@@ -756,6 +756,8 @@
 
 void ChromeBrowserMainPartsChromeos::PostBrowserStart() {
   if (!chrome::IsRunningInMash()) {
+    system::InputDeviceSettings::Get()->UpdateTouchDevicesStatusFromPrefs();
+
     // These are dependent on the ash::Shell singleton already having been
     // initialized. Consequently, these cannot be used when running as a mus
     // client.
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index 0b402aa..b9b1fdb 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -707,8 +707,7 @@
                                              prefs::kUse24HourClock, value);
   }
 
-  system::InputDeviceSettings::Get()
-      ->UpdateTouchDevicesStatusFromActiveProfilePrefs();
+  system::InputDeviceSettings::Get()->UpdateTouchDevicesStatusFromPrefs();
 }
 
 void Preferences::OnIsSyncingChanged() {
diff --git a/chrome/browser/chromeos/system/input_device_settings.cc b/chrome/browser/chromeos/system/input_device_settings.cc
index eb94105..cc3db8f 100644
--- a/chrome/browser/chromeos/system/input_device_settings.cc
+++ b/chrome/browser/chromeos/system/input_device_settings.cc
@@ -234,42 +234,69 @@
 }
 
 // static
+void InputDeviceSettings::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterBooleanPref(::prefs::kTouchscreenEnabledLocal, true);
+}
+
+// static
 void InputDeviceSettings::RegisterProfilePrefs(PrefRegistrySimple* registry) {
-  registry->RegisterBooleanPref(::prefs::kTouchScreenEnabled, true);
-  registry->RegisterBooleanPref(::prefs::kTouchPadEnabled, true);
+  registry->RegisterBooleanPref(::prefs::kTouchscreenEnabled, true);
+  registry->RegisterBooleanPref(::prefs::kTouchpadEnabled, true);
 }
 
-void InputDeviceSettings::UpdateTouchDevicesStatusFromActiveProfilePrefs() {
+void InputDeviceSettings::UpdateTouchDevicesStatusFromPrefs() {
+  UpdateTouchscreenStatusFromPrefs();
+
   PrefService* user_prefs = GetActiveProfilePrefs();
   if (!user_prefs)
     return;
 
-  const bool touch_screen_status =
-      user_prefs->HasPrefPath(::prefs::kTouchScreenEnabled)
-          ? user_prefs->GetBoolean(::prefs::kTouchScreenEnabled)
+  const bool touchpad_status =
+      user_prefs->HasPrefPath(::prefs::kTouchpadEnabled)
+          ? user_prefs->GetBoolean(::prefs::kTouchpadEnabled)
           : true;
-
-  const bool touch_pad_status =
-      user_prefs->HasPrefPath(::prefs::kTouchPadEnabled)
-          ? user_prefs->GetBoolean(::prefs::kTouchPadEnabled)
-          : true;
-
-  SetTouchscreensEnabled(touch_screen_status);
-  SetInternalTouchpadEnabled(touch_pad_status);
+  SetInternalTouchpadEnabled(touchpad_status);
 }
 
-void InputDeviceSettings::ToggleTouchscreen() {
-  PrefService* user_prefs = GetActiveProfilePrefs();
-  if (!user_prefs)
-    return;
+bool InputDeviceSettings::IsTouchscreenEnabledInPrefs(
+    bool use_local_state) const {
+  if (use_local_state) {
+    PrefService* local_state = g_browser_process->local_state();
+    DCHECK(local_state);
 
-  const bool touch_screen_status =
-      user_prefs->HasPrefPath(::prefs::kTouchScreenEnabled)
-          ? user_prefs->GetBoolean(::prefs::kTouchScreenEnabled)
-          : true;
+    return local_state->HasPrefPath(::prefs::kTouchscreenEnabledLocal)
+               ? local_state->GetBoolean(::prefs::kTouchscreenEnabledLocal)
+               : true;
+  } else {
+    PrefService* user_prefs = GetActiveProfilePrefs();
+    if (!user_prefs)
+      return true;
 
-  user_prefs->SetBoolean(::prefs::kTouchScreenEnabled, !touch_screen_status);
-  SetTouchscreensEnabled(!touch_screen_status);
+    return user_prefs->HasPrefPath(::prefs::kTouchscreenEnabled)
+               ? user_prefs->GetBoolean(::prefs::kTouchscreenEnabled)
+               : true;
+  }
+}
+
+void InputDeviceSettings::SetTouchscreenEnabledInPrefs(bool enabled,
+                                                       bool use_local_state) {
+  if (use_local_state) {
+    PrefService* local_state = g_browser_process->local_state();
+    DCHECK(local_state);
+    local_state->SetBoolean(::prefs::kTouchscreenEnabledLocal, enabled);
+  } else {
+    PrefService* user_prefs = GetActiveProfilePrefs();
+    if (!user_prefs)
+      return;
+
+    user_prefs->SetBoolean(::prefs::kTouchscreenEnabled, enabled);
+  }
+}
+
+void InputDeviceSettings::UpdateTouchscreenStatusFromPrefs() {
+  bool enabled_in_local_state = IsTouchscreenEnabledInPrefs(true);
+  bool enabled_in_user_prefs = IsTouchscreenEnabledInPrefs(false);
+  SetTouchscreensEnabled(enabled_in_local_state && enabled_in_user_prefs);
 }
 
 void InputDeviceSettings::ToggleTouchpad() {
@@ -277,13 +304,13 @@
   if (!user_prefs)
     return;
 
-  const bool touch_pad_status =
-      user_prefs->HasPrefPath(::prefs::kTouchPadEnabled)
-          ? user_prefs->GetBoolean(::prefs::kTouchPadEnabled)
+  const bool touchpad_status =
+      user_prefs->HasPrefPath(::prefs::kTouchpadEnabled)
+          ? user_prefs->GetBoolean(::prefs::kTouchpadEnabled)
           : true;
 
-  user_prefs->SetBoolean(::prefs::kTouchPadEnabled, !touch_pad_status);
-  SetInternalTouchpadEnabled(!touch_pad_status);
+  user_prefs->SetBoolean(::prefs::kTouchpadEnabled, !touchpad_status);
+  SetInternalTouchpadEnabled(!touchpad_status);
 }
 
 }  // namespace system
diff --git a/chrome/browser/chromeos/system/input_device_settings.h b/chrome/browser/chromeos/system/input_device_settings.h
index 5cf208f2..24311ce0 100644
--- a/chrome/browser/chromeos/system/input_device_settings.h
+++ b/chrome/browser/chromeos/system/input_device_settings.h
@@ -174,16 +174,29 @@
   // where other input devices like mouse are absent.
   static bool ForceKeyboardDrivenUINavigation();
 
-  // Registers profile pref names for touchpad and touch screen statuses.
+  // Registers local state pref names for touchscreen status.
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
+  // Registers profile pref names for touchpad and touchscreen statuses.
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
-  // Updates the on/off status of the touchscreen/touchpad from the active
-  // user's preferences.
-  void UpdateTouchDevicesStatusFromActiveProfilePrefs();
+  // Updates the enabled/disabled status of the touchscreen/touchpad from the
+  // preferences.
+  void UpdateTouchDevicesStatusFromPrefs();
 
-  // Toggles the status of Touchscreen/Touchpad on or off and updates the local
-  // prefs.
-  void ToggleTouchscreen();
+  // If |use_local_state| is true, returns the touchscreen status from local
+  // state, otherwise from user prefs.
+  bool IsTouchscreenEnabledInPrefs(bool use_local_state) const;
+
+  // Sets the status of touchscreen to |enabled| in prefs. If |use_local_state|,
+  // pref is set in local state, otherwise in user pref.
+  void SetTouchscreenEnabledInPrefs(bool enabled, bool use_local_state);
+
+  // Updates the enabled/disabled status of the touchscreen from prefs. Enabled
+  // if both local state and user prefs are enabled, otherwise disabled.
+  void UpdateTouchscreenStatusFromPrefs();
+
+  // Toggles the status of touchpad between enabled and disabled.
   void ToggleTouchpad();
 
   // Calls |callback|, possibly asynchronously, after determining if a touchpad
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 176f283..2f95eb44 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -429,6 +429,7 @@
   chromeos::SigninScreenHandler::RegisterPrefs(registry);
   chromeos::StartupUtils::RegisterPrefs(registry);
   chromeos::system::AutomaticRebootManager::RegisterPrefs(registry);
+  chromeos::system::InputDeviceSettings::RegisterPrefs(registry);
   chromeos::TimeZoneResolver::RegisterPrefs(registry);
   chromeos::UserImageManager::RegisterPrefs(registry);
   chromeos::UserSessionManager::RegisterPrefs(registry);
@@ -707,8 +708,8 @@
 void MigrateObsoleteBrowserPrefs(Profile* profile, PrefService* local_state) {
 #if defined(OS_CHROMEOS)
   // Added 11/2016
-  local_state->ClearPref(prefs::kTouchScreenEnabled);
-  local_state->ClearPref(prefs::kTouchPadEnabled);
+  local_state->ClearPref(prefs::kTouchscreenEnabled);
+  local_state->ClearPref(prefs::kTouchpadEnabled);
 #endif  // defined(OS_CHROMEOS)
 }
 
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc
index 9dc9758..0440d50 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -500,12 +500,25 @@
       IDR_BLUETOOTH_KEYBOARD);
 }
 
-void ChromeShellDelegate::ToggleTouchpad() {
-  chromeos::system::InputDeviceSettings::Get()->ToggleTouchpad();
+bool ChromeShellDelegate::IsTouchscreenEnabledInPrefs(
+    bool use_local_state) const {
+  return chromeos::system::InputDeviceSettings::Get()
+      ->IsTouchscreenEnabledInPrefs(use_local_state);
 }
 
-void ChromeShellDelegate::ToggleTouchscreen() {
-  chromeos::system::InputDeviceSettings::Get()->ToggleTouchscreen();
+void ChromeShellDelegate::SetTouchscreenEnabledInPrefs(bool enabled,
+                                                       bool use_local_state) {
+  chromeos::system::InputDeviceSettings::Get()->SetTouchscreenEnabledInPrefs(
+      enabled, use_local_state);
+}
+
+void ChromeShellDelegate::UpdateTouchscreenStatusFromPrefs() {
+  chromeos::system::InputDeviceSettings::Get()
+      ->UpdateTouchscreenStatusFromPrefs();
+}
+
+void ChromeShellDelegate::ToggleTouchpad() {
+  chromeos::system::InputDeviceSettings::Get()->ToggleTouchpad();
 }
 
 keyboard::KeyboardUI* ChromeShellDelegate::CreateKeyboardUI() {
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h
index 2b5fde0..95d0052 100644
--- a/chrome/browser/ui/ash/chrome_shell_delegate.h
+++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -56,8 +56,11 @@
   base::string16 GetProductName() const override;
   void OpenKeyboardShortcutHelpPage() const override;
   gfx::Image GetDeprecatedAcceleratorImage() const override;
+  bool IsTouchscreenEnabledInPrefs(bool use_local_state) const override;
+  void SetTouchscreenEnabledInPrefs(bool enabled,
+                                    bool use_local_state) override;
+  void UpdateTouchscreenStatusFromPrefs() override;
   void ToggleTouchpad() override;
-  void ToggleTouchscreen() override;
 
   // content::NotificationObserver override:
   void Observe(int type,
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index a8dbe12..e7c71f43 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -844,9 +844,9 @@
 // A boolean pref set to true if the virtual keyboard should be enabled.
 const char kTouchVirtualKeyboardEnabled[] = "ui.touch_virtual_keyboard_enabled";
 
-// Boolean prefs for the status of the touch screen and the touchpad.
-const char kTouchScreenEnabled[] = "events.touch_screen.enabled";
-const char kTouchPadEnabled[] = "events.touch_pad.enabled";
+// Boolean prefs for the status of the touchscreen and the touchpad.
+const char kTouchscreenEnabled[] = "events.touch_screen.enabled";
+const char kTouchpadEnabled[] = "events.touch_pad.enabled";
 
 // A boolean pref that controls whether the dark connect feature is enabled.
 // The dark connect feature allows a Chrome OS device to periodically wake
@@ -1415,13 +1415,6 @@
 // A boolean indicating if ending processes are enabled or disabled by policy.
 const char kTaskManagerEndProcessEnabled[] = "task_manager.end_process_enabled";
 
-#if defined(OS_CHROMEOS)
-// Dictionary indicating current network bandwidth throttling settings.
-// Contains a boolean (is throttling enabled) and two integers (upload rate
-// and download rate in kbits/s to throttle to)
-const char kNetworkThrottlingEnabled[] = "net.throttling_enabled";
-#endif
-
 // A collection of position, size, and other data relating to app windows to
 // restore on startup.
 const char kAppWindowPlacement[] = "browser.app_window_placement";
@@ -1883,6 +1876,14 @@
 // A preference that controlles Android status reporting.
 const char kReportArcStatusEnabled[] = "arc.status_reporting_enabled";
 
+// Dictionary indicating current network bandwidth throttling settings.
+// Contains a boolean (is throttling enabled) and two integers (upload rate
+// and download rate in kbits/s to throttle to)
+const char kNetworkThrottlingEnabled[] = "net.throttling_enabled";
+
+// Boolean prefs for the local status of the touchscreen.
+const char kTouchscreenEnabledLocal[] = "events.touch_screen.enabled_local";
+
 #endif  // defined(OS_CHROMEOS)
 
 // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index c9251d3f..6d4972b 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -293,8 +293,8 @@
 extern const char kCurrentWallpaperAppName[];
 extern const char kFileSystemProviderMounted[];
 extern const char kTouchVirtualKeyboardEnabled[];
-extern const char kTouchScreenEnabled[];
-extern const char kTouchPadEnabled[];
+extern const char kTouchscreenEnabled[];
+extern const char kTouchpadEnabled[];
 extern const char kWakeOnWifiDarkConnect[];
 extern const char kCaptivePortalAuthenticationIgnoresProxy[];
 extern const char kForceMaximizeOnFirstRun[];
@@ -664,6 +664,7 @@
 extern const char kIsBootstrappingSlave[];
 extern const char kReportArcStatusEnabled[];
 extern const char kNetworkThrottlingEnabled[];
+extern const char kTouchscreenEnabledLocal[];
 #endif  // defined(OS_CHROMEOS)
 
 extern const char kClearPluginLSODataEnabled[];
diff --git a/chromeos/components/BUILD.gn b/chromeos/components/BUILD.gn
new file mode 100644
index 0000000..636f4bc
--- /dev/null
+++ b/chromeos/components/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright 2016 The Chromium 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")
+
+assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
+
+# To add a unit test to this target, make a "unit_test" source_set in your
+# component and add a reference here.
+test("chromeos_components_unittests") {
+  sources = [
+    "run_all_unittests.cc",
+  ]
+
+  deps = [
+    "//base",
+    "//base/test:test_support",
+    "//chromeos/components/tether:unit_tests",
+  ]
+}
diff --git a/chromeos/components/run_all_unittests.cc b/chromeos/components/run_all_unittests.cc
new file mode 100644
index 0000000..064a9bc
--- /dev/null
+++ b/chromeos/components/run_all_unittests.cc
@@ -0,0 +1,14 @@
+// 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 "base/test/launcher/unit_test_launcher.h"
+#include "base/test/test_suite.h"
+
+int main(int argc, char** argv) {
+  base::TestSuite test_suite(argc, argv);
+  return base::LaunchUnitTests(
+      argc, argv,
+      base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn
new file mode 100644
index 0000000..5ea6be4
--- /dev/null
+++ b/chromeos/components/tether/BUILD.gn
@@ -0,0 +1,44 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
+
+static_library("tether") {
+  sources = [
+    "initializer.cc",
+    "initializer.h",
+  ]
+
+  deps = [
+    "//base",
+  ]
+}
+
+static_library("test_support") {
+  testonly = true
+
+  sources = []
+
+  public_deps = [
+    ":tether",
+  ]
+
+  deps = [
+    "//base",
+    "//testing/gmock",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+
+  sources = []
+
+  deps = [
+    ":test_support",
+    ":tether",
+    "//base/test:test_support",
+    "//testing/gtest",
+  ]
+}
diff --git a/chromeos/components/tether/OWNERS b/chromeos/components/tether/OWNERS
new file mode 100644
index 0000000..07d43fee
--- /dev/null
+++ b/chromeos/components/tether/OWNERS
@@ -0,0 +1,3 @@
+khorimoto@chromium.org
+hansberry@chromium.org
+jlklein@chromium.org
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc
new file mode 100644
index 0000000..7cb779d
--- /dev/null
+++ b/chromeos/components/tether/initializer.cc
@@ -0,0 +1,17 @@
+// Copyright 2016 The Chromium 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 "chromeos/components/tether/initializer.h"
+
+namespace chromeos {
+
+namespace tether {
+
+Initializer::Initializer() {}
+
+Initializer::~Initializer() {}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/initializer.h b/chromeos/components/tether/initializer.h
new file mode 100644
index 0000000..d0e4a1f
--- /dev/null
+++ b/chromeos/components/tether/initializer.h
@@ -0,0 +1,29 @@
+// Copyright 2016 The Chromium 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 CHROMEOS_COMPONENTS_TETHER_INITIALIZER_H_
+#define CHROMEOS_COMPONENTS_TETHER_INITIALIZER_H_
+
+#include "base/macros.h"
+
+namespace chromeos {
+
+namespace tether {
+
+// Initializes the Tether Chrome OS component.
+// TODO(khorimoto): Implement.
+class Initializer {
+ public:
+  Initializer();
+  ~Initializer();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Initializer);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_INITIALIZER_H_
diff --git a/components/test_runner/test_plugin.cc b/components/test_runner/test_plugin.cc
index 03cdcd0..6818384 100644
--- a/components/test_runner/test_plugin.cc
+++ b/components/test_runner/test_plugin.cc
@@ -265,9 +265,7 @@
 
     gpu::SyncToken sync_token;
     gl_->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
-    texture_mailbox_ =
-        cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D,
-                           gfx::Rect(rect_).size(), false, false);
+    texture_mailbox_ = cc::TextureMailbox(mailbox, sync_token, GL_TEXTURE_2D);
   } else {
     std::unique_ptr<cc::SharedBitmap> bitmap =
         delegate_->GetSharedBitmapManager()->AllocateSharedBitmap(
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index f55c17c..840d3a4 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -386,8 +386,7 @@
   if (subscriber_texture.get()) {
     request->SetTextureMailbox(cc::TextureMailbox(
         subscriber_texture->mailbox(), subscriber_texture->sync_token(),
-        subscriber_texture->target(), current_frame_size_in_dip_, false,
-        false));
+        subscriber_texture->target()));
   }
 
   if (local_frame_id_.is_valid()) {
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py
index b18a5ef8..757260a 100644
--- a/content/test/gpu/gpu_tests/pixel_expectations.py
+++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -41,20 +41,6 @@
     self.Flaky('Pixel_ScissorTestWithPreserveDrawingBuffer', ['mac'],
                bug=660461)
 
-    # TODO(dshwang): remove these after new reference images are generated.
-    self.Fail('Pixel_2DCanvasWebGL', bug=615325)
-    self.Fail('Pixel_2DCanvasWebGLES3', bug=615325)
-    self.Fail('Pixel_OffscreenCanvasWebGLDefault', bug=615325)
-    self.Fail('Pixel_OffscreenCanvasWebGLDefaultWorker', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_Alpha', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_NoAlpha', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_NoAA_Alpha', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_NoAA_NoAlpha', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_AlphaES3', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_AA_NoAlphaES3', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_NoAA_AlphaES3', bug=615325)
-    self.Fail('Pixel_WebGLGreenTriangle_NoAA_NoAlphaES3', bug=615325)
-
     # TODO(kainino): remove this once golden images are generated
     self.Fail('Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear',
               bug=666259)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py
index e853271..ad0650b 100644
--- a/content/test/gpu/gpu_tests/pixel_test_pages.py
+++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -64,25 +64,25 @@
       'pixel_webgl_aa_alpha.html',
       base_name + '_WebGLGreenTriangle_AA_Alpha',
       test_rect=[0, 0, 300, 300],
-      revision=2),
+      revision=1),
 
     PixelTestPage(
       'pixel_webgl_noaa_alpha.html',
       base_name + '_WebGLGreenTriangle_NoAA_Alpha',
       test_rect=[0, 0, 300, 300],
-      revision=2),
+      revision=1),
 
     PixelTestPage(
       'pixel_webgl_aa_noalpha.html',
       base_name + '_WebGLGreenTriangle_AA_NoAlpha',
       test_rect=[0, 0, 300, 300],
-      revision=2),
+      revision=1),
 
     PixelTestPage(
       'pixel_webgl_noaa_noalpha.html',
       base_name + '_WebGLGreenTriangle_NoAA_NoAlpha',
       test_rect=[0, 0, 300, 300],
-      revision=2),
+      revision=1),
 
     PixelTestPage(
       'pixel_webgl_noalpha_implicit_clear.html',
@@ -123,7 +123,7 @@
       'pixel_canvas2d_webgl.html',
       base_name + '_2DCanvasWebGL',
       test_rect=[0, 0, 300, 300],
-      revision=4),
+      revision=3),
 
     PixelTestPage(
       'pixel_background.html',
@@ -159,14 +159,14 @@
       'pixel_offscreenCanvas_webgl_commit_main.html',
       base_name + '_OffscreenCanvasWebGLDefault',
       test_rect=[0, 0, 350, 350],
-      revision=2,
+      revision=1,
       browser_args=browser_args),
 
     PixelTestPage(
       'pixel_offscreenCanvas_webgl_commit_worker.html',
       base_name + '_OffscreenCanvasWebGLDefaultWorker',
       test_rect=[0, 0, 350, 350],
-      revision=2,
+      revision=1,
       browser_args=browser_args),
 
     PixelTestPage(
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 9ecf0ce..7dcf1fb4 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -538,6 +538,12 @@
     self.Flaky('deqp/functional/gles3/texturespecification/' +
         'random_teximage2d_2d.html',
         ['linux', 'amd', 'intel'], bug=618447)
+    self.Fail('conformance2/rendering/clear-srgb-color-buffer.html',
+        ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1
+    self.Fail('conformance2/rendering/clipping-wide-points.html',
+        ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1
+    self.Fail('conformance2/textures/misc/tex-srgb-mipmap.html',
+        ['linux', 'amd', 'intel'], bug=662644) # WebGL 2.0.1
 
     # Linux NVIDIA
     # This test is flaky both with and without ANGLE.
@@ -608,6 +614,8 @@
         ['linux', 'amd'], bug=483282)
     self.Fail('conformance2/rendering/blitframebuffer-filter-srgb.html',
         ['linux', 'amd'], bug=634525)
+    self.Fail('conformance2/rendering/blitframebuffer-outside-readbuffer.html',
+        ['linux', 'amd'], bug=662644) # WebGL 2.0.1
     self.Fail('conformance2/renderbuffers/framebuffer-texture-layer.html',
         ['linux', 'amd'], bug=295792)
     self.Fail('conformance2/textures/misc/tex-mipmap-levels.html',
diff --git a/media/renderers/skcanvas_video_renderer.cc b/media/renderers/skcanvas_video_renderer.cc
index 9376b5d..e6ee9d1 100644
--- a/media/renderers/skcanvas_video_renderer.cc
+++ b/media/renderers/skcanvas_video_renderer.cc
@@ -225,9 +225,8 @@
                    SkPMColor ctable[],
                    int* ctable_count) override {
     // If skia couldn't do the YUV conversion on GPU, we will on CPU.
-    SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
-        frame_.get(), SkCanvasVideoRenderer::ConvertingSize::VISUAL, pixels,
-        row_bytes);
+    SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(frame_.get(), pixels,
+                                                        row_bytes);
     return true;
   }
 
@@ -523,33 +522,19 @@
   return ret;
 }
 
-const uint8_t* FrameData(const VideoFrame* video_frame,
-                         SkCanvasVideoRenderer::ConvertingSize size_type,
-                         size_t plane) {
-  if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL)
-    return video_frame->visible_data(plane);
-  DCHECK(size_type == SkCanvasVideoRenderer::ConvertingSize::CODED);
-  return video_frame->data(plane);
-}
-
 // We take the upper 8 bits of 16-bit data and convert it as luminance to ARGB.
 // We loose the precision here, but it is important not to render Y16 as RG_88.
 // To get the full precision use float textures with WebGL1 and e.g. R16UI or
 // R32F textures with WebGL2.
 void ConvertY16ToARGB(const VideoFrame* video_frame,
-                      SkCanvasVideoRenderer::ConvertingSize size_type,
                       void* argb_pixels,
                       size_t argb_row_bytes) {
-  const uint8_t* row_head =
-      FrameData(video_frame, size_type, VideoFrame::kYPlane);
+  const uint8_t* row_head = video_frame->visible_data(0);
   uint8_t* out = static_cast<uint8_t*>(argb_pixels);
   const size_t stride = video_frame->stride(0);
-  gfx::Size frame_size = video_frame->coded_size();
-  if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL)
-    frame_size = video_frame->visible_rect().size();
-  for (int i = 0; i < frame_size.height(); ++i) {
+  for (int i = 0; i < video_frame->visible_rect().height(); ++i) {
     uint32_t* rgba = reinterpret_cast<uint32_t*>(out);
-    const uint8_t* row_end = row_head + frame_size.width() * 2;
+    const uint8_t* row_end = row_head + video_frame->visible_rect().width() * 2;
     for (const uint8_t* row = row_head; row < row_end; ++row) {
       uint32_t gray_value = *++row;
       *rgba++ = SkColorSetRGB(gray_value, gray_value, gray_value);
@@ -559,12 +544,11 @@
   }
 }
 
-}  // namespace
+}  // anonymous namespace
 
 // static
 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels(
     const VideoFrame* video_frame,
-    ConvertingSize size_type,
     void* rgb_pixels,
     size_t row_bytes) {
   if (!video_frame->IsMappable()) {
@@ -572,82 +556,79 @@
     return;
   }
 
-  gfx::Size frame_size = video_frame->coded_size();
-  if (size_type == SkCanvasVideoRenderer::ConvertingSize::VISUAL)
-    frame_size = video_frame->visible_rect().size();
-
   switch (video_frame->format()) {
     case PIXEL_FORMAT_YV12:
     case PIXEL_FORMAT_I420:
       if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) {
-        LIBYUV_J420_TO_ARGB(
-            FrameData(video_frame, size_type, VideoFrame::kYPlane),
-            video_frame->stride(VideoFrame::kYPlane),
-            FrameData(video_frame, size_type, VideoFrame::kUPlane),
-            video_frame->stride(VideoFrame::kUPlane),
-            FrameData(video_frame, size_type, VideoFrame::kVPlane),
-            video_frame->stride(VideoFrame::kVPlane),
-            static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-            frame_size.height());
+        LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane),
+                            video_frame->stride(VideoFrame::kYPlane),
+                            video_frame->visible_data(VideoFrame::kUPlane),
+                            video_frame->stride(VideoFrame::kUPlane),
+                            video_frame->visible_data(VideoFrame::kVPlane),
+                            video_frame->stride(VideoFrame::kVPlane),
+                            static_cast<uint8_t*>(rgb_pixels), row_bytes,
+                            video_frame->visible_rect().width(),
+                            video_frame->visible_rect().height());
       } else if (CheckColorSpace(video_frame, COLOR_SPACE_HD_REC709)) {
-        LIBYUV_H420_TO_ARGB(
-            FrameData(video_frame, size_type, VideoFrame::kYPlane),
-            video_frame->stride(VideoFrame::kYPlane),
-            FrameData(video_frame, size_type, VideoFrame::kUPlane),
-            video_frame->stride(VideoFrame::kUPlane),
-            FrameData(video_frame, size_type, VideoFrame::kVPlane),
-            video_frame->stride(VideoFrame::kVPlane),
-            static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-            frame_size.height());
+        LIBYUV_H420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane),
+                            video_frame->stride(VideoFrame::kYPlane),
+                            video_frame->visible_data(VideoFrame::kUPlane),
+                            video_frame->stride(VideoFrame::kUPlane),
+                            video_frame->visible_data(VideoFrame::kVPlane),
+                            video_frame->stride(VideoFrame::kVPlane),
+                            static_cast<uint8_t*>(rgb_pixels), row_bytes,
+                            video_frame->visible_rect().width(),
+                            video_frame->visible_rect().height());
       } else {
-        LIBYUV_I420_TO_ARGB(
-            FrameData(video_frame, size_type, VideoFrame::kYPlane),
-            video_frame->stride(VideoFrame::kYPlane),
-            FrameData(video_frame, size_type, VideoFrame::kUPlane),
-            video_frame->stride(VideoFrame::kUPlane),
-            FrameData(video_frame, size_type, VideoFrame::kVPlane),
-            video_frame->stride(VideoFrame::kVPlane),
-            static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-            frame_size.height());
+        LIBYUV_I420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane),
+                            video_frame->stride(VideoFrame::kYPlane),
+                            video_frame->visible_data(VideoFrame::kUPlane),
+                            video_frame->stride(VideoFrame::kUPlane),
+                            video_frame->visible_data(VideoFrame::kVPlane),
+                            video_frame->stride(VideoFrame::kVPlane),
+                            static_cast<uint8_t*>(rgb_pixels), row_bytes,
+                            video_frame->visible_rect().width(),
+                            video_frame->visible_rect().height());
       }
       break;
     case PIXEL_FORMAT_YV16:
-      LIBYUV_I422_TO_ARGB(
-          FrameData(video_frame, size_type, VideoFrame::kYPlane),
-          video_frame->stride(VideoFrame::kYPlane),
-          FrameData(video_frame, size_type, VideoFrame::kUPlane),
-          video_frame->stride(VideoFrame::kUPlane),
-          FrameData(video_frame, size_type, VideoFrame::kVPlane),
-          video_frame->stride(VideoFrame::kVPlane),
-          static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-          frame_size.height());
+      LIBYUV_I422_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane),
+                          video_frame->stride(VideoFrame::kYPlane),
+                          video_frame->visible_data(VideoFrame::kUPlane),
+                          video_frame->stride(VideoFrame::kUPlane),
+                          video_frame->visible_data(VideoFrame::kVPlane),
+                          video_frame->stride(VideoFrame::kVPlane),
+                          static_cast<uint8_t*>(rgb_pixels), row_bytes,
+                          video_frame->visible_rect().width(),
+                          video_frame->visible_rect().height());
       break;
 
     case PIXEL_FORMAT_YV12A:
       LIBYUV_I420ALPHA_TO_ARGB(
-          FrameData(video_frame, size_type, VideoFrame::kYPlane),
+          video_frame->visible_data(VideoFrame::kYPlane),
           video_frame->stride(VideoFrame::kYPlane),
-          FrameData(video_frame, size_type, VideoFrame::kUPlane),
+          video_frame->visible_data(VideoFrame::kUPlane),
           video_frame->stride(VideoFrame::kUPlane),
-          FrameData(video_frame, size_type, VideoFrame::kVPlane),
+          video_frame->visible_data(VideoFrame::kVPlane),
           video_frame->stride(VideoFrame::kVPlane),
-          FrameData(video_frame, size_type, VideoFrame::kAPlane),
+          video_frame->visible_data(VideoFrame::kAPlane),
           video_frame->stride(VideoFrame::kAPlane),
-          static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-          frame_size.height(),
+          static_cast<uint8_t*>(rgb_pixels), row_bytes,
+          video_frame->visible_rect().width(),
+          video_frame->visible_rect().height(),
           1);  // 1 = enable RGB premultiplication by Alpha.
       break;
 
     case PIXEL_FORMAT_YV24:
-      LIBYUV_I444_TO_ARGB(
-          FrameData(video_frame, size_type, VideoFrame::kYPlane),
-          video_frame->stride(VideoFrame::kYPlane),
-          FrameData(video_frame, size_type, VideoFrame::kUPlane),
-          video_frame->stride(VideoFrame::kUPlane),
-          FrameData(video_frame, size_type, VideoFrame::kVPlane),
-          video_frame->stride(VideoFrame::kVPlane),
-          static_cast<uint8_t*>(rgb_pixels), row_bytes, frame_size.width(),
-          frame_size.height());
+      LIBYUV_I444_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane),
+                          video_frame->stride(VideoFrame::kYPlane),
+                          video_frame->visible_data(VideoFrame::kUPlane),
+                          video_frame->stride(VideoFrame::kUPlane),
+                          video_frame->visible_data(VideoFrame::kVPlane),
+                          video_frame->stride(VideoFrame::kVPlane),
+                          static_cast<uint8_t*>(rgb_pixels), row_bytes,
+                          video_frame->visible_rect().width(),
+                          video_frame->visible_rect().height());
       break;
 
     case PIXEL_FORMAT_YUV420P9:
@@ -661,13 +642,13 @@
     case PIXEL_FORMAT_YUV444P12: {
       scoped_refptr<VideoFrame> temporary_frame =
           DownShiftHighbitVideoFrame(video_frame);
-      ConvertVideoFrameToRGBPixels(temporary_frame.get(), size_type, rgb_pixels,
+      ConvertVideoFrameToRGBPixels(temporary_frame.get(), rgb_pixels,
                                    row_bytes);
       break;
     }
 
     case PIXEL_FORMAT_Y16:
-      ConvertY16ToARGB(video_frame, size_type, rgb_pixels, row_bytes);
+      ConvertY16ToARGB(video_frame, rgb_pixels, row_bytes);
       break;
 
     case PIXEL_FORMAT_NV12:
diff --git a/media/renderers/skcanvas_video_renderer.h b/media/renderers/skcanvas_video_renderer.h
index 256e498..2740c0c 100644
--- a/media/renderers/skcanvas_video_renderer.h
+++ b/media/renderers/skcanvas_video_renderer.h
@@ -55,12 +55,10 @@
             SkCanvas* canvas,
             const Context3D& context_3d);
 
-  enum class ConvertingSize { VISUAL, CODED };
   // Convert the contents of |video_frame| to raw RGB pixels. |rgb_pixels|
   // should point into a buffer large enough to hold as many 32 bit RGBA pixels
   // as are in the visible_rect() area of the frame.
   static void ConvertVideoFrameToRGBPixels(const media::VideoFrame* video_frame,
-                                           ConvertingSize size_type,
                                            void* rgb_pixels,
                                            size_t row_bytes);
 
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLContextGroup.cpp b/third_party/WebKit/Source/modules/webgl/WebGLContextGroup.cpp
index 46ac62e..0f7d79f 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLContextGroup.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLContextGroup.cpp
@@ -30,7 +30,13 @@
 WebGLContextGroup::WebGLContextGroup() : m_numberOfContextLosses(0) {}
 
 gpu::gles2::GLES2Interface* WebGLContextGroup::getAGLInterface() {
-  ASSERT(!m_contexts.isEmpty());
+  // During an Oilpan GC where WebGL objects become unreachable at the same
+  // time the context does, the m_contexts set can be fully cleared out
+  // before WebGLObjects' destructors run. Since the calling code handles
+  // this gracefully, explicitly test for this possibility.
+  if (m_contexts.isEmpty())
+    return nullptr;
+
   // Weak processing removes dead entries from the HeapHashSet, so it's
   // guaranteed that this will not return null for the reason that a
   // WeakMember was nulled out.
diff --git a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
index 6a5716a2..99c10e6 100644
--- a/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
+++ b/third_party/WebKit/Source/platform/graphics/Canvas2DLayerBridge.cpp
@@ -433,10 +433,7 @@
     gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
   }
   mailboxInfo.m_mailbox = mailbox;
-  bool isOverlayCandidate = false;
-  bool secureOutputOnly = false;
-  *outMailbox = cc::TextureMailbox(mailbox, syncToken, GL_TEXTURE_2D, m_size,
-                                   isOverlayCandidate, secureOutputOnly);
+  *outMailbox = cc::TextureMailbox(mailbox, syncToken, GL_TEXTURE_2D);
 
   gl->BindTexture(GL_TEXTURE_2D, 0);
   // Because we are changing the texture binding without going through skia,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py
index c648dc0..b9ea558 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/wpt_github.py
@@ -4,8 +4,21 @@
 
 import base64
 import json
-import httplib2
 import logging
+import os
+import sys
+
+from webkitpy.common.system.filesystem import FileSystem
+from webkitpy.common.webkit_finder import WebKitFinder
+
+# httplib2 is part of the hermetic depot_tools install,
+# but we first need to find a path to it.
+# TODO(dglazkov): libhttp2 needs to be imported into thirdparty dir.
+# See http://crbug.com/670987 for details.
+_DEPOT_TOOLS_ROOT = WebKitFinder(FileSystem()).depot_tools_base()
+sys.path.append(os.path.join(_DEPOT_TOOLS_ROOT, 'third_party'))
+
+import httplib2
 
 _log = logging.getLogger(__name__)
 API_BASE = 'https://api.github.com'