Remove dependency on Skia from chromoting client.

Now DesktopRegion, DesktopRect and DesktopSize are used instead of
corresponding skia types.

[email protected]
[email protected] (for _moved_ skia dependency)

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=224101

Review URL: https://codereview.chromium.org/23440046

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@225265 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/remoting/DEPS b/remoting/DEPS
index 6e5ae99..66f4af9 100644
--- a/remoting/DEPS
+++ b/remoting/DEPS
@@ -15,13 +15,11 @@
   "-remoting",
   "+remoting/base",
   "+remoting/proto",
-  "+skia/config",
-  "+skia/ext",
   "+third_party/GTM",
   "+third_party/GTM/AppKit",
   "+third_party/libjingle",
   "+third_party/libvpx",
   "+third_party/libyuv",
-  "+third_party/skia/include/core",
+  "+third_party/webrtc/modules/desktop_capture",
   "+ui/base/keycodes",
 ]
diff --git a/remoting/base/util.cc b/remoting/base/util.cc
index 0a0a529..d27b651 100644
--- a/remoting/base/util.cc
+++ b/remoting/base/util.cc
@@ -12,7 +12,7 @@
 #include "media/base/video_frame.h"
 #include "media/base/yuv_convert.h"
 #include "third_party/libyuv/include/libyuv/convert.h"
-#include "third_party/skia/include/core/SkRegion.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 #if defined(OS_POSIX)
 #include <pwd.h>
@@ -73,54 +73,56 @@
                      width, height);
 }
 
-void ConvertAndScaleYUVToRGB32Rect(const uint8* source_yplane,
-                                   const uint8* source_uplane,
-                                   const uint8* source_vplane,
-                                   int source_ystride,
-                                   int source_uvstride,
-                                   const SkISize& source_size,
-                                   const SkIRect& source_buffer_rect,
-                                   uint8* dest_buffer,
-                                   int dest_stride,
-                                   const SkISize& dest_size,
-                                   const SkIRect& dest_buffer_rect,
-                                   const SkIRect& dest_rect) {
+void ConvertAndScaleYUVToRGB32Rect(
+    const uint8* source_yplane,
+    const uint8* source_uplane,
+    const uint8* source_vplane,
+    int source_ystride,
+    int source_uvstride,
+    const webrtc::DesktopSize& source_size,
+    const webrtc::DesktopRect& source_buffer_rect,
+    uint8* dest_buffer,
+    int dest_stride,
+    const webrtc::DesktopSize& dest_size,
+    const webrtc::DesktopRect& dest_buffer_rect,
+    const webrtc::DesktopRect& dest_rect) {
   // N.B. It is caller's responsibility to check if strides are large enough. We
   // cannot do it here anyway.
-  DCHECK(SkIRect::MakeSize(source_size).contains(source_buffer_rect));
-  DCHECK(SkIRect::MakeSize(dest_size).contains(dest_buffer_rect));
-  DCHECK(dest_buffer_rect.contains(dest_rect));
-  DCHECK(ScaleRect(source_buffer_rect, source_size, dest_size).
-             contains(dest_rect));
+  DCHECK(DoesRectContain(webrtc::DesktopRect::MakeSize(source_size),
+                         source_buffer_rect));
+  DCHECK(DoesRectContain(webrtc::DesktopRect::MakeSize(dest_size),
+                         dest_buffer_rect));
+  DCHECK(DoesRectContain(dest_buffer_rect, dest_rect));
+  DCHECK(DoesRectContain(ScaleRect(source_buffer_rect, source_size, dest_size),
+                         dest_rect));
 
   // If the source and/or destination buffers don't start at (0, 0)
   // offset the pointers to pretend we have complete buffers.
-  int y_offset = - CalculateYOffset(source_buffer_rect.x(),
-                                    source_buffer_rect.y(),
+  int y_offset = - CalculateYOffset(source_buffer_rect.left(),
+                                    source_buffer_rect.top(),
                                     source_ystride);
-  int uv_offset = - CalculateUVOffset(source_buffer_rect.x(),
-                                      source_buffer_rect.y(),
+  int uv_offset = - CalculateUVOffset(source_buffer_rect.left(),
+                                      source_buffer_rect.top(),
                                       source_uvstride);
-  int rgb_offset = - CalculateRGBOffset(dest_buffer_rect.x(),
-                                        dest_buffer_rect.y(),
+  int rgb_offset = - CalculateRGBOffset(dest_buffer_rect.left(),
+                                        dest_buffer_rect.top(),
                                         dest_stride);
 
   // See if scaling is needed.
-  if (source_size == dest_size) {
+  if (source_size.equals(dest_size)) {
     // Calculate the inner rectangle that can be copied by the optimized
     // libyuv::I420ToARGB().
-    SkIRect inner_rect =
-        SkIRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left() + 1),
-                          RoundToTwosMultiple(dest_rect.top() + 1),
-                          dest_rect.right(),
-                          dest_rect.bottom());
+    webrtc::DesktopRect inner_rect =
+        webrtc::DesktopRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left() + 1),
+                                      RoundToTwosMultiple(dest_rect.top() + 1),
+                                      dest_rect.right(), dest_rect.bottom());
 
     // Offset pointers to point to the top left corner of the inner rectangle.
-    y_offset += CalculateYOffset(inner_rect.x(), inner_rect.y(),
+    y_offset += CalculateYOffset(inner_rect.left(), inner_rect.top(),
                                  source_ystride);
-    uv_offset += CalculateUVOffset(inner_rect.x(), inner_rect.y(),
+    uv_offset += CalculateUVOffset(inner_rect.left(), inner_rect.top(),
                                    source_uvstride);
-    rgb_offset += CalculateRGBOffset(inner_rect.x(), inner_rect.y(),
+    rgb_offset += CalculateRGBOffset(inner_rect.left(), inner_rect.top(),
                                      dest_stride);
 
     libyuv::I420ToARGB(source_yplane + y_offset, source_ystride,
@@ -130,15 +132,14 @@
                        inner_rect.width(), inner_rect.height());
 
     // Now see if some pixels weren't copied due to alignment.
-    if (dest_rect != inner_rect) {
-      SkIRect outer_rect =
-        SkIRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left()),
-                          RoundToTwosMultiple(dest_rect.top()),
-                          dest_rect.right(),
-                          dest_rect.bottom());
+    if (!dest_rect.equals(inner_rect)) {
+      webrtc::DesktopRect outer_rect =
+          webrtc::DesktopRect::MakeLTRB(RoundToTwosMultiple(dest_rect.left()),
+                                        RoundToTwosMultiple(dest_rect.top()),
+                                        dest_rect.right(), dest_rect.bottom());
 
-      SkIPoint offset = SkIPoint::Make(outer_rect.x() - inner_rect.x(),
-                                       outer_rect.y() - inner_rect.y());
+      webrtc::DesktopVector offset(outer_rect.left() - inner_rect.left(),
+                                   outer_rect.top() - inner_rect.top());
 
       // Offset the pointers to point to the top left corner of the outer
       // rectangle.
@@ -147,11 +148,12 @@
       rgb_offset += CalculateRGBOffset(offset.x(), offset.y(), dest_stride);
 
       // Draw unaligned edges.
-      SkRegion edges(dest_rect);
-      edges.op(inner_rect, SkRegion::kDifference_Op);
-      for (SkRegion::Iterator i(edges); !i.done(); i.next()) {
-        SkIRect rect(i.rect());
-        rect.offset(- outer_rect.left(), - outer_rect.top());
+      webrtc::DesktopRegion edges(dest_rect);
+      edges.Subtract(inner_rect);
+      for (webrtc::DesktopRegion::Iterator i(edges); !i.IsAtEnd();
+           i.Advance()) {
+        webrtc::DesktopRect rect = i.rect();
+        rect.Translate(-outer_rect.left(), -outer_rect.top());
         media::ScaleYUVToRGB32WithRect(source_yplane + y_offset,
                                        source_uplane + uv_offset,
                                        source_vplane + uv_offset,
@@ -192,43 +194,45 @@
   return x & (~1);
 }
 
-SkIRect AlignRect(const SkIRect& rect) {
+webrtc::DesktopRect AlignRect(const webrtc::DesktopRect& rect) {
   int x = RoundToTwosMultiple(rect.left());
   int y = RoundToTwosMultiple(rect.top());
   int right = RoundToTwosMultiple(rect.right() + 1);
   int bottom = RoundToTwosMultiple(rect.bottom() + 1);
-  return SkIRect::MakeLTRB(x, y, right, bottom);
+  return webrtc::DesktopRect::MakeLTRB(x, y, right, bottom);
 }
 
-SkIRect ScaleRect(const SkIRect& rect,
-                  const SkISize& in_size,
-                  const SkISize& out_size) {
+webrtc::DesktopRect ScaleRect(const webrtc::DesktopRect& rect,
+                              const webrtc::DesktopSize& in_size,
+                              const webrtc::DesktopSize& out_size) {
   int left = (rect.left() * out_size.width()) / in_size.width();
   int top = (rect.top() * out_size.height()) / in_size.height();
   int right = (rect.right() * out_size.width() + in_size.width() - 1) /
       in_size.width();
   int bottom = (rect.bottom() * out_size.height() + in_size.height() - 1) /
       in_size.height();
-  return SkIRect::MakeLTRB(left, top, right, bottom);
+  return webrtc::DesktopRect::MakeLTRB(left, top, right, bottom);
 }
 
 void CopyRGB32Rect(const uint8* source_buffer,
                    int source_stride,
-                   const SkIRect& source_buffer_rect,
+                   const webrtc::DesktopRect& source_buffer_rect,
                    uint8* dest_buffer,
                    int dest_stride,
-                   const SkIRect& dest_buffer_rect,
-                   const SkIRect& dest_rect) {
-  DCHECK(dest_buffer_rect.contains(dest_rect));
-  DCHECK(source_buffer_rect.contains(dest_rect));
+                   const webrtc::DesktopRect& dest_buffer_rect,
+                   const webrtc::DesktopRect& dest_rect) {
+  DCHECK(DoesRectContain(dest_buffer_rect, dest_rect));
+  DCHECK(DoesRectContain(source_buffer_rect, dest_rect));
 
   // Get the address of the starting point.
-  source_buffer += CalculateRGBOffset(dest_rect.x() - source_buffer_rect.x(),
-                                      dest_rect.y() - source_buffer_rect.y(),
-                                      source_stride);
-  dest_buffer += CalculateRGBOffset(dest_rect.x() - dest_buffer_rect.x(),
-                                    dest_rect.y() - dest_buffer_rect.y(),
-                                    source_stride);
+  source_buffer += CalculateRGBOffset(
+      dest_rect.left() - source_buffer_rect.left(),
+      dest_rect.top() - source_buffer_rect.top(),
+      source_stride);
+  dest_buffer += CalculateRGBOffset(
+      dest_rect.left() - dest_buffer_rect.left(),
+      dest_rect.top() - dest_buffer_rect.top(),
+      source_stride);
 
   // Copy pixels in the rectangle line by line.
   const int bytes_per_line = kBytesPerPixelRGB32 * dest_rect.width();
@@ -328,4 +332,11 @@
 #endif  // defined(OS_POSIX)
 }
 
+bool DoesRectContain(const webrtc::DesktopRect& a,
+                     const webrtc::DesktopRect& b) {
+  webrtc::DesktopRect intersection(a);
+  intersection.IntersectWith(b);
+  return intersection.equals(b);
+}
+
 }  // namespace remoting
diff --git a/remoting/base/util.h b/remoting/base/util.h
index 8f70005b..5478c7f 100644
--- a/remoting/base/util.h
+++ b/remoting/base/util.h
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "media/base/video_frame.h"
-#include "third_party/skia/include/core/SkRect.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 namespace remoting {
 
@@ -36,18 +36,19 @@
 //
 // N.B. The top left corner coordinates of YUV buffer should have even X and Y
 // coordinates.
-void ConvertAndScaleYUVToRGB32Rect(const uint8* source_yplane,
-                                   const uint8* source_uplane,
-                                   const uint8* source_vplane,
-                                   int source_ystride,
-                                   int source_uvstride,
-                                   const SkISize& source_size,
-                                   const SkIRect& source_buffer_rect,
-                                   uint8* dest_buffer,
-                                   int dest_stride,
-                                   const SkISize& dest_size,
-                                   const SkIRect& dest_buffer_rect,
-                                   const SkIRect& dest_rect);
+void ConvertAndScaleYUVToRGB32Rect(
+    const uint8* source_yplane,
+    const uint8* source_uplane,
+    const uint8* source_vplane,
+    int source_ystride,
+    int source_uvstride,
+    const webrtc::DesktopSize& source_size,
+    const webrtc::DesktopRect& source_buffer_rect,
+    uint8* dest_buffer,
+    int dest_stride,
+    const webrtc::DesktopSize& dest_size,
+    const webrtc::DesktopRect& dest_buffer_rect,
+    const webrtc::DesktopRect& dest_rect);
 
 // Convert RGB32 to YUV on a specific rectangle.
 void ConvertRGB32ToYUVWithRect(const uint8* rgb_plane,
@@ -65,23 +66,23 @@
 int RoundToTwosMultiple(int x);
 
 // Align the sides of the rectangle to multiples of 2 (expanding outwards).
-SkIRect AlignRect(const SkIRect& rect);
+webrtc::DesktopRect AlignRect(const webrtc::DesktopRect& rect);
 
 // Scales the supplied rectangle from |in_size| coordinates to |out_size|.
 // If the result has non-integer coordinates then the smallest integer-
 // coordinate rectangle that wholly encloses it is returned.
-SkIRect ScaleRect(const SkIRect& rect,
-                  const SkISize& in_size,
-                  const SkISize& out_size);
+webrtc::DesktopRect ScaleRect(const webrtc::DesktopRect& rect,
+                              const webrtc::DesktopSize& in_size,
+                              const webrtc::DesktopSize& out_size);
 
 // Copy content of a rectangle in a RGB32 image.
 void CopyRGB32Rect(const uint8* source_buffer,
                    int source_stride,
-                   const SkIRect& source_buffer_rect,
+                   const webrtc::DesktopRect& source_buffer_rect,
                    uint8* dest_buffer,
                    int dest_stride,
-                   const SkIRect& dest_buffer_rect,
-                   const SkIRect& dest_rect);
+                   const webrtc::DesktopRect& dest_buffer_rect,
+                   const webrtc::DesktopRect& dest_rect);
 
 // Replaces every occurrence of "\n" in a string by "\r\n".
 std::string ReplaceLfByCrLf(const std::string& in);
@@ -96,6 +97,9 @@
 // error or if not implemented.
 std::string GetUsername();
 
+bool DoesRectContain(const webrtc::DesktopRect& a,
+                     const webrtc::DesktopRect& b);
+
 }  // namespace remoting
 
 #endif  // REMOTING_BASE_UTIL_H_
diff --git a/remoting/base/util_unittest.cc b/remoting/base/util_unittest.cc
index a269c07..1dad9aa 100644
--- a/remoting/base/util_unittest.cc
+++ b/remoting/base/util_unittest.cc
@@ -6,8 +6,7 @@
 
 #include "remoting/base/util.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkSize.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 static const int kWidth = 32 ;
 static const int kHeight = 24 ;
@@ -45,7 +44,7 @@
     memset(rgb_buffer_.get(), 0, rgb_buffer_size_);
   }
 
-  void FillRgbBuffer(const SkIRect& rect) {
+  void FillRgbBuffer(const webrtc::DesktopRect& rect) {
     uint32* ptr = reinterpret_cast<uint32*>(
         rgb_buffer_.get() + (rect.top() * kRgbStride) +
         (rect.left() * kBytesPerPixel));
@@ -57,7 +56,7 @@
   }
 
   // Check the the desination buffer is filled within expected bounds.
-  void  CheckRgbBuffer(const SkIRect& rect) {
+  void  CheckRgbBuffer(const webrtc::DesktopRect& rect) {
     uint32* ptr = reinterpret_cast<uint32*>(rgb_buffer_.get());
     for (int y = 0; y < kHeight; ++y) {
       if (y < rect.top() || rect.bottom() <= y) {
@@ -81,8 +80,10 @@
     }
   }
 
-  void RunTest(const SkISize dest_size, const SkIRect& rect) {
-    ASSERT_TRUE(SkIRect::MakeSize(dest_size).contains(rect));
+  void RunTest(const webrtc::DesktopSize dest_size,
+               const webrtc::DesktopRect& rect) {
+    ASSERT_TRUE(
+        DoesRectContain(webrtc::DesktopRect::MakeSize(dest_size), rect));
 
     // Reset buffers.
     ResetYuvBuffer();
@@ -109,12 +110,12 @@
                                   vplane_,
                                   kYStride,
                                   kUvStride,
-                                  SkISize::Make(kWidth, kHeight),
-                                  SkIRect::MakeWH(kWidth, kHeight),
+                                  webrtc::DesktopSize(kWidth, kHeight),
+                                  webrtc::DesktopRect::MakeWH(kWidth, kHeight),
                                   rgb_buffer_.get(),
                                   kRgbStride,
                                   dest_size,
-                                  SkIRect::MakeSize(dest_size),
+                                  webrtc::DesktopRect::MakeSize(dest_size),
                                   rect);
 
     // Check if it worked out.
@@ -123,7 +124,8 @@
 
   void TestBasicConversion() {
     // Whole buffer.
-    RunTest(SkISize::Make(kWidth, kHeight), SkIRect::MakeWH(kWidth, kHeight));
+    RunTest(webrtc::DesktopSize(kWidth, kHeight),
+            webrtc::DesktopRect::MakeWH(kWidth, kHeight));
   }
 
  private:
@@ -147,18 +149,15 @@
 TEST(YuvToRgbTest, Clipping) {
   YuvToRgbTester tester;
 
-  SkISize dest_size = SkISize::Make(kWidth, kHeight);
-  SkIRect rect = SkIRect::MakeLTRB(0, 0, kWidth - 1, kHeight - 1);
+  webrtc::DesktopSize dest_size = webrtc::DesktopSize(kWidth, kHeight);
+  webrtc::DesktopRect rect =
+      webrtc::DesktopRect::MakeLTRB(0, 0, kWidth - 1, kHeight - 1);
   for (int i = 0; i < 16; ++i) {
-    SkIRect dest_rect = rect;
-    if ((i & 1) != 0)
-      dest_rect.fLeft += 1;
-    if ((i & 2) != 0)
-      dest_rect.fTop += 1;
-    if ((i & 4) != 0)
-      dest_rect.fRight += 1;
-    if ((i & 8) != 0)
-      dest_rect.fBottom += 1;
+    webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB(
+        rect.left() + ((i & 1) ? 1 : 0),
+        rect.top() + ((i & 2) ? 1 : 0),
+        rect.right() + ((i & 4) ? 1 : 0),
+        rect.bottom() + ((i & 8) ? 1 : 0));
 
     tester.RunTest(dest_size, dest_rect);
   }
@@ -167,18 +166,16 @@
 TEST(YuvToRgbTest, ClippingAndScaling) {
   YuvToRgbTester tester;
 
-  SkISize dest_size = SkISize::Make(kWidth - 10, kHeight - 10);
-  SkIRect rect = SkIRect::MakeLTRB(5, 5, kWidth - 11, kHeight - 11);
+  webrtc::DesktopSize dest_size =
+      webrtc::DesktopSize(kWidth - 10, kHeight - 10);
+  webrtc::DesktopRect rect =
+      webrtc::DesktopRect::MakeLTRB(5, 5, kWidth - 11, kHeight - 11);
   for (int i = 0; i < 16; ++i) {
-    SkIRect dest_rect = rect;
-    if ((i & 1) != 0)
-      dest_rect.fLeft += 1;
-    if ((i & 2) != 0)
-      dest_rect.fTop += 1;
-    if ((i & 4) != 0)
-      dest_rect.fRight += 1;
-    if ((i & 8) != 0)
-      dest_rect.fBottom += 1;
+    webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB(
+        rect.left() + ((i & 1) ? 1 : 0),
+        rect.top() + ((i & 2) ? 1 : 0),
+        rect.right() + ((i & 4) ? 1 : 0),
+        rect.bottom() + ((i & 8) ? 1 : 0));
 
     tester.RunTest(dest_size, dest_rect);
   }
diff --git a/remoting/client/DEPS b/remoting/client/DEPS
index 4b52eec..235d972e 100644
--- a/remoting/client/DEPS
+++ b/remoting/client/DEPS
@@ -2,7 +2,6 @@
   "+ppapi",
   "+jingle/glue",
   "+net",
-  "+third_party/webrtc",
 
   "+remoting/codec",
   "+remoting/protocol",
diff --git a/remoting/client/frame_consumer.h b/remoting/client/frame_consumer.h
index b5f937ca..4df7595 100644
--- a/remoting/client/frame_consumer.h
+++ b/remoting/client/frame_consumer.h
@@ -6,12 +6,13 @@
 #define REMOTING_CLIENT_FRAME_CONSUMER_H_
 
 #include "base/basictypes.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/skia/include/core/SkSize.h"
 
 namespace webrtc {
 class DesktopFrame;
+class DesktopRect;
+class DesktopRegion;
+class DesktopSize;
+class DesktopVector;
 }  // namespace webrtc
 
 namespace remoting {
@@ -26,10 +27,10 @@
   //
   // N.B. Both |clip_area| and |region| are in output coordinates relative to
   // the frame.
-  virtual void ApplyBuffer(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void ApplyBuffer(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            webrtc::DesktopFrame* buffer,
-                           const SkRegion& region) = 0;
+                           const webrtc::DesktopRegion& region) = 0;
 
   // Accepts a buffer that couldn't be used for drawing for any reason (shutdown
   // is in progress, the view area has changed, etc.). The accepted buffer can
@@ -37,8 +38,8 @@
   virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) = 0;
 
   // Set the dimension of the entire host screen.
-  virtual void SetSourceSize(const SkISize& source_size,
-                             const SkIPoint& dpi) = 0;
+  virtual void SetSourceSize(const webrtc::DesktopSize& source_size,
+                             const webrtc::DesktopVector& dpi) = 0;
 
  protected:
   FrameConsumer() {}
diff --git a/remoting/client/frame_consumer_proxy.cc b/remoting/client/frame_consumer_proxy.cc
index 070130c..4c7d79f5 100644
--- a/remoting/client/frame_consumer_proxy.cc
+++ b/remoting/client/frame_consumer_proxy.cc
@@ -8,6 +8,8 @@
 #include "base/location.h"
 #include "base/single_thread_task_runner.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 namespace remoting {
 
@@ -16,10 +18,10 @@
     : task_runner_(task_runner) {
 }
 
-void FrameConsumerProxy::ApplyBuffer(const SkISize& view_size,
-                                     const SkIRect& clip_area,
+void FrameConsumerProxy::ApplyBuffer(const webrtc::DesktopSize& view_size,
+                                     const webrtc::DesktopRect& clip_area,
                                      webrtc::DesktopFrame* buffer,
-                                     const SkRegion& region) {
+                                     const webrtc::DesktopRegion& region) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(FROM_HERE, base::Bind(
         &FrameConsumerProxy::ApplyBuffer, this,
@@ -42,8 +44,9 @@
     frame_consumer_->ReturnBuffer(buffer);
 }
 
-void FrameConsumerProxy::SetSourceSize(const SkISize& source_size,
-                                       const SkIPoint& source_dpi) {
+void FrameConsumerProxy::SetSourceSize(
+    const webrtc::DesktopSize& source_size,
+    const webrtc::DesktopVector& source_dpi) {
   if (!task_runner_->BelongsToCurrentThread()) {
     task_runner_->PostTask(FROM_HERE, base::Bind(
         &FrameConsumerProxy::SetSourceSize, this, source_size, source_dpi));
diff --git a/remoting/client/frame_consumer_proxy.h b/remoting/client/frame_consumer_proxy.h
index e39d1561..21e8fe48 100644
--- a/remoting/client/frame_consumer_proxy.h
+++ b/remoting/client/frame_consumer_proxy.h
@@ -29,13 +29,13 @@
   FrameConsumerProxy(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   // FrameConsumer implementation.
-  virtual void ApplyBuffer(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void ApplyBuffer(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            webrtc::DesktopFrame* buffer,
-                           const SkRegion& region) OVERRIDE;
+                           const webrtc::DesktopRegion& region) OVERRIDE;
   virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) OVERRIDE;
-  virtual void SetSourceSize(const SkISize& source_size,
-                             const SkIPoint& dpi) OVERRIDE;
+  virtual void SetSourceSize(const webrtc::DesktopSize& source_size,
+                             const webrtc::DesktopVector& dpi) OVERRIDE;
 
   // Attaches to |frame_consumer_|.
   // This must only be called from |frame_consumer_message_loop_|.
diff --git a/remoting/client/frame_producer.h b/remoting/client/frame_producer.h
index 14bf283f..aa7e63de 100644
--- a/remoting/client/frame_producer.h
+++ b/remoting/client/frame_producer.h
@@ -6,12 +6,12 @@
 #define REMOTING_CLIENT_FRAME_PRODUCER_H_
 
 #include "base/callback_forward.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/skia/include/core/SkSize.h"
 
 namespace webrtc {
 class DesktopFrame;
+class DesktopRect;
+class DesktopRegion;
+class DesktopSize;
 }  // namespace webrtc
 
 namespace remoting {
@@ -31,7 +31,7 @@
   // Requests repainting of the specified |region| of the frame as soon as
   // possible. |region| is specified in output coordinates relative to
   // the beginning of the frame.
-  virtual void InvalidateRegion(const SkRegion& region) = 0;
+  virtual void InvalidateRegion(const webrtc::DesktopRegion& region) = 0;
 
   // Requests returing of all pending buffers to the consumer via
   // FrameConsumer::ReturnBuffer() calls.
@@ -39,11 +39,11 @@
 
   // Notifies the producer of changes to the output view size or clipping area.
   // Implementations must cope with empty |view_size| or |clip_area|.
-  virtual void SetOutputSizeAndClip(const SkISize& view_size,
-                                    const SkIRect& clip_area) = 0;
+  virtual void SetOutputSizeAndClip(const webrtc::DesktopSize& view_size,
+                                    const webrtc::DesktopRect& clip_area) = 0;
 
   // Returns a reference to the shape of the most recently drawn buffer.
-  virtual const SkRegion* GetBufferShape() = 0;
+  virtual const webrtc::DesktopRegion* GetBufferShape() = 0;
 
  protected:
   virtual ~FrameProducer() {}
diff --git a/remoting/client/jni/jni_frame_consumer.cc b/remoting/client/jni/jni_frame_consumer.cc
index 8f8cfc6..3b4e763c 100644
--- a/remoting/client/jni/jni_frame_consumer.cc
+++ b/remoting/client/jni/jni_frame_consumer.cc
@@ -10,6 +10,7 @@
 #include "remoting/client/frame_producer.h"
 #include "remoting/client/jni/chromoting_jni_runtime.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 namespace {
 
@@ -62,10 +63,10 @@
   frame_producer_ = producer;
 }
 
-void JniFrameConsumer::ApplyBuffer(const SkISize& view_size,
-                                   const SkIRect& clip_area,
+void JniFrameConsumer::ApplyBuffer(const webrtc::DesktopSize& view_size,
+                                   const webrtc::DesktopRect& clip_area,
                                    webrtc::DesktopFrame* buffer,
-                                   const SkRegion& region) {
+                                   const webrtc::DesktopRegion& region) {
   DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
 
   scoped_ptr<webrtc::DesktopFrame> buffer_scoped(buffer);
@@ -93,14 +94,14 @@
   delete buffer;
 }
 
-void JniFrameConsumer::SetSourceSize(const SkISize& source_size,
-                                     const SkIPoint& dpi) {
+void JniFrameConsumer::SetSourceSize(const webrtc::DesktopSize& source_size,
+                                     const webrtc::DesktopVector& dpi) {
   DCHECK(jni_runtime_->display_task_runner()->BelongsToCurrentThread());
 
   // We currently render the desktop 1:1 and perform pan/zoom scaling
   // and cropping on the managed canvas.
   view_size_ = source_size;
-  clip_area_ = SkIRect::MakeSize(view_size_);
+  clip_area_ = webrtc::DesktopRect::MakeSize(view_size_);
   frame_producer_->SetOutputSizeAndClip(view_size_, clip_area_);
 
   // Unless being destructed, allocate buffer and start drawing frames onto it.
@@ -123,8 +124,8 @@
 
     // Update Java's reference to the buffer and record of its dimensions.
     jni_runtime_->UpdateImageBuffer(view_size_.width(),
-                                        view_size_.height(),
-                                        buffer->buffer());
+                                    view_size_.height(),
+                                    buffer->buffer());
 
     frame_producer_->DrawBuffer(buffer);
   }
diff --git a/remoting/client/jni/jni_frame_consumer.h b/remoting/client/jni/jni_frame_consumer.h
index 38ff86c..14155a1 100644
--- a/remoting/client/jni/jni_frame_consumer.h
+++ b/remoting/client/jni/jni_frame_consumer.h
@@ -8,6 +8,7 @@
 #include "remoting/client/frame_consumer.h"
 
 #include "base/compiler_specific.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 namespace webrtc {
 class DesktopFrame;
@@ -29,13 +30,13 @@
   void set_frame_producer(FrameProducer* producer);
 
   // FrameConsumer implementation.
-  virtual void ApplyBuffer(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void ApplyBuffer(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            webrtc::DesktopFrame* buffer,
-                           const SkRegion& region) OVERRIDE;
+                           const webrtc::DesktopRegion& region) OVERRIDE;
   virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) OVERRIDE;
-  virtual void SetSourceSize(const SkISize& source_size,
-                             const SkIPoint& dpi) OVERRIDE;
+  virtual void SetSourceSize(const webrtc::DesktopSize& source_size,
+                             const webrtc::DesktopVector& dpi) OVERRIDE;
 
  private:
   // Variables are to be used from the display thread.
@@ -48,8 +49,8 @@
   bool in_dtor_;
 
   FrameProducer* frame_producer_;
-  SkISize view_size_;
-  SkIRect clip_area_;
+  webrtc::DesktopSize view_size_;
+  webrtc::DesktopRect clip_area_;
 
   // If |provide_buffer_|, allocates a new buffer of |view_size_|, informs
   // Java about it, and tells the producer to draw onto it. Otherwise, no-op.
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 066d1329..6cecbaa 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -351,8 +351,8 @@
   return input_handler_.HandleInputEvent(event);
 }
 
-void ChromotingInstance::SetDesktopSize(const SkISize& size,
-                                        const SkIPoint& dpi) {
+void ChromotingInstance::SetDesktopSize(const webrtc::DesktopSize& size,
+                                        const webrtc::DesktopVector& dpi) {
   mouse_input_filter_.set_output_size(size);
 
   scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue());
@@ -365,18 +365,18 @@
   PostChromotingMessage("onDesktopSize", data.Pass());
 }
 
-void ChromotingInstance::SetDesktopShape(const SkRegion& shape) {
-  if (desktop_shape_ && shape == *desktop_shape_)
+void ChromotingInstance::SetDesktopShape(const webrtc::DesktopRegion& shape) {
+  if (desktop_shape_ && shape.Equals(*desktop_shape_))
     return;
 
-  desktop_shape_.reset(new SkRegion(shape));
+  desktop_shape_.reset(new webrtc::DesktopRegion(shape));
 
   scoped_ptr<base::ListValue> rects_value(new base::ListValue());
-  for (SkRegion::Iterator i(shape); !i.done(); i.next()) {
-    SkIRect rect = i.rect();
+  for (webrtc::DesktopRegion::Iterator i(shape); !i.IsAtEnd(); i.Advance()) {
+    const webrtc::DesktopRect& rect = i.rect();
     scoped_ptr<base::ListValue> rect_value(new base::ListValue());
-    rect_value->AppendInteger(rect.x());
-    rect_value->AppendInteger(rect.y());
+    rect_value->AppendInteger(rect.left());
+    rect_value->AppendInteger(rect.top());
     rect_value->AppendInteger(rect.width());
     rect_value->AppendInteger(rect.height());
     rects_value->Append(rect_value.release());
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 227bcac08..7b120a85 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -33,9 +33,6 @@
 #include "remoting/protocol/mouse_input_filter.h"
 #include "remoting/protocol/negotiating_client_authenticator.h"
 #include "remoting/protocol/third_party_client_authenticator.h"
-#include "third_party/skia/include/core/SkPoint.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/skia/include/core/SkSize.h"
 
 namespace base {
 class DictionaryValue;
@@ -46,6 +43,12 @@
 class Module;
 }  // namespace pp
 
+namespace webrtc {
+class DesktopRegion;
+class DesktopSize;
+class DesktopVector;
+}  // namespace webrtc
+
 namespace remoting {
 
 class ChromotingClient;
@@ -132,8 +135,9 @@
       const protocol::CursorShapeInfo& cursor_shape) OVERRIDE;
 
   // Called by PepperView.
-  void SetDesktopSize(const SkISize& size, const SkIPoint& dpi);
-  void SetDesktopShape(const SkRegion& shape);
+  void SetDesktopSize(const webrtc::DesktopSize& size,
+                      const webrtc::DesktopVector& dpi);
+  void SetDesktopShape(const webrtc::DesktopRegion& shape);
   void OnFirstFrameReceived();
 
   // Return statistics record by ChromotingClient.
@@ -239,7 +243,7 @@
   pp::View plugin_view_;
 
   // Contains the most-recently-reported desktop shape, if any.
-  scoped_ptr<SkRegion> desktop_shape_;
+  scoped_ptr<webrtc::DesktopRegion> desktop_shape_;
 
   scoped_ptr<DelegatingSignalStrategy> signal_strategy_;
 
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc
index c412316..a0f6ac4b 100644
--- a/remoting/client/plugin/pepper_view.cc
+++ b/remoting/client/plugin/pepper_view.cc
@@ -67,14 +67,8 @@
     context_(context),
     producer_(producer),
     merge_buffer_(NULL),
-    merge_clip_area_(SkIRect::MakeEmpty()),
-    dips_size_(SkISize::Make(0, 0)),
     dips_to_device_scale_(1.0f),
-    view_size_(SkISize::Make(0, 0)),
     dips_to_view_scale_(1.0f),
-    clip_area_(SkIRect::MakeEmpty()),
-    source_size_(SkISize::Make(0, 0)),
-    source_dpi_(SkIPoint::Make(0, 0)),
     flush_pending_(false),
     is_initialized_(false),
     frame_received_(false),
@@ -101,10 +95,10 @@
   bool view_changed = false;
 
   pp::Rect pp_size = view.GetRect();
-  SkISize new_dips_size = SkISize::Make(pp_size.width(), pp_size.height());
+  webrtc::DesktopSize new_dips_size(pp_size.width(), pp_size.height());
   float new_dips_to_device_scale = view.GetDeviceScale();
 
-  if (dips_size_ != new_dips_size ||
+  if (!dips_size_.equals(new_dips_size) ||
       dips_to_device_scale_ != new_dips_to_device_scale) {
     view_changed = true;
     dips_to_device_scale_ = new_dips_to_device_scale;
@@ -120,11 +114,10 @@
 
     // If the view's DIP dimensions don't match the source then let the frame
     // producer do the scaling, and render at device resolution.
-    if (dips_size_ != source_size_) {
+    if (!dips_size_.equals(source_size_)) {
       dips_to_view_scale_ = dips_to_device_scale_;
-      view_size_ = SkISize::Make(
-          ceilf(dips_size_.width() * dips_to_view_scale_),
-          ceilf(dips_size_.height() * dips_to_view_scale_));
+      view_size_.set(ceilf(dips_size_.width() * dips_to_view_scale_),
+                     ceilf(dips_size_.height() * dips_to_view_scale_));
     }
 
     // Create a 2D rendering context at the chosen frame dimensions.
@@ -141,18 +134,18 @@
   }
 
   pp::Rect pp_clip = view.GetClipRect();
-  SkIRect new_clip = SkIRect::MakeLTRB(
+  webrtc::DesktopRect new_clip = webrtc::DesktopRect::MakeLTRB(
       floorf(pp_clip.x() * dips_to_view_scale_),
       floorf(pp_clip.y() * dips_to_view_scale_),
       ceilf(pp_clip.right() * dips_to_view_scale_),
       ceilf(pp_clip.bottom() * dips_to_view_scale_));
-  if (clip_area_ != new_clip) {
+  if (!clip_area_.equals(new_clip)) {
     view_changed = true;
 
     // YUV to RGB conversion may require even X and Y coordinates for
     // the top left corner of the clipping area.
     clip_area_ = AlignRect(new_clip);
-    clip_area_.intersect(SkIRect::MakeSize(view_size_));
+    clip_area_.IntersectWith(webrtc::DesktopRect::MakeSize(view_size_));
   }
 
   if (view_changed) {
@@ -161,10 +154,10 @@
   }
 }
 
-void PepperView::ApplyBuffer(const SkISize& view_size,
-                             const SkIRect& clip_area,
+void PepperView::ApplyBuffer(const webrtc::DesktopSize& view_size,
+                             const webrtc::DesktopRect& clip_area,
                              webrtc::DesktopFrame* buffer,
-                             const SkRegion& region) {
+                             const webrtc::DesktopRegion& region) {
   DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
 
   if (!frame_received_) {
@@ -176,7 +169,7 @@
   // TODO(alexeypa): We could rescale and draw it (or even draw it without
   // rescaling) to reduce the perceived lag while we are waiting for
   // the properly scaled data.
-  if (view_size_ != view_size) {
+  if (!view_size_.equals(view_size)) {
     FreeBuffer(buffer);
     InitiateDrawing();
   } else {
@@ -198,11 +191,11 @@
   }
 }
 
-void PepperView::SetSourceSize(const SkISize& source_size,
-                               const SkIPoint& source_dpi) {
+void PepperView::SetSourceSize(const webrtc::DesktopSize& source_size,
+                               const webrtc::DesktopVector& source_dpi) {
   DCHECK(context_->main_task_runner()->BelongsToCurrentThread());
 
-  if (source_size_ == source_size && source_dpi_ == source_dpi)
+  if (source_size_.equals(source_size) && source_dpi_.equals(source_dpi))
     return;
 
   source_size_ = source_size;
@@ -250,9 +243,9 @@
   }
 }
 
-void PepperView::FlushBuffer(const SkIRect& clip_area,
+void PepperView::FlushBuffer(const webrtc::DesktopRect& clip_area,
                              webrtc::DesktopFrame* buffer,
-                             const SkRegion& region) {
+                             const webrtc::DesktopRegion& region) {
   // Defer drawing if the flush is already in progress.
   if (flush_pending_) {
     // |merge_buffer_| is guaranteed to be free here because we allocate only
@@ -269,16 +262,17 @@
   // Notify Pepper API about the updated areas and flush pixels to the screen.
   base::Time start_time = base::Time::Now();
 
-  for (SkRegion::Iterator i(region); !i.done(); i.next()) {
-    SkIRect rect = i.rect();
+  for (webrtc::DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
+    webrtc::DesktopRect rect = i.rect();
 
     // Re-clip |region| with the current clipping area |clip_area_| because
     // the latter could change from the time the buffer was drawn.
-    if (!rect.intersect(clip_area_))
+    rect.IntersectWith(clip_area_);
+    if (rect.is_empty())
       continue;
 
     // Specify the rectangle coordinates relative to the clipping area.
-    rect.offset(-clip_area.left(), -clip_area.top());
+    rect.Translate(-clip_area.left(), -clip_area.top());
 
     // Pepper Graphics 2D has a strange and badly documented API that the
     // point here is the offset from the source rect. Why?
@@ -290,10 +284,10 @@
 
   // Notify the producer that some parts of the region weren't painted because
   // the clipping area has changed already.
-  if (clip_area != clip_area_) {
-    SkRegion not_painted = region;
-    not_painted.op(clip_area_, SkRegion::kDifference_Op);
-    if (!not_painted.isEmpty()) {
+  if (!clip_area.equals(clip_area_)) {
+    webrtc::DesktopRegion not_painted = region;
+    not_painted.Subtract(clip_area_);
+    if (!not_painted.is_empty()) {
       producer_->InvalidateRegion(not_painted);
     }
   }
@@ -308,7 +302,7 @@
   flush_pending_ = true;
 
   // If the buffer we just rendered has a shape then pass that to JavaScript.
-  const SkRegion* buffer_shape = producer_->GetBufferShape();
+  const webrtc::DesktopRegion* buffer_shape = producer_->GetBufferShape();
   if (buffer_shape)
     instance_->SetDesktopShape(*buffer_shape);
 }
diff --git a/remoting/client/plugin/pepper_view.h b/remoting/client/plugin/pepper_view.h
index 4848a8e..4027b620 100644
--- a/remoting/client/plugin/pepper_view.h
+++ b/remoting/client/plugin/pepper_view.h
@@ -16,6 +16,8 @@
 #include "ppapi/cpp/point.h"
 #include "ppapi/utility/completion_callback_factory.h"
 #include "remoting/client/frame_consumer.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 namespace base {
 class Time;
@@ -41,26 +43,26 @@
   virtual ~PepperView();
 
   // FrameConsumer implementation.
-  virtual void ApplyBuffer(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void ApplyBuffer(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            webrtc::DesktopFrame* buffer,
-                           const SkRegion& region) OVERRIDE;
+                           const webrtc::DesktopRegion& region) OVERRIDE;
   virtual void ReturnBuffer(webrtc::DesktopFrame* buffer) OVERRIDE;
-  virtual void SetSourceSize(const SkISize& source_size,
-                             const SkIPoint& dpi) OVERRIDE;
+  virtual void SetSourceSize(const webrtc::DesktopSize& source_size,
+                             const webrtc::DesktopVector& dpi) OVERRIDE;
 
   // Updates the PepperView's size & clipping area, taking into account the
   // DIP-to-device scale factor.
   void SetView(const pp::View& view);
 
   // Returns the dimensions of the most recently displayed frame, in pixels.
-  const SkISize& get_source_size() const {
+  const webrtc::DesktopSize& get_source_size() const {
     return source_size_;
   }
 
   // Return the dimensions of the view in Density Independent Pixels (DIPs).
   // Note that there may be multiple device pixels per DIP.
-  const SkISize& get_view_size_dips() const {
+  const webrtc::DesktopSize& get_view_size_dips() const {
     return dips_size_;
   }
 
@@ -80,9 +82,9 @@
   // clip area of the view has changed since the buffer was generated then
   // FrameProducer is supplied the missed parts of |region|.  The FrameProducer
   // will be supplied a new buffer when FlushBuffer() completes.
-  void FlushBuffer(const SkIRect& clip_area,
+  void FlushBuffer(const webrtc::DesktopRect& clip_area,
                    webrtc::DesktopFrame* buffer,
-                   const SkRegion& region);
+                   const webrtc::DesktopRegion& region);
 
   // Handles completion of FlushBuffer(), triggering a new buffer to be
   // returned to FrameProducer for rendering.
@@ -107,11 +109,11 @@
 
   // Queued buffer to paint, with clip area and dirty region in device pixels.
   webrtc::DesktopFrame* merge_buffer_;
-  SkIRect merge_clip_area_;
-  SkRegion merge_region_;
+  webrtc::DesktopRect merge_clip_area_;
+  webrtc::DesktopRegion merge_region_;
 
   // View size in Density Independent Pixels (DIPs).
-  SkISize dips_size_;
+  webrtc::DesktopSize dips_size_;
 
   // Scale factor from DIPs to device pixels.
   float dips_to_device_scale_;
@@ -119,19 +121,19 @@
   // View size in output pixels. This is the size at which FrameProducer must
   // render frames. It usually matches the DIPs size of the view, but may match
   // the size in device pixels when scaling is in effect, to reduce artefacts.
-  SkISize view_size_;
+  webrtc::DesktopSize view_size_;
 
   // Scale factor from output pixels to device pixels.
   float dips_to_view_scale_;
 
   // Visible area of the view, in output pixels.
-  SkIRect clip_area_;
+  webrtc::DesktopRect clip_area_;
 
   // Size of the most recent source frame in pixels.
-  SkISize source_size_;
+  webrtc::DesktopSize source_size_;
 
   // Resolution of the most recent source frame dots-per-inch.
-  SkIPoint source_dpi_;
+  webrtc::DesktopVector source_dpi_;
 
   // True if there is already a Flush() pending on the Graphics2D context.
   bool flush_pending_;
diff --git a/remoting/client/rectangle_update_decoder.cc b/remoting/client/rectangle_update_decoder.cc
index 3f21a99..af123e85 100644
--- a/remoting/client/rectangle_update_decoder.cc
+++ b/remoting/client/rectangle_update_decoder.cc
@@ -31,10 +31,6 @@
     : main_task_runner_(main_task_runner),
       decode_task_runner_(decode_task_runner),
       consumer_(consumer),
-      source_size_(SkISize::Make(0, 0)),
-      source_dpi_(SkIPoint::Make(0, 0)),
-      view_size_(SkISize::Make(0, 0)),
-      clip_area_(SkIRect::MakeEmpty()),
       paint_scheduled_(false),
       latest_sequence_number_(0) {
 }
@@ -66,25 +62,25 @@
   // If the packet includes screen size or DPI information, store them.
   if (packet->format().has_screen_width() &&
       packet->format().has_screen_height()) {
-    SkISize source_size = SkISize::Make(packet->format().screen_width(),
-                                        packet->format().screen_height());
-    if (source_size_ != source_size) {
+    webrtc::DesktopSize source_size(packet->format().screen_width(),
+                                    packet->format().screen_height());
+    if (!source_size_.equals(source_size)) {
       source_size_ = source_size;
       decoder_needs_reset = true;
       notify_size_or_dpi_change = true;
     }
   }
   if (packet->format().has_x_dpi() && packet->format().has_y_dpi()) {
-    SkIPoint source_dpi(SkIPoint::Make(packet->format().x_dpi(),
-                                       packet->format().y_dpi()));
-    if (source_dpi != source_dpi_) {
+    webrtc::DesktopVector source_dpi(packet->format().x_dpi(),
+                                     packet->format().y_dpi());
+    if (!source_dpi.equals(source_dpi_)) {
       source_dpi_ = source_dpi;
       notify_size_or_dpi_change = true;
     }
   }
 
   // If we've never seen a screen size, ignore the packet.
-  if (source_size_.isZero())
+  if (source_size_.is_empty())
     return;
 
   if (decoder_needs_reset)
@@ -112,23 +108,23 @@
   paint_scheduled_ = false;
 
   // If the view size is empty or we have no output buffers ready, return.
-  if (buffers_.empty() || view_size_.isEmpty())
+  if (buffers_.empty() || view_size_.is_empty())
     return;
 
   // If no Decoder is initialized, or the host dimensions are empty, return.
-  if (!decoder_.get() || source_size_.isEmpty())
+  if (!decoder_.get() || source_size_.is_empty())
     return;
 
   // Draw the invalidated region to the buffer.
   webrtc::DesktopFrame* buffer = buffers_.front();
-  SkRegion output_region;
+  webrtc::DesktopRegion output_region;
   decoder_->RenderFrame(view_size_, clip_area_,
                         buffer->data(),
                         buffer->stride(),
                         &output_region);
 
   // Notify the consumer that painting is done.
-  if (!output_region.isEmpty()) {
+  if (!output_region.is_empty()) {
     buffers_.pop_front();
     consumer_->ApplyBuffer(view_size_, clip_area_, buffer, output_region);
   }
@@ -166,7 +162,8 @@
   SchedulePaint();
 }
 
-void RectangleUpdateDecoder::InvalidateRegion(const SkRegion& region) {
+void RectangleUpdateDecoder::InvalidateRegion(
+    const webrtc::DesktopRegion& region) {
   if (!decode_task_runner_->BelongsToCurrentThread()) {
     decode_task_runner_->PostTask(
         FROM_HERE, base::Bind(&RectangleUpdateDecoder::InvalidateRegion,
@@ -180,8 +177,9 @@
   }
 }
 
-void RectangleUpdateDecoder::SetOutputSizeAndClip(const SkISize& view_size,
-                                                  const SkIRect& clip_area) {
+void RectangleUpdateDecoder::SetOutputSizeAndClip(
+    const webrtc::DesktopSize& view_size,
+    const webrtc::DesktopRect& clip_area) {
   if (!decode_task_runner_->BelongsToCurrentThread()) {
     decode_task_runner_->PostTask(
         FROM_HERE, base::Bind(&RectangleUpdateDecoder::SetOutputSizeAndClip,
@@ -190,14 +188,14 @@
   }
 
   // The whole frame needs to be repainted if the scaling factor has changed.
-  if (view_size_ != view_size && decoder_.get()) {
-    SkRegion region;
-    region.op(SkIRect::MakeSize(view_size), SkRegion::kUnion_Op);
+  if (!view_size_.equals(view_size) && decoder_.get()) {
+    webrtc::DesktopRegion region;
+    region.AddRect(webrtc::DesktopRect::MakeSize(view_size));
     decoder_->Invalidate(view_size, region);
   }
 
-  if (view_size_ != view_size ||
-      clip_area_ != clip_area) {
+  if (!view_size_.equals(view_size) ||
+      !clip_area_.equals(clip_area)) {
     view_size_ = view_size;
     clip_area_ = clip_area;
 
@@ -218,7 +216,7 @@
   }
 }
 
-const SkRegion* RectangleUpdateDecoder::GetBufferShape() {
+const webrtc::DesktopRegion* RectangleUpdateDecoder::GetBufferShape() {
   return decoder_->GetImageShape();
 }
 
diff --git a/remoting/client/rectangle_update_decoder.h b/remoting/client/rectangle_update_decoder.h
index 6d46a1efa..3c7468a 100644
--- a/remoting/client/rectangle_update_decoder.h
+++ b/remoting/client/rectangle_update_decoder.h
@@ -15,6 +15,7 @@
 #include "remoting/client/frame_consumer_proxy.h"
 #include "remoting/client/frame_producer.h"
 #include "remoting/protocol/video_stub.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 namespace base {
 class SingleThreadTaskRunner;
@@ -52,11 +53,12 @@
   // FrameProducer implementation.  These methods may be called before we are
   // Initialize()d, or we know the source screen size.
   virtual void DrawBuffer(webrtc::DesktopFrame* buffer) OVERRIDE;
-  virtual void InvalidateRegion(const SkRegion& region) OVERRIDE;
+  virtual void InvalidateRegion(const webrtc::DesktopRegion& region) OVERRIDE;
   virtual void RequestReturnBuffers(const base::Closure& done) OVERRIDE;
-  virtual void SetOutputSizeAndClip(const SkISize& view_size,
-                                    const SkIRect& clip_area) OVERRIDE;
-  virtual const SkRegion* GetBufferShape() OVERRIDE;
+  virtual void SetOutputSizeAndClip(
+      const webrtc::DesktopSize& view_size,
+      const webrtc::DesktopRect& clip_area) OVERRIDE;
+  virtual const webrtc::DesktopRegion* GetBufferShape() OVERRIDE;
 
   // VideoStub implementation.
   virtual void ProcessVideoPacket(scoped_ptr<VideoPacket> packet,
@@ -89,14 +91,14 @@
   scoped_ptr<VideoDecoder> decoder_;
 
   // Remote screen size in pixels.
-  SkISize source_size_;
+  webrtc::DesktopSize source_size_;
 
   // Vertical and horizontal DPI of the remote screen.
-  SkIPoint source_dpi_;
+  webrtc::DesktopVector source_dpi_;
 
   // The current dimensions of the frame consumer view.
-  SkISize view_size_;
-  SkIRect clip_area_;
+  webrtc::DesktopSize view_size_;
+  webrtc::DesktopRect clip_area_;
 
   // The drawing buffers supplied by the frame consumer.
   std::list<webrtc::DesktopFrame*> buffers_;
diff --git a/remoting/codec/codec_test.cc b/remoting/codec/codec_test.cc
index eebe263..e63ec3e 100644
--- a/remoting/codec/codec_test.cc
+++ b/remoting/codec/codec_test.cc
@@ -64,12 +64,12 @@
         view_size_.width() * view_size_.height() * kBytesPerPixel]);
     EXPECT_TRUE(image_data_.get());
     decoder_->Initialize(
-        SkISize::Make(screen_size_.width(), screen_size_.height()));
+        webrtc::DesktopSize(screen_size_.width(), screen_size_.height()));
   }
 
   void Reset() {
     expected_region_.Clear();
-    update_region_.setEmpty();
+    update_region_.Clear();
   }
 
   void ResetRenderedData() {
@@ -85,10 +85,9 @@
 
   void RenderFrame() {
     decoder_->RenderFrame(
-        SkISize::Make(view_size_.width(), view_size_.height()),
-        SkIRect::MakeWH(view_size_.width(), view_size_.height()),
-        image_data_.get(),
-        view_size_.width() * kBytesPerPixel,
+        webrtc::DesktopSize(view_size_.width(), view_size_.height()),
+        webrtc::DesktopRect::MakeWH(view_size_.width(), view_size_.height()),
+        image_data_.get(), view_size_.width() * kBytesPerPixel,
         &update_region_);
   }
 
@@ -121,14 +120,10 @@
     ASSERT_TRUE(frame_);
 
     // Test the content of the update region.
-    webrtc::DesktopRegion update_region;
-    for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) {
-      update_region.AddRect(webrtc::DesktopRect::MakeXYWH(
-          i.rect().x(), i.rect().y(), i.rect().width(), i.rect().height()));
-    }
-    EXPECT_TRUE(expected_region_.Equals(update_region));
+    EXPECT_TRUE(expected_region_.Equals(update_region_));
 
-    for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) {
+    for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
+         i.Advance()) {
       const int stride = view_size_.width() * kBytesPerPixel;
       EXPECT_EQ(stride, frame_->stride());
       const int offset =  stride * i.rect().top() +
@@ -153,7 +148,8 @@
     double max_error = 0.0;
     double sum_error = 0.0;
     int error_num = 0;
-    for (SkRegion::Iterator i(update_region_); !i.done(); i.next()) {
+    for (webrtc::DesktopRegion::Iterator i(update_region_); !i.IsAtEnd();
+         i.Advance()) {
       const int stride = view_size_.width() * kBytesPerPixel;
       const int offset =  stride * i.rect().top() +
           kBytesPerPixel * i.rect().left();
@@ -195,7 +191,7 @@
   DesktopSize view_size_;
   bool strict_;
   webrtc::DesktopRegion expected_region_;
-  SkRegion update_region_;
+  webrtc::DesktopRegion update_region_;
   VideoDecoder* decoder_;
   scoped_ptr<uint8[]> image_data_;
   webrtc::DesktopFrame* frame_;
@@ -377,8 +373,9 @@
   // invalidates the frame.
   decoder_tester.ResetRenderedData();
   decoder->Invalidate(
-      SkISize::Make(view_size.width(), view_size.height()),
-      SkRegion(SkIRect::MakeWH(view_size.width(), view_size.height())));
+      webrtc::DesktopSize(view_size.width(), view_size.height()),
+      webrtc::DesktopRegion(
+          webrtc::DesktopRect::MakeWH(view_size.width(), view_size.height())));
   decoder_tester.RenderFrame();
   decoder_tester.VerifyResultsApprox(expected_result->data(),
                                      max_error_limit, mean_error_limit);
diff --git a/remoting/codec/video_decoder.h b/remoting/codec/video_decoder.h
index 61f0233..b3048a90 100644
--- a/remoting/codec/video_decoder.h
+++ b/remoting/codec/video_decoder.h
@@ -7,9 +7,12 @@
 
 #include "base/basictypes.h"
 #include "remoting/proto/video.pb.h"
-#include "third_party/skia/include/core/SkRect.h"
-#include "third_party/skia/include/core/SkRegion.h"
-#include "third_party/skia/include/core/SkSize.h"
+
+namespace webrtc {
+class DesktopRect;
+class DesktopRegion;
+class DesktopSize;
+}  // namespace webrtc
 
 namespace remoting {
 
@@ -24,7 +27,7 @@
 
   // Initializes the decoder and sets the output dimensions.
   // |screen size| must not be empty.
-  virtual void Initialize(const SkISize& screen_size) = 0;
+  virtual void Initialize(const webrtc::DesktopSize& screen_size) = 0;
 
   // Feeds more data into the decoder. Returns true if |packet| was processed
   // and the frame can be displayed now.
@@ -33,8 +36,8 @@
   // Marks the specified |region| of the view for update the next time
   // RenderFrame() is called.  |region| is expressed in |view_size| coordinates.
   // |view_size| must not be empty.
-  virtual void Invalidate(const SkISize& view_size,
-                          const SkRegion& region) = 0;
+  virtual void Invalidate(const webrtc::DesktopSize& view_size,
+                          const webrtc::DesktopRegion& region) = 0;
 
   // Copies invalidated pixels within |clip_area| to |image_buffer|. Pixels are
   // invalidated either by new data received in DecodePacket(), or by explicit
@@ -48,15 +51,15 @@
   //
   // On return, |output_region| contains the updated area, in |view_size|
   // coordinates.
-  virtual void RenderFrame(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void RenderFrame(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            uint8* image_buffer,
                            int image_stride,
-                           SkRegion* output_region) = 0;
+                           webrtc::DesktopRegion* output_region) = 0;
 
   // Returns the "shape", if any, of the most recently rendered frame.
   // The shape is returned in source dimensions.
-  virtual const SkRegion* GetImageShape() = 0;
+  virtual const webrtc::DesktopRegion* GetImageShape() = 0;
 };
 
 }  // namespace remoting
diff --git a/remoting/codec/video_decoder_verbatim.cc b/remoting/codec/video_decoder_verbatim.cc
index 0431dc2..05af0ce 100644
--- a/remoting/codec/video_decoder_verbatim.cc
+++ b/remoting/codec/video_decoder_verbatim.cc
@@ -9,18 +9,17 @@
 
 namespace remoting {
 
-VideoDecoderVerbatim::VideoDecoderVerbatim()
-    : screen_size_(SkISize::Make(0, 0)) {}
+VideoDecoderVerbatim::VideoDecoderVerbatim() {}
 
 VideoDecoderVerbatim::~VideoDecoderVerbatim() {}
 
-void VideoDecoderVerbatim::Initialize(const SkISize& screen_size) {
-  updated_region_.setEmpty();
+void VideoDecoderVerbatim::Initialize(const webrtc::DesktopSize& screen_size) {
+  updated_region_.Clear();
   screen_buffer_.reset();
 
   screen_size_ = screen_size;
   // Allocate the screen buffer, if necessary.
-  if (!screen_size_.isEmpty()) {
+  if (!screen_size_.is_empty()) {
     screen_buffer_.reset(
         new uint8[screen_size_.width() * screen_size_.height() *
                   kBytesPerPixel]);
@@ -28,27 +27,28 @@
 }
 
 bool VideoDecoderVerbatim::DecodePacket(const VideoPacket& packet) {
-  SkRegion region;
+  webrtc::DesktopRegion region;
 
   const char* in = packet.data().data();
   int stride = kBytesPerPixel * screen_size_.width();
   for (int i = 0; i < packet.dirty_rects_size(); ++i) {
     Rect proto_rect = packet.dirty_rects(i);
-    SkIRect rect = SkIRect::MakeXYWH(proto_rect.x(),
-                                     proto_rect.y(),
-                                     proto_rect.width(),
-                                     proto_rect.height());
-    region.op(rect, SkRegion::kUnion_Op);
+    webrtc::DesktopRect rect =
+        webrtc::DesktopRect::MakeXYWH(proto_rect.x(),
+                                      proto_rect.y(),
+                                      proto_rect.width(),
+                                      proto_rect.height());
+    region.AddRect(rect);
 
-    if (!SkIRect::MakeSize(screen_size_).contains(rect)) {
+    if (!DoesRectContain(webrtc::DesktopRect::MakeSize(screen_size_), rect)) {
       LOG(ERROR) << "Invalid packet received";
       return false;
     }
 
     int rect_row_size = kBytesPerPixel * rect.width();
-    uint8_t* out = screen_buffer_.get() + rect.y() * stride +
-                   rect.x() * kBytesPerPixel;
-    for (int y = rect.y(); y < rect.y() + rect.height(); ++y) {
+    uint8_t* out = screen_buffer_.get() + rect.top() * stride +
+                   rect.left() * kBytesPerPixel;
+    for (int y = rect.top(); y < rect.top() + rect.height(); ++y) {
       if (in + rect_row_size > packet.data().data() + packet.data().size()) {
         LOG(ERROR) << "Invalid packet received";
         return false;
@@ -64,33 +64,36 @@
     return false;
   }
 
-  updated_region_.op(region, SkRegion::kUnion_Op);
+  updated_region_.AddRegion(region);
 
   return true;
 }
 
-void VideoDecoderVerbatim::Invalidate(const SkISize& view_size,
-                                      const SkRegion& region) {
-  updated_region_.op(region, SkRegion::kUnion_Op);
+void VideoDecoderVerbatim::Invalidate(const webrtc::DesktopSize& view_size,
+                                      const webrtc::DesktopRegion& region) {
+  updated_region_.AddRegion(region);
 }
 
-void VideoDecoderVerbatim::RenderFrame(const SkISize& view_size,
-                                       const SkIRect& clip_area,
+void VideoDecoderVerbatim::RenderFrame(const webrtc::DesktopSize& view_size,
+                                       const webrtc::DesktopRect& clip_area,
                                        uint8* image_buffer,
                                        int image_stride,
-                                       SkRegion* output_region) {
-  output_region->setEmpty();
+                                       webrtc::DesktopRegion* output_region) {
+  output_region->Clear();
 
   // TODO(alexeypa): scaling is not implemented.
-  SkIRect clip_rect = SkIRect::MakeSize(screen_size_);
-  if (!clip_rect.intersect(clip_area))
+  webrtc::DesktopRect clip_rect = webrtc::DesktopRect::MakeSize(screen_size_);
+  clip_rect.IntersectWith(clip_area);
+  if (clip_rect.is_empty())
     return;
 
   int screen_stride = screen_size_.width() * kBytesPerPixel;
 
-  for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
-    SkIRect rect(i.rect());
-    if (!rect.intersect(clip_rect))
+  for (webrtc::DesktopRegion::Iterator i(updated_region_);
+       !i.IsAtEnd(); i.Advance()) {
+    webrtc::DesktopRect rect(i.rect());
+    rect.IntersectWith(clip_rect);
+    if (rect.is_empty())
       continue;
 
     CopyRGB32Rect(screen_buffer_.get(), screen_stride,
@@ -98,13 +101,13 @@
                   image_buffer, image_stride,
                   clip_area,
                   rect);
-    output_region->op(rect, SkRegion::kUnion_Op);
+    output_region->AddRect(rect);
   }
 
-  updated_region_.setEmpty();
+  updated_region_.Clear();
 }
 
-const SkRegion* VideoDecoderVerbatim::GetImageShape() {
+const webrtc::DesktopRegion* VideoDecoderVerbatim::GetImageShape() {
   return NULL;
 }
 
diff --git a/remoting/codec/video_decoder_verbatim.h b/remoting/codec/video_decoder_verbatim.h
index fa783dd..24203d9 100644
--- a/remoting/codec/video_decoder_verbatim.h
+++ b/remoting/codec/video_decoder_verbatim.h
@@ -8,6 +8,8 @@
 #include "base/compiler_specific.h"
 #include "base/memory/scoped_ptr.h"
 #include "remoting/codec/video_decoder.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 namespace remoting {
 
@@ -21,23 +23,23 @@
   VideoDecoderVerbatim();
 
   // VideoDecoder implementation.
-  virtual void Initialize(const SkISize& screen_size) OVERRIDE;
+  virtual void Initialize(const webrtc::DesktopSize& screen_size) OVERRIDE;
   virtual bool DecodePacket(const VideoPacket& packet) OVERRIDE;
-  virtual void Invalidate(const SkISize& view_size,
-                          const SkRegion& region) OVERRIDE;
-  virtual void RenderFrame(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void Invalidate(const webrtc::DesktopSize& view_size,
+                          const webrtc::DesktopRegion& region) OVERRIDE;
+  virtual void RenderFrame(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            uint8* image_buffer,
                            int image_stride,
-                           SkRegion* output_region) OVERRIDE;
-  virtual const SkRegion* GetImageShape() OVERRIDE;
+                           webrtc::DesktopRegion* output_region) OVERRIDE;
+  virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE;
 
  private:
   // The region updated that hasn't been copied to the screen yet.
-  SkRegion updated_region_;
+  webrtc::DesktopRegion updated_region_;
 
   // Size of the remote screen.
-  SkISize screen_size_;
+  webrtc::DesktopSize screen_size_;
 
   // The bitmap holding the remote screen bits.
   scoped_ptr<uint8[]> screen_buffer_;
diff --git a/remoting/codec/video_decoder_vp8.cc b/remoting/codec/video_decoder_vp8.cc
index 48bf534..0d43f15f 100644
--- a/remoting/codec/video_decoder_vp8.cc
+++ b/remoting/codec/video_decoder_vp8.cc
@@ -26,8 +26,7 @@
 VideoDecoderVp8::VideoDecoderVp8()
     : state_(kUninitialized),
       codec_(NULL),
-      last_image_(NULL),
-      screen_size_(SkISize::Make(0, 0)) {
+      last_image_(NULL) {
 }
 
 VideoDecoderVp8::~VideoDecoderVp8() {
@@ -38,13 +37,13 @@
   delete codec_;
 }
 
-void VideoDecoderVp8::Initialize(const SkISize& screen_size) {
-  DCHECK(!screen_size.isEmpty());
+void VideoDecoderVp8::Initialize(const webrtc::DesktopSize& screen_size) {
+  DCHECK(!screen_size.is_empty());
 
   screen_size_ = screen_size;
   state_ = kReady;
 
-  transparent_region_.setRect(SkIRect::MakeSize(screen_size_));
+  transparent_region_.SetRect(webrtc::DesktopRect::MakeSize(screen_size_));
 }
 
 bool VideoDecoderVp8::DecodePacket(const VideoPacket& packet) {
@@ -61,8 +60,7 @@
     config.h = 0;
     config.threads = 2;
     vpx_codec_err_t ret =
-        vpx_codec_dec_init(
-            codec_, vpx_codec_vp8_dx(), &config, 0);
+        vpx_codec_dec_init(codec_, vpx_codec_vp8_dx(), &config, 0);
     if (ret != VPX_CODEC_OK) {
       LOG(INFO) << "Cannot initialize codec.";
       delete codec_;
@@ -92,33 +90,30 @@
   }
   last_image_ = image;
 
-  SkRegion region;
+  webrtc::DesktopRegion region;
   for (int i = 0; i < packet.dirty_rects_size(); ++i) {
     Rect remoting_rect = packet.dirty_rects(i);
-    SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
-                                     remoting_rect.y(),
-                                     remoting_rect.width(),
-                                     remoting_rect.height());
-    region.op(rect, SkRegion::kUnion_Op);
+    region.AddRect(webrtc::DesktopRect::MakeXYWH(
+        remoting_rect.x(), remoting_rect.y(),
+        remoting_rect.width(), remoting_rect.height()));
   }
 
-  updated_region_.op(region, SkRegion::kUnion_Op);
+  updated_region_.AddRegion(region);
 
   // Update the desktop shape region.
-  SkRegion desktop_shape_region;
+  webrtc::DesktopRegion desktop_shape_region;
   if (packet.has_use_desktop_shape()) {
     for (int i = 0; i < packet.desktop_shape_rects_size(); ++i) {
       Rect remoting_rect = packet.desktop_shape_rects(i);
-      SkIRect rect = SkIRect::MakeXYWH(remoting_rect.x(),
-                                       remoting_rect.y(),
-                                       remoting_rect.width(),
-                                       remoting_rect.height());
-      desktop_shape_region.op(rect, SkRegion::kUnion_Op);
+      desktop_shape_region.AddRect(webrtc::DesktopRect::MakeXYWH(
+          remoting_rect.x(), remoting_rect.y(),
+          remoting_rect.width(), remoting_rect.height()));
     }
   } else {
     // Fallback for the case when the host didn't include the desktop shape
     // region.
-    desktop_shape_region = SkRegion(SkIRect::MakeSize(screen_size_));
+    desktop_shape_region =
+        webrtc::DesktopRegion(webrtc::DesktopRect::MakeSize(screen_size_));
   }
 
   UpdateImageShapeRegion(&desktop_shape_region);
@@ -126,64 +121,65 @@
   return true;
 }
 
-void VideoDecoderVp8::Invalidate(const SkISize& view_size,
-                                 const SkRegion& region) {
+void VideoDecoderVp8::Invalidate(const webrtc::DesktopSize& view_size,
+                                 const webrtc::DesktopRegion& region) {
   DCHECK_EQ(kReady, state_);
-  DCHECK(!view_size.isEmpty());
+  DCHECK(!view_size.is_empty());
 
-  for (SkRegion::Iterator i(region); !i.done(); i.next()) {
-    SkIRect rect = i.rect();
-    rect = ScaleRect(rect, view_size, screen_size_);
-    updated_region_.op(rect, SkRegion::kUnion_Op);
+  for (webrtc::DesktopRegion::Iterator i(region); !i.IsAtEnd(); i.Advance()) {
+    updated_region_.AddRect(ScaleRect(i.rect(), view_size, screen_size_));
   }
 
   // Updated areas outside of the new desktop shape region should be made
   // transparent, not repainted.
-  SkRegion difference = updated_region_;
-  difference.op(desktop_shape_, SkRegion::kDifference_Op);
-  updated_region_.op(difference, SkRegion::kDifference_Op);
-  transparent_region_.op(difference, SkRegion::kUnion_Op);
+  webrtc::DesktopRegion difference = updated_region_;
+  difference.Subtract(desktop_shape_);
+  updated_region_.Subtract(difference);
+  transparent_region_.AddRegion(difference);
 }
 
-void VideoDecoderVp8::RenderFrame(const SkISize& view_size,
-                                  const SkIRect& clip_area,
+void VideoDecoderVp8::RenderFrame(const webrtc::DesktopSize& view_size,
+                                  const webrtc::DesktopRect& clip_area,
                                   uint8* image_buffer,
                                   int image_stride,
-                                  SkRegion* output_region) {
+                                  webrtc::DesktopRegion* output_region) {
   DCHECK_EQ(kReady, state_);
-  DCHECK(!view_size.isEmpty());
+  DCHECK(!view_size.is_empty());
 
   // Early-return and do nothing if we haven't yet decoded any frames.
   if (!last_image_)
     return;
 
-  SkIRect source_clip = SkIRect::MakeWH(last_image_->d_w, last_image_->d_h);
+  webrtc::DesktopRect source_clip =
+      webrtc::DesktopRect::MakeWH(last_image_->d_w, last_image_->d_h);
 
   // ScaleYUVToRGB32WithRect does not currently support up-scaling.  We won't
   // be asked to up-scale except during resizes or if page zoom is >100%, so
   // we work-around the limitation by using the slower ScaleYUVToRGB32.
   // TODO(wez): Remove this hack if/when ScaleYUVToRGB32WithRect can up-scale.
-  if (!updated_region_.isEmpty() &&
+  if (!updated_region_.is_empty() &&
       (source_clip.width() < view_size.width() ||
        source_clip.height() < view_size.height())) {
     // We're scaling only |clip_area| into the |image_buffer|, so we need to
     // work out which source rectangle that corresponds to.
-    SkIRect source_rect = ScaleRect(clip_area, view_size, screen_size_);
-    source_rect = SkIRect::MakeLTRB(RoundToTwosMultiple(source_rect.left()),
-                                    RoundToTwosMultiple(source_rect.top()),
-                                    source_rect.right(),
-                                    source_rect.bottom());
+    webrtc::DesktopRect source_rect =
+        ScaleRect(clip_area, view_size, screen_size_);
+    source_rect = webrtc::DesktopRect::MakeLTRB(
+        RoundToTwosMultiple(source_rect.left()),
+        RoundToTwosMultiple(source_rect.top()),
+        source_rect.right(),
+        source_rect.bottom());
 
     // If there were no changes within the clip source area then don't render.
-    if (!updated_region_.intersects(source_rect))
+    webrtc::DesktopRegion intersection(source_rect);
+    intersection.IntersectWith(updated_region_);
+    if (intersection.is_empty())
       return;
 
     // Scale & convert the entire clip area.
-    int y_offset = CalculateYOffset(source_rect.x(),
-                                    source_rect.y(),
+    int y_offset = CalculateYOffset(source_rect.left(), source_rect.top(),
                                     last_image_->stride[0]);
-    int uv_offset = CalculateUVOffset(source_rect.x(),
-                                      source_rect.y(),
+    int uv_offset = CalculateUVOffset(source_rect.left(), source_rect.top(),
                                       last_image_->stride[1]);
     ScaleYUVToRGB32(last_image_->planes[0] + y_offset,
                     last_image_->planes[1] + uv_offset,
@@ -200,18 +196,21 @@
                     media::ROTATE_0,
                     media::FILTER_BILINEAR);
 
-    output_region->op(clip_area, SkRegion::kUnion_Op);
-    updated_region_.op(source_rect, SkRegion::kDifference_Op);
+    output_region->AddRect(clip_area);
+    updated_region_.Subtract(source_rect);
     return;
   }
 
-  for (SkRegion::Iterator i(updated_region_); !i.done(); i.next()) {
+  for (webrtc::DesktopRegion::Iterator i(updated_region_);
+       !i.IsAtEnd(); i.Advance()) {
     // Determine the scaled area affected by this rectangle changing.
-    SkIRect rect = i.rect();
-    if (!rect.intersect(source_clip))
+    webrtc::DesktopRect rect = i.rect();
+    rect.IntersectWith(source_clip);
+    if (rect.is_empty())
       continue;
     rect = ScaleRect(rect, screen_size_, view_size);
-    if (!rect.intersect(clip_area))
+    rect.IntersectWith(clip_area);
+    if (rect.is_empty())
       continue;
 
     ConvertAndScaleYUVToRGB32Rect(last_image_->planes[0],
@@ -227,38 +226,41 @@
                                   clip_area,
                                   rect);
 
-    output_region->op(rect, SkRegion::kUnion_Op);
+    output_region->AddRect(rect);
   }
 
-  updated_region_.op(ScaleRect(clip_area, view_size, screen_size_),
-                     SkRegion::kDifference_Op);
+  updated_region_.Subtract(ScaleRect(clip_area, view_size, screen_size_));
 
-  for (SkRegion::Iterator i(transparent_region_); !i.done(); i.next()) {
+  for (webrtc::DesktopRegion::Iterator i(transparent_region_);
+       !i.IsAtEnd(); i.Advance()) {
     // Determine the scaled area affected by this rectangle changing.
-    SkIRect rect = i.rect();
-    if (!rect.intersect(source_clip))
+    webrtc::DesktopRect rect = i.rect();
+    rect.IntersectWith(source_clip);
+    if (rect.is_empty())
       continue;
     rect = ScaleRect(rect, screen_size_, view_size);
-    if (!rect.intersect(clip_area))
+    rect.IntersectWith(clip_area);
+    if (rect.is_empty())
       continue;
 
     // Fill the rectange with transparent pixels.
     FillRect(image_buffer, image_stride, rect, kTransparent);
-    output_region->op(rect, SkRegion::kUnion_Op);
+    output_region->AddRect(rect);
   }
 
-  SkIRect scaled_clip_area = ScaleRect(clip_area, view_size, screen_size_);
-  updated_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
-  transparent_region_.op(scaled_clip_area, SkRegion::kDifference_Op);
+  webrtc::DesktopRect scaled_clip_area =
+      ScaleRect(clip_area, view_size, screen_size_);
+  updated_region_.Subtract(scaled_clip_area);
+  transparent_region_.Subtract(scaled_clip_area);
 }
 
-const SkRegion* VideoDecoderVp8::GetImageShape() {
+const webrtc::DesktopRegion* VideoDecoderVp8::GetImageShape() {
   return &desktop_shape_;
 }
 
 void VideoDecoderVp8::FillRect(uint8* buffer,
                                int stride,
-                               const SkIRect& rect,
+                               const webrtc::DesktopRect& rect,
                                uint32 color) {
   uint32* ptr = reinterpret_cast<uint32*>(buffer + (rect.top() * stride) +
       (rect.left() * kBytesPerPixel));
@@ -269,22 +271,23 @@
   }
 }
 
-void VideoDecoderVp8::UpdateImageShapeRegion(SkRegion* new_desktop_shape) {
+void VideoDecoderVp8::UpdateImageShapeRegion(
+    webrtc::DesktopRegion* new_desktop_shape) {
   // Add all areas that have been updated or become transparent to the
   // transparent region. Exclude anything within the new desktop shape.
-  transparent_region_.op(desktop_shape_, SkRegion::kUnion_Op);
-  transparent_region_.op(updated_region_, SkRegion::kUnion_Op);
-  transparent_region_.op(*new_desktop_shape, SkRegion::kDifference_Op);
+  transparent_region_.AddRegion(desktop_shape_);
+  transparent_region_.AddRegion(updated_region_);
+  transparent_region_.Subtract(*new_desktop_shape);
 
   // Add newly exposed areas to the update region and limit updates to the new
   // desktop shape.
-  SkRegion difference = *new_desktop_shape;
-  difference.op(desktop_shape_, SkRegion::kDifference_Op);
-  updated_region_.op(difference, SkRegion::kUnion_Op);
-  updated_region_.op(*new_desktop_shape, SkRegion::kIntersect_Op);
+  webrtc::DesktopRegion difference = *new_desktop_shape;
+  difference.Subtract(desktop_shape_);
+  updated_region_.AddRegion(difference);
+  updated_region_.IntersectWith(*new_desktop_shape);
 
   // Set the new desktop shape region.
-  desktop_shape_.swap(*new_desktop_shape);
+  desktop_shape_.Swap(new_desktop_shape);
 }
 
 }  // namespace remoting
diff --git a/remoting/codec/video_decoder_vp8.h b/remoting/codec/video_decoder_vp8.h
index 6912ab0..42a3176 100644
--- a/remoting/codec/video_decoder_vp8.h
+++ b/remoting/codec/video_decoder_vp8.h
@@ -7,6 +7,8 @@
 
 #include "base/compiler_specific.h"
 #include "remoting/codec/video_decoder.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 typedef struct vpx_codec_ctx vpx_codec_ctx_t;
 typedef struct vpx_image vpx_image_t;
@@ -19,16 +21,16 @@
   virtual ~VideoDecoderVp8();
 
   // VideoDecoder implementations.
-  virtual void Initialize(const SkISize& screen_size) OVERRIDE;
+  virtual void Initialize(const webrtc::DesktopSize& screen_size) OVERRIDE;
   virtual bool DecodePacket(const VideoPacket& packet) OVERRIDE;
-  virtual void Invalidate(const SkISize& view_size,
-                          const SkRegion& region) OVERRIDE;
-  virtual void RenderFrame(const SkISize& view_size,
-                           const SkIRect& clip_area,
+  virtual void Invalidate(const webrtc::DesktopSize& view_size,
+                          const webrtc::DesktopRegion& region) OVERRIDE;
+  virtual void RenderFrame(const webrtc::DesktopSize& view_size,
+                           const webrtc::DesktopRect& clip_area,
                            uint8* image_buffer,
                            int image_stride,
-                           SkRegion* output_region) OVERRIDE;
-  virtual const SkRegion* GetImageShape() OVERRIDE;
+                           webrtc::DesktopRegion* output_region) OVERRIDE;
+  virtual const webrtc::DesktopRegion* GetImageShape() OVERRIDE;
 
  private:
   enum State {
@@ -38,12 +40,14 @@
   };
 
   // Fills the rectangle |rect| with the given ARGB color |color| in |buffer|.
-  void FillRect(uint8* buffer, int stride, const SkIRect& rect, uint32 color);
+  void FillRect(uint8* buffer, int stride,
+                const webrtc::DesktopRect& rect,
+                uint32 color);
 
   // Calculates the difference between the desktop shape regions in two
   // consecutive frames and updates |updated_region_| and |transparent_region_|
   // accordingly.
-  void UpdateImageShapeRegion(SkRegion* new_desktop_shape);
+  void UpdateImageShapeRegion(webrtc::DesktopRegion* new_desktop_shape);
 
   // The internal state of the decoder.
   State state_;
@@ -54,16 +58,16 @@
   vpx_image_t* last_image_;
 
   // The region updated that hasn't been copied to the screen yet.
-  SkRegion updated_region_;
+  webrtc::DesktopRegion updated_region_;
 
   // Output dimensions.
-  SkISize screen_size_;
+  webrtc::DesktopSize screen_size_;
 
   // The region occupied by the top level windows.
-  SkRegion desktop_shape_;
+  webrtc::DesktopRegion desktop_shape_;
 
   // The region that should be make transparent.
-  SkRegion transparent_region_;
+  webrtc::DesktopRegion transparent_region_;
 
   DISALLOW_COPY_AND_ASSIGN(VideoDecoderVp8);
 };
diff --git a/remoting/codec/video_encoder_vp8.cc b/remoting/codec/video_encoder_vp8.cc
index 179483da..077bdd1 100644
--- a/remoting/codec/video_encoder_vp8.cc
+++ b/remoting/codec/video_encoder_vp8.cc
@@ -12,6 +12,7 @@
 #include "remoting/proto/video.pb.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
 
 extern "C" {
 #define VPX_CODEC_DISABLE_COMPAT 1
@@ -145,30 +146,31 @@
 }
 
 void VideoEncoderVp8::PrepareImage(const webrtc::DesktopFrame& frame,
-                                   SkRegion* updated_region) {
+                                   webrtc::DesktopRegion* updated_region) {
   if (frame.updated_region().is_empty()) {
-    updated_region->setEmpty();
+    updated_region->Clear();
     return;
   }
 
   // Align the region to macroblocks, to avoid encoding artefacts.
   // This also ensures that all rectangles have even-aligned top-left, which
   // is required for ConvertRGBToYUVWithRect() to work.
-  std::vector<SkIRect> aligned_rects;
+  std::vector<webrtc::DesktopRect> aligned_rects;
   for (webrtc::DesktopRegion::Iterator r(frame.updated_region());
        !r.IsAtEnd(); r.Advance()) {
     const webrtc::DesktopRect& rect = r.rect();
-    aligned_rects.push_back(AlignRect(
-      SkIRect::MakeLTRB(rect.left(), rect.top(), rect.right(), rect.bottom())));
+    aligned_rects.push_back(AlignRect(webrtc::DesktopRect::MakeLTRB(
+        rect.left(), rect.top(), rect.right(), rect.bottom())));
   }
   DCHECK(!aligned_rects.empty());
-  updated_region->setRects(&aligned_rects[0], aligned_rects.size());
+  updated_region->Clear();
+  updated_region->AddRects(&aligned_rects[0], aligned_rects.size());
 
   // Clip back to the screen dimensions, in case they're not macroblock aligned.
   // The conversion routines don't require even width & height, so this is safe
   // even if the source dimensions are not even.
-  updated_region->op(SkIRect::MakeWH(image_->w, image_->h),
-                     SkRegion::kIntersect_Op);
+  updated_region->IntersectWith(
+      webrtc::DesktopRect::MakeWH(image_->w, image_->h));
 
   // Convert the updated region to YUV ready for encoding.
   const uint8* rgb_data = frame.data();
@@ -179,22 +181,25 @@
   uint8* y_data = image_->planes[0];
   uint8* u_data = image_->planes[1];
   uint8* v_data = image_->planes[2];
-  for (SkRegion::Iterator r(*updated_region); !r.done(); r.next()) {
-    const SkIRect& rect = r.rect();
+  for (webrtc::DesktopRegion::Iterator r(*updated_region); !r.IsAtEnd();
+       r.Advance()) {
+    const webrtc::DesktopRect& rect = r.rect();
     ConvertRGB32ToYUVWithRect(
         rgb_data, y_data, u_data, v_data,
-        rect.x(), rect.y(), rect.width(), rect.height(),
+        rect.left(), rect.top(), rect.width(), rect.height(),
         rgb_stride, y_stride, uv_stride);
   }
 }
 
-void VideoEncoderVp8::PrepareActiveMap(const SkRegion& updated_region) {
+void VideoEncoderVp8::PrepareActiveMap(
+    const webrtc::DesktopRegion& updated_region) {
   // Clear active map first.
   memset(active_map_.get(), 0, active_map_width_ * active_map_height_);
 
   // Mark updated areas active.
-  for (SkRegion::Iterator r(updated_region); !r.done(); r.next()) {
-    const SkIRect& rect = r.rect();
+  for (webrtc::DesktopRegion::Iterator r(updated_region); !r.IsAtEnd();
+       r.Advance()) {
+    const webrtc::DesktopRect& rect = r.rect();
     int left = rect.left() / kMacroBlockSize;
     int right = (rect.right() - 1) / kMacroBlockSize;
     int top = rect.top() / kMacroBlockSize;
@@ -227,7 +232,7 @@
   }
 
   // Convert the updated capture data ready for encode.
-  SkRegion updated_region;
+  webrtc::DesktopRegion updated_region;
   PrepareImage(frame, &updated_region);
 
   // Update active map based on updated region.
@@ -263,8 +268,8 @@
   scoped_ptr<VideoPacket> packet(new VideoPacket());
 
   while (!got_data) {
-    const vpx_codec_cx_pkt_t* vpx_packet = vpx_codec_get_cx_data(codec_.get(),
-                                                                 &iter);
+    const vpx_codec_cx_pkt_t* vpx_packet =
+        vpx_codec_get_cx_data(codec_.get(), &iter);
     if (!vpx_packet)
       continue;
 
@@ -290,10 +295,11 @@
     packet->mutable_format()->set_x_dpi(frame.dpi().x());
     packet->mutable_format()->set_y_dpi(frame.dpi().y());
   }
-  for (SkRegion::Iterator r(updated_region); !r.done(); r.next()) {
+  for (webrtc::DesktopRegion::Iterator r(updated_region); !r.IsAtEnd();
+       r.Advance()) {
     Rect* rect = packet->add_dirty_rects();
-    rect->set_x(r.rect().x());
-    rect->set_y(r.rect().y());
+    rect->set_x(r.rect().left());
+    rect->set_y(r.rect().top());
     rect->set_width(r.rect().width());
     rect->set_height(r.rect().height());
   }
diff --git a/remoting/codec/video_encoder_vp8.h b/remoting/codec/video_encoder_vp8.h
index 2e1ade1..25b00b36 100644
--- a/remoting/codec/video_encoder_vp8.h
+++ b/remoting/codec/video_encoder_vp8.h
@@ -7,12 +7,12 @@
 
 #include "base/gtest_prod_util.h"
 #include "remoting/codec/video_encoder.h"
-#include "third_party/skia/include/core/SkRegion.h"
 
 typedef struct vpx_codec_ctx vpx_codec_ctx_t;
 typedef struct vpx_image vpx_image_t;
 
 namespace webrtc {
+class DesktopRegion;
 class DesktopSize;
 }  // namespace webrtc
 
@@ -42,11 +42,11 @@
   //
   // TODO(sergeyu): Update this code to use webrtc::DesktopRegion.
   void PrepareImage(const webrtc::DesktopFrame& frame,
-                    SkRegion* updated_region);
+                    webrtc::DesktopRegion* updated_region);
 
   // Update the active map according to |updated_region|. Active map is then
   // given to the encoder to speed up encoding.
-  void PrepareActiveMap(const SkRegion& updated_region);
+  void PrepareActiveMap(const webrtc::DesktopRegion& updated_region);
 
   // True if the encoder is initialized.
   bool initialized_;
diff --git a/remoting/host/DEPS b/remoting/host/DEPS
index ef945f3..70b8379 100644
--- a/remoting/host/DEPS
+++ b/remoting/host/DEPS
@@ -1,11 +1,13 @@
 include_rules = [
   "+net",
   "+remoting/codec",
-  "+remoting/protocol",
   "+remoting/jingle_glue",
+  "+remoting/protocol",
+  "+skia/ext",
   "+third_party/jsoncpp",
   "+third_party/modp_b64",
   "+third_party/npapi",
+  "+third_party/skia/include/core",
   "+third_party/webrtc",
   "+ui",
 ]
diff --git a/remoting/host/mouse_clamping_filter.cc b/remoting/host/mouse_clamping_filter.cc
index db01c10..91462fa3 100644
--- a/remoting/host/mouse_clamping_filter.cc
+++ b/remoting/host/mouse_clamping_filter.cc
@@ -24,8 +24,9 @@
   // Configure the MouseInputFilter to clamp to the video dimensions.
   if (video_packet->format().has_screen_width() &&
       video_packet->format().has_screen_height()) {
-    SkISize screen_size = SkISize::Make(video_packet->format().screen_width(),
-                                        video_packet->format().screen_height());
+    webrtc::DesktopSize screen_size =
+        webrtc::DesktopSize(video_packet->format().screen_width(),
+                            video_packet->format().screen_height());
     input_filter_.set_input_size(screen_size);
     input_filter_.set_output_size(screen_size);
   }
diff --git a/remoting/protocol/input_event_tracker.cc b/remoting/protocol/input_event_tracker.cc
index 7090d4d2..331546a 100644
--- a/remoting/protocol/input_event_tracker.cc
+++ b/remoting/protocol/input_event_tracker.cc
@@ -12,7 +12,6 @@
 
 InputEventTracker::InputEventTracker(InputStub* input_stub)
     : input_stub_(input_stub),
-      mouse_pos_(SkIPoint::Make(0, 0)),
       mouse_button_state_(0) {
 }
 
@@ -74,7 +73,7 @@
 
 void InputEventTracker::InjectMouseEvent(const MouseEvent& event) {
   if (event.has_x() && event.has_y()) {
-    mouse_pos_ = SkIPoint::Make(event.x(), event.y());
+    mouse_pos_ = webrtc::DesktopVector(event.x(), event.y());
   }
   if (event.has_button() && event.has_button_down()) {
     // Button values are defined in remoting/proto/event.proto.
diff --git a/remoting/protocol/input_event_tracker.h b/remoting/protocol/input_event_tracker.h
index 794fffe9..8e0bda7b 100644
--- a/remoting/protocol/input_event_tracker.h
+++ b/remoting/protocol/input_event_tracker.h
@@ -10,7 +10,7 @@
 #include "base/basictypes.h"
 #include "base/compiler_specific.h"
 #include "remoting/protocol/input_stub.h"
-#include "third_party/skia/include/core/SkPoint.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 namespace remoting {
 namespace protocol {
@@ -42,7 +42,7 @@
 
   std::set<uint32> pressed_keys_;
 
-  SkIPoint mouse_pos_;
+  webrtc::DesktopVector mouse_pos_;
   uint32 mouse_button_state_;
 
   DISALLOW_COPY_AND_ASSIGN(InputEventTracker);
diff --git a/remoting/protocol/mouse_input_filter.cc b/remoting/protocol/mouse_input_filter.cc
index 5a11fa8..f3943416 100644
--- a/remoting/protocol/mouse_input_filter.cc
+++ b/remoting/protocol/mouse_input_filter.cc
@@ -14,15 +14,13 @@
 
 MouseInputFilter::MouseInputFilter(InputStub* input_stub)
     : InputFilter(input_stub) {
-  input_max_.setEmpty();
-  output_max_.setEmpty();
 }
 
 MouseInputFilter::~MouseInputFilter() {
 }
 
 void MouseInputFilter::InjectMouseEvent(const MouseEvent& event) {
-  if (input_max_.isEmpty() || output_max_.isEmpty())
+  if (input_max_.is_empty() || output_max_.is_empty())
     return;
 
   // We scale based on the maximum input & output coordinates, rather than the
@@ -44,12 +42,12 @@
   InputFilter::InjectMouseEvent(out_event);
 }
 
-void MouseInputFilter::set_input_size(const SkISize& size) {
-  input_max_ = SkISize::Make(size.width() - 1, size.height() - 1);
+void MouseInputFilter::set_input_size(const webrtc::DesktopSize& size) {
+  input_max_.set(size.width() - 1, size.height() - 1);
 }
 
-void MouseInputFilter::set_output_size(const SkISize& size) {
-  output_max_ = SkISize::Make(size.width() - 1, size.height() - 1);
+void MouseInputFilter::set_output_size(const webrtc::DesktopSize& size) {
+  output_max_.set(size.width() - 1, size.height() - 1);
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/mouse_input_filter.h b/remoting/protocol/mouse_input_filter.h
index f83af93..47dae114 100644
--- a/remoting/protocol/mouse_input_filter.h
+++ b/remoting/protocol/mouse_input_filter.h
@@ -7,8 +7,7 @@
 
 #include "base/compiler_specific.h"
 #include "remoting/protocol/input_filter.h"
-#include "third_party/skia/include/core/SkTypes.h"
-#include "third_party/skia/include/core/SkSize.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 namespace remoting {
 namespace protocol {
@@ -23,17 +22,17 @@
   virtual ~MouseInputFilter();
 
   // Specify the input dimensions for mouse events.
-  void set_input_size(const SkISize& size);
+  void set_input_size(const webrtc::DesktopSize& size);
 
   // Specify the output dimensions.
-  void set_output_size(const SkISize& size);
+  void set_output_size(const webrtc::DesktopSize& size);
 
   // InputStub overrides.
   virtual void InjectMouseEvent(const protocol::MouseEvent& event) OVERRIDE;
 
  private:
-  SkISize input_max_;
-  SkISize output_max_;
+  webrtc::DesktopSize input_max_;
+  webrtc::DesktopSize output_max_;
 
   DISALLOW_COPY_AND_ASSIGN(MouseInputFilter);
 };
diff --git a/remoting/protocol/mouse_input_filter_unittest.cc b/remoting/protocol/mouse_input_filter_unittest.cc
index 376decd..6c989302 100644
--- a/remoting/protocol/mouse_input_filter_unittest.cc
+++ b/remoting/protocol/mouse_input_filter_unittest.cc
@@ -8,7 +8,7 @@
 #include "remoting/protocol/protocol_mock_objects.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkPoint.h"
+#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
 
 using ::testing::_;
 using ::testing::InSequence;
@@ -28,16 +28,22 @@
 }
 
 static void InjectTestSequence(InputStub* input_stub) {
-  static const SkIPoint input_sequence[] = {
+  struct Point {
+    int x;
+    int y;
+  };
+  static const Point input_sequence[] = {
     {-5, 10}, {0, 10}, {-1, 10}, {15, 40}, {15, 45}, {15, 39}, {15, 25}
   };
-  for (unsigned int i=0; i<arraysize(input_sequence); ++i) {
-    const SkIPoint& point = input_sequence[i];
-    input_stub->InjectMouseEvent(MouseMoveEvent(point.x(), point.y()));
+  // arraysize() cannot be used here, becase Point is declared inside of a
+  // function.
+  for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(input_sequence); ++i) {
+    const Point& point = input_sequence[i];
+    input_stub->InjectMouseEvent(MouseMoveEvent(point.x, point.y));
   }
-  for (unsigned int i=0; i<arraysize(input_sequence); ++i) {
-    const SkIPoint& point = input_sequence[i];
-    input_stub->InjectMouseEvent(MouseMoveEvent(point.y(), point.x()));
+  for (unsigned int i = 0; i < ARRAYSIZE_UNSAFE(input_sequence); ++i) {
+    const Point& point = input_sequence[i];
+    input_stub->InjectMouseEvent(MouseMoveEvent(point.y, point.x));
   }
 }
 
@@ -56,7 +62,7 @@
 TEST(MouseInputFilterTest, InputDimensionsZero) {
   MockInputStub mock_stub;
   MouseInputFilter mouse_filter(&mock_stub);
-  mouse_filter.set_output_size(SkISize::Make(50,50));
+  mouse_filter.set_output_size(webrtc::DesktopSize(50, 50));
 
   EXPECT_CALL(mock_stub, InjectMouseEvent(_))
       .Times(0);
@@ -68,7 +74,7 @@
 TEST(MouseInputFilterTest, OutputDimensionsZero) {
   MockInputStub mock_stub;
   MouseInputFilter mouse_filter(&mock_stub);
-  mouse_filter.set_input_size(SkISize::Make(50,50));
+  mouse_filter.set_input_size(webrtc::DesktopSize(50, 50));
 
   EXPECT_CALL(mock_stub, InjectMouseEvent(_))
       .Times(0);
@@ -80,8 +86,8 @@
 TEST(MouseInputFilterTest, NoScalingOrClipping) {
   MockInputStub mock_stub;
   MouseInputFilter mouse_filter(&mock_stub);
-  mouse_filter.set_output_size(SkISize::Make(40,40));
-  mouse_filter.set_input_size(SkISize::Make(40,40));
+  mouse_filter.set_output_size(webrtc::DesktopSize(40,40));
+  mouse_filter.set_input_size(webrtc::DesktopSize(40,40));
 
   {
     InSequence s;
@@ -108,8 +114,8 @@
 TEST(MouseInputFilterTest, UpScalingAndClamping) {
   MockInputStub mock_stub;
   MouseInputFilter mouse_filter(&mock_stub);
-  mouse_filter.set_output_size(SkISize::Make(80,80));
-  mouse_filter.set_input_size(SkISize::Make(40,40));
+  mouse_filter.set_output_size(webrtc::DesktopSize(80, 80));
+  mouse_filter.set_input_size(webrtc::DesktopSize(40, 40));
 
   {
     InSequence s;
@@ -136,8 +142,8 @@
 TEST(MouseInputFilterTest, DownScalingAndClamping) {
   MockInputStub mock_stub;
   MouseInputFilter mouse_filter(&mock_stub);
-  mouse_filter.set_output_size(SkISize::Make(30,30));
-  mouse_filter.set_input_size(SkISize::Make(40,40));
+  mouse_filter.set_output_size(webrtc::DesktopSize(30, 30));
+  mouse_filter.set_input_size(webrtc::DesktopSize(40, 40));
 
   {
     InSequence s;