special device for not drawing -- performs no clipping
authorMike Reed <reed@google.com>
Wed, 8 Mar 2017 16:29:33 +0000 (11:29 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Wed, 8 Mar 2017 17:03:13 +0000 (17:03 +0000)
Running nanobench clip_overhead_recording_lite

Before : 240us
After  : 177us

BUG=skia:6214

Change-Id: I9ae6f9170c151798ffdc6c584a48b08cc7705d6b
Reviewed-on: https://skia-review.googlesource.com/9409
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Derek Sollenberger <djsollen@google.com>
src/core/SkBitmapDevice.cpp
src/core/SkBitmapDevice.h
src/core/SkCanvas.cpp
src/core/SkDevice.h

index 89a0265..b775783 100644 (file)
@@ -130,14 +130,6 @@ SkBitmapDevice* SkBitmapDevice::Create(const SkImageInfo& origInfo,
     return new SkBitmapDevice(bitmap, surfaceProps, hndl);
 }
 
-void SkBitmapDevice::setNewSize(const SkISize& size) {
-    SkASSERT(!fBitmap.pixelRef());
-    fBitmap.setInfo(fBitmap.info().makeWH(size.fWidth, size.fHeight));
-    this->privateResize(fBitmap.info().width(), fBitmap.info().height());
-
-    fRCStack.setNewSize(size.fWidth, size.fHeight);
-}
-
 void SkBitmapDevice::replaceBitmapBackendForRasterSurface(const SkBitmap& bm) {
     SkASSERT(bm.width() == fBitmap.width());
     SkASSERT(bm.height() == fBitmap.height());
index a97ad01..d6b5127 100644 (file)
@@ -163,8 +163,6 @@ private:
     void*       fRasterHandle = nullptr;
     SkRasterClipStack  fRCStack;
 
-    void setNewSize(const SkISize&);  // Used by SkCanvas for resetForNextPicture().
-
     typedef SkBaseDevice INHERITED;
 };
 
index daefeeb..c3e6aa6 100644 (file)
 
 #define RETURN_ON_NULL(ptr)     do { if (nullptr == (ptr)) return; } while (0)
 
+class SkNoPixelsDevice : public SkBaseDevice {
+public:
+    SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props)
+        : SkBaseDevice(SkImageInfo::MakeUnknown(bounds.width(), bounds.height()), props)
+    {}
+
+    void resetForNextPicture(const SkIRect& bounds) {
+        this->privateResize(bounds.width(), bounds.height());
+    }
+
+protected:
+    // We don't track the clip at all (for performance), but we have to respond to some queries.
+    // We pretend to be wide-open. We could pretend to always be empty, but that *seems* worse.
+    void onSave() override {}
+    void onRestore() override {}
+    void onClipRect(const SkRect& rect, SkClipOp, bool aa) override {}
+    void onClipRRect(const SkRRect& rrect, SkClipOp, bool aa) override {}
+    void onClipPath(const SkPath& path, SkClipOp, bool aa) override {}
+    void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override {}
+    void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override {}
+    bool onClipIsAA() const override { return false; }
+    void onAsRgnClip(SkRegion* rgn) const override {
+        rgn->setRect(SkIRect::MakeWH(this->width(), this->height()));
+    }
+    ClipType onGetClipType() const override {
+        return kRect_ClipType;
+    }
+
+    void drawPaint(const SkPaint& paint) override {}
+    void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&) override {}
+    void drawRect(const SkRect&, const SkPaint&) override {}
+    void drawOval(const SkRect&, const SkPaint&) override {}
+    void drawRRect(const SkRRect&, const SkPaint&) override {}
+    void drawPath(const SkPath&, const SkPaint&, const SkMatrix*, bool) override {}
+    void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override {}
+    void drawSprite(const SkBitmap&, int, int, const SkPaint&) override {}
+    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint&,
+                        SkCanvas::SrcRectConstraint) override {}
+    void drawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {}
+    void drawPosText(const void*, size_t, const SkScalar[], int, const SkPoint&,
+                     const SkPaint&) override {}
+    void drawDevice(SkBaseDevice*, int, int, const SkPaint&) override {}
+    void drawVertices(SkCanvas::VertexMode, int, const SkPoint[], const SkPoint[], const SkColor[],
+                      SkBlendMode, const uint16_t[], int, const SkPaint&) override {}
+
+private:
+    typedef SkBaseDevice INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 /*
  *  Return true if the drawing this rect would hit every pixels in the canvas.
  *
@@ -578,8 +629,8 @@ void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
     fMCRec->reset(bounds);
 
     // We're peering through a lot of structs here.  Only at this scope do we
-    // know that the device is an SkBitmapDevice (really an SkNoPixelsBitmapDevice).
-    static_cast<SkBitmapDevice*>(fMCRec->fLayer->fDevice)->setNewSize(bounds.size());
+    // know that the device is a SkNoPixelsDevice.
+    static_cast<SkNoPixelsDevice*>(fMCRec->fLayer->fDevice)->resetForNextPicture(bounds);
     fDeviceClipBounds = qr_clip_bounds(bounds);
     fIsScaleTranslate = true;
 }
@@ -631,32 +682,13 @@ SkCanvas::SkCanvas()
     this->init(nullptr, kDefault_InitFlags);
 }
 
-static SkBitmap make_nopixels(int width, int height) {
-    SkBitmap bitmap;
-    bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
-    return bitmap;
-}
-
-class SkNoPixelsBitmapDevice : public SkBitmapDevice {
-public:
-    SkNoPixelsBitmapDevice(const SkIRect& bounds, const SkSurfaceProps& surfaceProps)
-        : INHERITED(make_nopixels(bounds.width(), bounds.height()), surfaceProps)
-    {
-        this->setOrigin(SkMatrix::I(), bounds.x(), bounds.y());
-    }
-
-private:
-
-    typedef SkBitmapDevice INHERITED;
-};
-
 SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(SkSurfacePropsCopyOrDefault(props))
 {
     inc_canvas();
 
-    this->init(new SkNoPixelsBitmapDevice(SkIRect::MakeWH(width, height), fProps),
+    this->init(new SkNoPixelsDevice(SkIRect::MakeWH(width, height), fProps),
                kDefault_InitFlags)->unref();
 }
 
@@ -666,7 +698,7 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
 {
     inc_canvas();
 
-    this->init(new SkNoPixelsBitmapDevice(bounds, fProps), flags)->unref();
+    this->init(new SkNoPixelsDevice(bounds, fProps), flags)->unref();
 }
 
 SkCanvas::SkCanvas(SkBaseDevice* device)
index cb727ae..a8a68b6 100644 (file)
@@ -376,6 +376,7 @@ private:
 
     virtual SkImageFilterCache* getImageFilterCache() { return NULL; }
 
+    friend class SkNoPixelsDevice;
     friend class SkBitmapDevice;
     void privateResize(int w, int h) {
         *const_cast<SkImageInfo*>(&fInfo) = fInfo.makeWH(w, h);