[go: nahoru, domu]

cc: Make PaintCanvas abstract

This is for the goal of having a separate implementation for recording
vs pass through to Skia.  Right now, there's only a single
implementation of PaintCanvas (SkiaPaintCanvas), but a newer
RecordPaintCanvas will be added after this patch that PaintRecorder
will use.

Virtualization here adds a little bit of overhead (0.5% record time on
linux 10k), but should be able to be recovered in future patches.
There's not much option here in terms of how to stage this patch, so
this regression will just need to be eaten in the short term.

BUG=671433

CQ_INCLUDE_TRYBOTS=master.tryserver.blink:linux_trusty_blink_rel;master.tryserver.chromium.linux:linux_layout_tests_slimming_paint_v2

Review-Url: https://codereview.chromium.org/2752593002
Cr-Commit-Position: refs/heads/master@{#457169}
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index f4379bc..cae112e 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -5,17 +5,12 @@
 #ifndef CC_PAINT_PAINT_CANVAS_H_
 #define CC_PAINT_PAINT_CANVAS_H_
 
-#include <memory>
-
 #include "base/compiler_specific.h"
-#include "base/logging.h"
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "cc/paint/paint_export.h"
-#include "cc/paint/paint_flags.h"
 #include "cc/paint/paint_record.h"
 #include "third_party/skia/include/core/SkCanvas.h"
-#include "third_party/skia/include/utils/SkNoDrawCanvas.h"
 
 namespace cc {
 
@@ -23,205 +18,127 @@
 
 class CC_PAINT_EXPORT PaintCanvas {
  public:
-  // TODO(enne): remove all constructors but the one that takes an SkCanvas
-  // and a future one that will take a PaintOpBuffer to build a PaintRecord.
-  explicit PaintCanvas(SkCanvas* canvas);
-  explicit PaintCanvas(const SkBitmap& bitmap);
-  explicit PaintCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props);
-  ~PaintCanvas();
+  virtual SkMetaData& getMetaData() = 0;
+  virtual SkImageInfo imageInfo() const = 0;
 
-  ALWAYS_INLINE SkMetaData& getMetaData() { return canvas_->getMetaData(); }
-  ALWAYS_INLINE SkImageInfo imageInfo() const { return canvas_->imageInfo(); }
-  ALWAYS_INLINE bool getProps(SkSurfaceProps* props) const {
-    return canvas_->getProps(props);
-  }
   // TODO(enne): It would be nice to get rid of flush() entirely, as it
   // doesn't really make sense for recording.  However, this gets used by
   // SkCanvasVideoRenderer which takes a PaintCanvas to paint both
   // software and hardware video.  This is super entangled with ImageBuffer
   // and canvas/video painting in Blink where the same paths are used for
   // both recording and gpu work.
-  ALWAYS_INLINE void flush() { canvas_->flush(); }
+  virtual void flush() = 0;
 
-  ALWAYS_INLINE SkISize getBaseLayerSize() const {
-    return canvas_->getBaseLayerSize();
+  virtual SkISize getBaseLayerSize() const = 0;
+  virtual bool peekPixels(SkPixmap* pixmap) = 0;
+  virtual bool readPixels(const SkImageInfo& dest_info,
+                          void* dest_pixels,
+                          size_t dest_row_bytes,
+                          int src_x,
+                          int src_y) = 0;
+  virtual bool readPixels(SkBitmap* bitmap, int src_x, int src_y) = 0;
+  virtual bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) = 0;
+  virtual bool writePixels(const SkImageInfo& info,
+                           const void* pixels,
+                           size_t row_bytes,
+                           int x,
+                           int y) = 0;
+  virtual int save() = 0;
+  virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
+  virtual int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) = 0;
+
+  virtual void restore() = 0;
+  virtual int getSaveCount() const = 0;
+  virtual void restoreToCount(int save_count) = 0;
+  virtual void translate(SkScalar dx, SkScalar dy) = 0;
+  virtual void scale(SkScalar sx, SkScalar sy) = 0;
+  virtual void rotate(SkScalar degrees) = 0;
+  virtual void rotate(SkScalar degrees, SkScalar px, SkScalar py) = 0;
+  virtual void concat(const SkMatrix& matrix) = 0;
+  virtual void setMatrix(const SkMatrix& matrix) = 0;
+  virtual void resetMatrix() = 0;
+
+  virtual void clipRect(const SkRect& rect,
+                        SkClipOp op,
+                        bool do_anti_alias) = 0;
+  void clipRect(const SkRect& rect, SkClipOp op) { clipRect(rect, op, false); }
+  void clipRect(const SkRect& rect, bool do_anti_alias) {
+    clipRect(rect, SkClipOp::kIntersect, do_anti_alias);
   }
-  ALWAYS_INLINE bool peekPixels(SkPixmap* pixmap) {
-    return canvas_->peekPixels(pixmap);
-  }
-  ALWAYS_INLINE bool readPixels(const SkImageInfo& dest_info,
-                                void* dest_pixels,
-                                size_t dest_row_bytes,
-                                int src_x,
-                                int src_y) {
-    return canvas_->readPixels(dest_info, dest_pixels, dest_row_bytes, src_x,
-                               src_y);
-  }
-  ALWAYS_INLINE bool readPixels(SkBitmap* bitmap, int src_x, int src_y) {
-    return canvas_->readPixels(bitmap, src_x, src_y);
-  }
-  ALWAYS_INLINE bool readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
-    return canvas_->readPixels(srcRect, bitmap);
-  }
-  ALWAYS_INLINE bool writePixels(const SkImageInfo& info,
-                                 const void* pixels,
-                                 size_t row_bytes,
-                                 int x,
-                                 int y) {
-    return canvas_->writePixels(info, pixels, row_bytes, x, y);
-  }
-  ALWAYS_INLINE int save() { return canvas_->save(); }
-  ALWAYS_INLINE int saveLayer(const SkRect* bounds, const PaintFlags* flags) {
-    return canvas_->saveLayer(bounds, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE int saveLayer(const SkRect& bounds, const PaintFlags* flags) {
-    return canvas_->saveLayer(bounds, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE int saveLayerPreserveLCDTextRequests(const SkRect* bounds,
-                                                     const PaintFlags* flags) {
-    return canvas_->saveLayerPreserveLCDTextRequests(bounds, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
-    return canvas_->saveLayerAlpha(bounds, alpha);
+  void clipRect(const SkRect& rect) {
+    clipRect(rect, SkClipOp::kIntersect, false);
   }
 
-  ALWAYS_INLINE void restore() { canvas_->restore(); }
-  ALWAYS_INLINE int getSaveCount() const { return canvas_->getSaveCount(); }
-  ALWAYS_INLINE void restoreToCount(int save_count) {
-    canvas_->restoreToCount(save_count);
+  virtual void clipRRect(const SkRRect& rrect,
+                         SkClipOp op,
+                         bool do_anti_alias) = 0;
+  void clipRRect(const SkRRect& rrect, bool do_anti_alias) {
+    clipRRect(rrect, SkClipOp::kIntersect, do_anti_alias);
   }
-  ALWAYS_INLINE void translate(SkScalar dx, SkScalar dy) {
-    canvas_->translate(dx, dy);
+  void clipRRect(const SkRRect& rrect, SkClipOp op) {
+    clipRRect(rrect, op, false);
   }
-  ALWAYS_INLINE void scale(SkScalar sx, SkScalar sy) { canvas_->scale(sx, sy); }
-  ALWAYS_INLINE void rotate(SkScalar degrees) { canvas_->rotate(degrees); }
-  ALWAYS_INLINE void rotate(SkScalar degrees, SkScalar px, SkScalar py) {
-    canvas_->rotate(degrees, px, py);
+  void clipRRect(const SkRRect& rrect) {
+    clipRRect(rrect, SkClipOp::kIntersect, false);
   }
-  ALWAYS_INLINE void skew(SkScalar sx, SkScalar sy) { canvas_->skew(sx, sy); }
-  ALWAYS_INLINE void concat(const SkMatrix& matrix) { canvas_->concat(matrix); }
-  ALWAYS_INLINE void setMatrix(const SkMatrix& matrix) {
-    canvas_->setMatrix(matrix);
-  }
-  ALWAYS_INLINE void resetMatrix() { canvas_->resetMatrix(); }
-  ALWAYS_INLINE void clipRect(const SkRect& rect,
-                              SkClipOp op,
-                              bool do_anti_alias = false) {
-    canvas_->clipRect(rect, op, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipRect(const SkRect& rect, bool do_anti_alias = false) {
-    canvas_->clipRect(rect, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipRRect(const SkRRect& rrect,
-                               SkClipOp op,
-                               bool do_anti_alias) {
-    canvas_->clipRRect(rrect, op, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipRRect(const SkRRect& rrect, SkClipOp op) {
-    canvas_->clipRRect(rrect, op);
-  }
-  ALWAYS_INLINE void clipRRect(const SkRRect& rrect,
-                               bool do_anti_alias = false) {
-    canvas_->clipRRect(rrect, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipPath(const SkPath& path,
-                              SkClipOp op,
-                              bool do_anti_alias) {
-    canvas_->clipPath(path, op, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipPath(const SkPath& path, SkClipOp op) {
-    canvas_->clipPath(path, op);
-  }
-  ALWAYS_INLINE void clipPath(const SkPath& path, bool do_anti_alias = false) {
-    canvas_->clipPath(path, do_anti_alias);
-  }
-  ALWAYS_INLINE void clipRegion(const SkRegion& device_region,
-                                SkClipOp op = SkClipOp::kIntersect) {
-    canvas_->clipRegion(device_region, op);
-  }
-  ALWAYS_INLINE bool quickReject(const SkRect& rect) const {
-    return canvas_->quickReject(rect);
-  }
-  ALWAYS_INLINE bool quickReject(const SkPath& path) const {
-    return canvas_->quickReject(path);
-  }
-  ALWAYS_INLINE SkRect getLocalClipBounds() const {
-    return canvas_->getLocalClipBounds();
-  }
-  ALWAYS_INLINE bool getLocalClipBounds(SkRect* bounds) const {
-    return canvas_->getLocalClipBounds(bounds);
-  }
-  ALWAYS_INLINE SkIRect getDeviceClipBounds() const {
-    return canvas_->getDeviceClipBounds();
-  }
-  ALWAYS_INLINE bool getDeviceClipBounds(SkIRect* bounds) const {
-    return canvas_->getDeviceClipBounds(bounds);
-  }
-  ALWAYS_INLINE void drawColor(SkColor color,
-                               SkBlendMode mode = SkBlendMode::kSrcOver) {
-    canvas_->drawColor(color, mode);
-  }
-  ALWAYS_INLINE void clear(SkColor color) { canvas_->clear(color); }
-  ALWAYS_INLINE void discard() { canvas_->discard(); }
 
-  ALWAYS_INLINE void drawLine(SkScalar x0,
-                              SkScalar y0,
-                              SkScalar x1,
-                              SkScalar y1,
-                              const PaintFlags& flags) {
-    canvas_->drawLine(x0, y0, x1, y1, ToSkPaint(flags));
+  virtual void clipPath(const SkPath& path,
+                        SkClipOp op,
+                        bool do_anti_alias) = 0;
+  void clipPath(const SkPath& path, SkClipOp op) { clipPath(path, op, false); }
+  void clipPath(const SkPath& path, bool do_anti_alias) {
+    clipPath(path, SkClipOp::kIntersect, do_anti_alias);
   }
-  ALWAYS_INLINE void drawRect(const SkRect& rect, const PaintFlags& flags) {
-    canvas_->drawRect(rect, ToSkPaint(flags));
+
+  virtual bool quickReject(const SkRect& rect) const = 0;
+  virtual bool quickReject(const SkPath& path) const = 0;
+  virtual SkRect getLocalClipBounds() const = 0;
+  virtual bool getLocalClipBounds(SkRect* bounds) const = 0;
+  virtual SkIRect getDeviceClipBounds() const = 0;
+  virtual bool getDeviceClipBounds(SkIRect* bounds) const = 0;
+  virtual void drawColor(SkColor color, SkBlendMode mode) = 0;
+  void drawColor(SkColor color) { drawColor(color, SkBlendMode::kSrcOver); }
+  virtual void clear(SkColor color) = 0;
+
+  virtual void drawLine(SkScalar x0,
+                        SkScalar y0,
+                        SkScalar x1,
+                        SkScalar y1,
+                        const PaintFlags& flags) = 0;
+  virtual void drawRect(const SkRect& rect, const PaintFlags& flags) = 0;
+  virtual void drawIRect(const SkIRect& rect, const PaintFlags& flags) = 0;
+  virtual void drawOval(const SkRect& oval, const PaintFlags& flags) = 0;
+  virtual void drawRRect(const SkRRect& rrect, const PaintFlags& flags) = 0;
+  virtual void drawDRRect(const SkRRect& outer,
+                          const SkRRect& inner,
+                          const PaintFlags& flags) = 0;
+  virtual void drawCircle(SkScalar cx,
+                          SkScalar cy,
+                          SkScalar radius,
+                          const PaintFlags& flags) = 0;
+  virtual void drawArc(const SkRect& oval,
+                       SkScalar start_angle,
+                       SkScalar sweep_angle,
+                       bool use_center,
+                       const PaintFlags& flags) = 0;
+  virtual void drawRoundRect(const SkRect& rect,
+                             SkScalar rx,
+                             SkScalar ry,
+                             const PaintFlags& flags) = 0;
+  virtual void drawPath(const SkPath& path, const PaintFlags& flags) = 0;
+  virtual void drawImage(const SkImage* image,
+                         SkScalar left,
+                         SkScalar top,
+                         const PaintFlags* flags) = 0;
+  void drawImage(const SkImage* image, SkScalar left, SkScalar top) {
+    drawImage(image, left, top, nullptr);
   }
-  ALWAYS_INLINE void drawIRect(const SkIRect& rect, const PaintFlags& flags) {
-    canvas_->drawIRect(rect, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawOval(const SkRect& oval, const PaintFlags& flags) {
-    canvas_->drawOval(oval, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawRRect(const SkRRect& rrect, const PaintFlags& flags) {
-    canvas_->drawRRect(rrect, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawDRRect(const SkRRect& outer,
-                                const SkRRect& inner,
-                                const PaintFlags& flags) {
-    canvas_->drawDRRect(outer, inner, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawCircle(SkScalar cx,
-                                SkScalar cy,
-                                SkScalar radius,
-                                const PaintFlags& flags) {
-    canvas_->drawCircle(cx, cy, radius, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawArc(const SkRect& oval,
-                             SkScalar start_angle,
-                             SkScalar sweep_angle,
-                             bool use_center,
-                             const PaintFlags& flags) {
-    canvas_->drawArc(oval, start_angle, sweep_angle, use_center,
-                     ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawRoundRect(const SkRect& rect,
-                                   SkScalar rx,
-                                   SkScalar ry,
-                                   const PaintFlags& flags) {
-    canvas_->drawRoundRect(rect, rx, ry, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawPath(const SkPath& path, const PaintFlags& flags) {
-    canvas_->drawPath(path, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawImage(const SkImage* image,
-                               SkScalar left,
-                               SkScalar top,
-                               const PaintFlags* flags = nullptr) {
-    canvas_->drawImage(image, left, top, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawImage(const sk_sp<SkImage>& image,
-                               SkScalar left,
-                               SkScalar top,
-                               const PaintFlags* flags = nullptr) {
-    canvas_->drawImage(image, left, top, ToSkPaint(flags));
+  virtual void drawImage(const sk_sp<SkImage>& image,
+                         SkScalar left,
+                         SkScalar top,
+                         const PaintFlags* flags) = 0;
+  void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top) {
+    drawImage(image, left, top, nullptr);
   }
 
   enum SrcRectConstraint {
@@ -229,147 +146,55 @@
     kFast_SrcRectConstraint = SkCanvas::kFast_SrcRectConstraint,
   };
 
-  ALWAYS_INLINE void drawImageRect(
-      const SkImage* image,
-      const SkRect& src,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(
-        image, src, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawImageRect(
-      const SkImage* image,
-      const SkIRect& isrc,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(
-        image, isrc, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawImageRect(
-      const SkImage* image,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(
-        image, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawImageRect(
-      const sk_sp<SkImage>& image,
-      const SkRect& src,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(
-        image, src, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawImageRect(
-      const sk_sp<SkImage>& image,
-      const SkIRect& isrc,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint cons = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(image, isrc, dst, ToSkPaint(flags),
-                           static_cast<SkCanvas::SrcRectConstraint>(cons));
-  }
-  ALWAYS_INLINE void drawImageRect(
-      const sk_sp<SkImage>& image,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint cons = kStrict_SrcRectConstraint) {
-    canvas_->drawImageRect(image, dst, ToSkPaint(flags),
-                           static_cast<SkCanvas::SrcRectConstraint>(cons));
-  }
-  ALWAYS_INLINE void drawBitmap(const SkBitmap& bitmap,
-                                SkScalar left,
-                                SkScalar top,
-                                const PaintFlags* flags = nullptr) {
-    canvas_->drawBitmap(bitmap, left, top, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawBitmapRect(
-      const SkBitmap& bitmap,
-      const SkRect& src,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawBitmapRect(
-        bitmap, src, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawBitmapRect(
-      const SkBitmap& bitmap,
-      const SkIRect& isrc,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawBitmapRect(
-        bitmap, isrc, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
-  }
-  ALWAYS_INLINE void drawBitmapRect(
-      const SkBitmap& bitmap,
-      const SkRect& dst,
-      const PaintFlags* flags,
-      SrcRectConstraint constraint = kStrict_SrcRectConstraint) {
-    canvas_->drawBitmapRect(
-        bitmap, dst, ToSkPaint(flags),
-        static_cast<SkCanvas::SrcRectConstraint>(constraint));
+  virtual void drawImageRect(const SkImage* image,
+                             const SkRect& src,
+                             const SkRect& dst,
+                             const PaintFlags* flags,
+                             SrcRectConstraint constraint) = 0;
+  virtual void drawBitmap(const SkBitmap& bitmap,
+                          SkScalar left,
+                          SkScalar top,
+                          const PaintFlags* flags) = 0;
+  void drawBitmap(const SkBitmap& bitmap, SkScalar left, SkScalar top) {
+    drawBitmap(bitmap, left, top, nullptr);
   }
 
-  ALWAYS_INLINE void drawText(const void* text,
-                              size_t byte_length,
-                              SkScalar x,
-                              SkScalar y,
-                              const PaintFlags& flags) {
-    canvas_->drawText(text, byte_length, x, y, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawPosText(const void* text,
-                                 size_t byte_length,
-                                 const SkPoint pos[],
-                                 const PaintFlags& flags) {
-    canvas_->drawPosText(text, byte_length, pos, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawTextBlob(const SkTextBlob* blob,
-                                  SkScalar x,
-                                  SkScalar y,
-                                  const PaintFlags& flags) {
-    canvas_->drawTextBlob(blob, x, y, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawTextBlob(const sk_sp<SkTextBlob>& blob,
-                                  SkScalar x,
-                                  SkScalar y,
-                                  const PaintFlags& flags) {
-    canvas_->drawTextBlob(blob, x, y, ToSkPaint(flags));
-  }
+  virtual void drawText(const void* text,
+                        size_t byte_length,
+                        SkScalar x,
+                        SkScalar y,
+                        const PaintFlags& flags) = 0;
+  virtual void drawPosText(const void* text,
+                           size_t byte_length,
+                           const SkPoint pos[],
+                           const PaintFlags& flags) = 0;
+  virtual void drawTextBlob(const SkTextBlob* blob,
+                            SkScalar x,
+                            SkScalar y,
+                            const PaintFlags& flags) = 0;
+  virtual void drawTextBlob(const sk_sp<SkTextBlob>& blob,
+                            SkScalar x,
+                            SkScalar y,
+                            const PaintFlags& flags) = 0;
 
-  ALWAYS_INLINE void drawPicture(const PaintRecord* record) {
-    canvas_->drawPicture(ToSkPicture(record));
-  }
-  ALWAYS_INLINE void drawPicture(const PaintRecord* record,
-                                 const SkMatrix* matrix,
-                                 const PaintFlags* flags) {
-    canvas_->drawPicture(ToSkPicture(record), matrix, ToSkPaint(flags));
-  }
-  ALWAYS_INLINE void drawPicture(sk_sp<PaintRecord> record) {
-    drawPicture(record.get());
-  }
+  virtual void drawPicture(const PaintRecord* record) = 0;
+  virtual void drawPicture(const PaintRecord* record,
+                           const SkMatrix* matrix,
+                           const PaintFlags* flags) = 0;
+  virtual void drawPicture(sk_sp<PaintRecord> record) = 0;
 
-  ALWAYS_INLINE bool isClipEmpty() const { return canvas_->isClipEmpty(); }
-  ALWAYS_INLINE bool isClipRect() const { return canvas_->isClipRect(); }
-  ALWAYS_INLINE const SkMatrix& getTotalMatrix() const {
-    return canvas_->getTotalMatrix();
-  }
+  virtual bool isClipEmpty() const = 0;
+  virtual bool isClipRect() const = 0;
+  virtual const SkMatrix& getTotalMatrix() const = 0;
 
   // For GraphicsContextCanvas only.  Maybe this could be rewritten?
-  ALWAYS_INLINE void temporary_internal_describeTopLayer(SkMatrix* matrix,
-                                                         SkIRect* clip_bounds) {
-    return canvas_->temporary_internal_describeTopLayer(matrix, clip_bounds);
-  }
+  virtual void temporary_internal_describeTopLayer(SkMatrix* matrix,
+                                                   SkIRect* clip_bounds) = 0;
+
+  virtual bool ToPixmap(SkPixmap* output) = 0;
+  virtual void AnnotateRectWithURL(const SkRect& rect, SkData* data) = 0;
+  virtual void AnnotateNamedDestination(const SkPoint& point, SkData* data) = 0;
+  virtual void AnnotateLinkToDestination(const SkRect& rect, SkData* data) = 0;
 
  protected:
   friend class PaintSurface;
@@ -387,18 +212,11 @@
       const SkRect& rect,
       SkData* data);
   friend CC_PAINT_EXPORT bool ToPixmap(PaintCanvas* canvas, SkPixmap* output);
-
- private:
-  SkCanvas* canvas_;
-  std::unique_ptr<SkCanvas> owned_;
-
-  DISALLOW_COPY_AND_ASSIGN(PaintCanvas);
 };
 
 class CC_PAINT_EXPORT PaintCanvasAutoRestore {
  public:
-  ALWAYS_INLINE PaintCanvasAutoRestore(PaintCanvas* canvas, bool save)
-      : canvas_(canvas) {
+  PaintCanvasAutoRestore(PaintCanvas* canvas, bool save) : canvas_(canvas) {
     if (canvas_) {
       save_count_ = canvas_->getSaveCount();
       if (save) {
@@ -407,13 +225,13 @@
     }
   }
 
-  ALWAYS_INLINE ~PaintCanvasAutoRestore() {
+  ~PaintCanvasAutoRestore() {
     if (canvas_) {
       canvas_->restoreToCount(save_count_);
     }
   }
 
-  ALWAYS_INLINE void restore() {
+  void restore() {
     if (canvas_) {
       canvas_->restoreToCount(save_count_);
       canvas_ = nullptr;