[go: nahoru, domu]

Back PaintRecord with PaintOpBuffer instead of SkPicture

Change the backing of PaintRecord to be a data structure implemented in
cc/paint instead of using SkPicture directly.  This new class cribs heavily
from SkLiteDL.

PaintRecord used to be a typedef to an SkPicture but now is a typedef to
a PaintOpBuffer.  (This leaves some flexibility to change this in the
future to an interface without having to modify all of Chromium again.)

PaintOpBuffer stores a contiguous array of ops, with the ops stored
in place.  As an optimization, the first op is stored locally in the
PaintOpBuffer itself to avoid extra allocations for small pictures.

This patch moves slow path counting from a gpu analysis canvas into
PaintOpBuffer directly.  As ops are recorded, slow paths are counted, and
a PaintRecord now knows how many ops it has.  This is about a 1.5% savings
for record time (gpu analysis was 2% and 0.5% overhead to record later).

This patch also implements the SkRecordNoopSaveLayerDrawRestores
optimization from Skia at raster time.  This takes save layer (just
opacity) / draw / restore commands and turns them into draws with
opacity.  It moves that optimization from Blink at record time inside of
CompositingRecorder and moves it to both DisplayItemList::RasterItem
and PaintOpBuffer::playback (since a save could be either a DisplayItem
or a PaintOp).  It's not as robust as Skia's solution and so misses
a few cases that Skia catches, but the rasterize and record on 10k
page agreed that performance was good enough.

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/2768143002
Cr-Commit-Position: refs/heads/master@{#468548}
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h
index 86348f0..e1fa9d0 100644
--- a/cc/paint/paint_canvas.h
+++ b/cc/paint/paint_canvas.h
@@ -11,19 +11,25 @@
 #include "build/build_config.h"
 #include "cc/paint/paint_export.h"
 #include "cc/paint/paint_image.h"
-#include "cc/paint/paint_record.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 
 namespace cc {
 
 class DisplayItemList;
 class PaintFlags;
+class PaintOpBuffer;
+
+using PaintRecord = PaintOpBuffer;
 
 class CC_PAINT_EXPORT PaintCanvas {
  public:
+  PaintCanvas() {}
   virtual ~PaintCanvas() {}
 
   virtual SkMetaData& getMetaData() = 0;
+
+  // TODO(enne): this only appears to mostly be used to determine if this is
+  // recording or not, so could be simplified or removed.
   virtual SkImageInfo imageInfo() const = 0;
 
   // TODO(enne): It would be nice to get rid of flush() entirely, as it
@@ -36,7 +42,7 @@
 
   virtual int save() = 0;
   virtual int saveLayer(const SkRect* bounds, const PaintFlags* flags) = 0;
-  virtual int saveLayerAlpha(const SkRect* bounds, U8CPU alpha) = 0;
+  virtual int saveLayerAlpha(const SkRect* bounds, uint8_t alpha) = 0;
 
   virtual void restore() = 0;
   virtual int getSaveCount() const = 0;
@@ -87,6 +93,8 @@
   virtual bool getDeviceClipBounds(SkIRect* bounds) const = 0;
   virtual void drawColor(SkColor color, SkBlendMode mode) = 0;
   void drawColor(SkColor color) { drawColor(color, SkBlendMode::kSrcOver); }
+
+  // TODO(enne): This is a synonym for drawColor with kSrc.  Remove it.
   virtual void clear(SkColor color) = 0;
 
   virtual void drawLine(SkScalar x0,
@@ -180,6 +188,9 @@
  protected:
   friend class PaintSurface;
   friend class PaintRecorder;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PaintCanvas);
 };
 
 class CC_PAINT_EXPORT PaintCanvasAutoRestore {