aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkCanvas.h4
-rw-r--r--include/utils/SkNoDrawCanvas.h2
-rw-r--r--src/core/SkCanvas.cpp56
-rw-r--r--src/core/SkDevice.h66
-rw-r--r--tools/remote_demo.cpp59
5 files changed, 118 insertions, 69 deletions
diff --git a/include/core/SkCanvas.h b/include/core/SkCanvas.h
index a426d1e546..e90408dc33 100644
--- a/include/core/SkCanvas.h
+++ b/include/core/SkCanvas.h
@@ -2445,6 +2445,7 @@ public:
void private_draw_shadow_rec(const SkPath&, const SkDrawShadowRec&);
+
protected:
// default impl defers to getDevice()->newSurface(info)
virtual sk_sp<SkSurface> onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props);
@@ -2559,6 +2560,8 @@ protected:
bool clipRectBounds(const SkRect* bounds, SaveLayerFlags flags, SkIRect* intersection,
const SkImageFilter* imageFilter = nullptr);
+ SkBaseDevice* getTopDevice() const;
+
private:
/** After calling saveLayer(), there can be any number of devices that make
up the top-most drawing area. LayerIter can be used to iterate through
@@ -2620,7 +2623,6 @@ private:
}
SkBaseDevice* getDevice() const;
- SkBaseDevice* getTopDevice() const;
class MCRec;
diff --git a/include/utils/SkNoDrawCanvas.h b/include/utils/SkNoDrawCanvas.h
index 7475956704..4c67226946 100644
--- a/include/utils/SkNoDrawCanvas.h
+++ b/include/utils/SkNoDrawCanvas.h
@@ -29,6 +29,8 @@ public:
// TODO: investigate the users of this ctor.
SkNoDrawCanvas(const SkIRect&);
+ explicit SkNoDrawCanvas(SkBaseDevice* device);
+
// Optimization to reset state to be the same as after construction.
void resetCanvas(int width, int height) {
resetForNextPicture(SkIRect::MakeWH(width, height));
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 2f31335286..24a6d4ab26 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -52,58 +52,6 @@
#define RETURN_ON_NULL(ptr) do { if (nullptr == (ptr)) return; } while (0)
#define RETURN_ON_FALSE(pred) do { if (!(pred)) return; } while (0)
-class SkNoPixelsDevice : public SkBaseDevice {
-public:
- SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props)
- : SkBaseDevice(SkImageInfo::MakeUnknown(bounds.width(), bounds.height()), props)
- {
- // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage
- //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
- }
-
- void resetForNextPicture(const SkIRect& bounds) {
- //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
- 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&, SkScalar x, SkScalar y, 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(const SkVertices*, SkBlendMode, const SkPaint&) override {}
-
-private:
- typedef SkBaseDevice INHERITED;
-};
-
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
@@ -974,7 +922,6 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
return true;
}
-
int SkCanvas::saveLayer(const SkRect* bounds, const SkPaint* paint) {
return this->saveLayer(SaveLayerRec(bounds, paint, 0));
}
@@ -2907,6 +2854,9 @@ SkNoDrawCanvas::SkNoDrawCanvas(int width, int height)
SkNoDrawCanvas::SkNoDrawCanvas(const SkIRect& bounds)
: INHERITED(bounds, kConservativeRasterClip_InitFlag) {}
+SkNoDrawCanvas::SkNoDrawCanvas(SkBaseDevice *device)
+ : INHERITED(device) {}
+
SkCanvas::SaveLayerStrategy SkNoDrawCanvas::getSaveLayerStrategy(const SaveLayerRec& rec) {
(void)this->INHERITED::getSaveLayerStrategy(rec);
return kNoLayer_SaveLayerStrategy;
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index c7b993cf22..6739230115 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -11,6 +11,7 @@
#include "SkRefCnt.h"
#include "SkCanvas.h"
#include "SkColor.h"
+#include "SkRegion.h"
#include "SkSurfaceProps.h"
class SkBitmap;
@@ -20,7 +21,6 @@ class SkImageFilterCache;
struct SkIRect;
class SkMatrix;
class SkRasterHandleAllocator;
-class SkRegion;
class SkSpecialImage;
class SkBaseDevice : public SkRefCnt {
@@ -125,6 +125,12 @@ public:
void setGlobalCTM(const SkMatrix& ctm);
virtual void validateDevBounds(const SkIRect&) {}
+ /**
+ * Returns the text-related flags, possibly modified based on the state of the
+ * device (e.g. support for LCD).
+ */
+ uint32_t filterTextFlags(const SkPaint&) const;
+
protected:
enum TileUsage {
kPossible_TileUsage, //!< the created device may be drawn tiled
@@ -135,12 +141,6 @@ protected:
uint32_t fFlags; // SkPaint::getFlags()
};
- /**
- * Returns the text-related flags, possibly modified based on the state of the
- * device (e.g. support for LCD).
- */
- uint32_t filterTextFlags(const SkPaint&) const;
-
virtual bool onShouldDisableLCD(const SkPaint&) const { return false; }
virtual void onSave() {}
@@ -390,6 +390,58 @@ private:
typedef SkRefCnt INHERITED;
};
+class SkNoPixelsDevice : public SkBaseDevice {
+public:
+ SkNoPixelsDevice(const SkIRect& bounds, const SkSurfaceProps& props)
+ : SkBaseDevice(SkImageInfo::MakeUnknown(bounds.width(), bounds.height()), props)
+ {
+ // this fails if we enable this assert: DiscardableImageMapTest.GetDiscardableImagesInRectMaxImage
+ //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
+ }
+
+ void resetForNextPicture(const SkIRect& bounds) {
+ //SkASSERT(bounds.width() >= 0 && bounds.height() >= 0);
+ 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&, SkScalar x, SkScalar y, 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(const SkVertices*, SkBlendMode, const SkPaint&) override {}
+
+private:
+ typedef SkBaseDevice INHERITED;
+};
+
class SkAutoDeviceCTMRestore : SkNoncopyable {
public:
SkAutoDeviceCTMRestore(SkBaseDevice* device, const SkMatrix& ctm)
diff --git a/tools/remote_demo.cpp b/tools/remote_demo.cpp
index b8cfdc76f7..8ff7d2986d 100644
--- a/tools/remote_demo.cpp
+++ b/tools/remote_demo.cpp
@@ -21,6 +21,7 @@
#include "SkTextBlobRunIterator.h"
#include "SkGlyphCache.h"
#include "SkDrawFilter.h"
+#include "SkDevice.h"
#include <type_traits>
#include <chrono>
@@ -51,8 +52,13 @@ static bool gUseGpu = true;
static bool gPurgeFontCaches = true;
static bool gUseProcess = true;
+static int gFontMetrics;
+static int gMetricsImage;
+static int gPath;
+
enum direction : int {kRead = 0, kWrite = 1};
+#define INSTRUMENT 0
template <typename T>
class SkArraySlice : public std::tuple<const T*, size_t> {
@@ -300,6 +306,18 @@ public:
};
};
+
+class TrackLayerDevice : public SkNoPixelsDevice {
+public:
+ TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props)
+ : SkNoPixelsDevice(bounds, props) { }
+ SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override {
+ const SkSurfaceProps surfaceProps(this->surfaceProps().flags(), cinfo.fPixelGeometry);
+ return new TrackLayerDevice(this->getGlobalBounds(), surfaceProps);
+ }
+};
+
+
class TextBlobFilterCanvas : public SkNoDrawCanvas {
public:
struct StrikeSpec {
@@ -323,7 +341,7 @@ public:
const SkMatrix& deviceMatrix,
const SkSurfaceProps& props,
SkScalerContextFlags flags)
- : SkNoDrawCanvas(width, height)
+ : SkNoDrawCanvas{new TrackLayerDevice{SkIRect::MakeWH(width, height), props}}
, fDeviceMatrix{deviceMatrix}
, fSurfaceProps{props}
, fScalerContextFlags{flags} { }
@@ -422,6 +440,10 @@ public:
protected:
+ SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
+ return kFullLayer_SaveLayerStrategy;
+ }
+
void onDrawTextBlob(
const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) override
{
@@ -433,6 +455,7 @@ protected:
// applyFontToPaint() always overwrites the exact same attributes,
// so it is safe to not re-seed the paint for this reason.
it.applyFontToPaint(&runPaint);
+ runPaint.setFlags(this->getTopDevice()->filterTextFlags(runPaint));
if (auto looper = runPaint.getLooper()) {
this->processLooper(position, it, runPaint, looper, this);
} else {
@@ -441,6 +464,16 @@ protected:
}
}
+ void onDrawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {
+ SK_ABORT("DrawText");
+ }
+ void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint&) override {
+ SK_ABORT("DrawPosText");
+ }
+ void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override {
+ SK_ABORT("DrawPosTextH");
+ }
+
private:
using PosFn = SkPoint(*)(int index, const SkScalar* pos);
using MapFn = SkPoint(*)(const SkMatrix& m, SkPoint pt);
@@ -633,13 +666,14 @@ public:
void generateFontMetrics(const SkTypefaceProxy& tf,
const SkScalerContextRec& rec,
SkPaint::FontMetrics* metrics) override {
+ gFontMetrics += 1;
//SK_ABORT("generateFontMetrics should not be called.");
// Send generateFontMetrics
Op* op = this->startOpWrite(OpCode::kFontMetrics, tf, rec);
fTransport->endWrite();
-#if 1
+#if INSTRUMENT
SkScalerContextRecDescriptor rd{rec};
std::cout << " metrics font op rec tf: " << rec.fFontID
<< " tf id: " << tf.fontID()
@@ -656,15 +690,16 @@ public:
const SkScalerContextRec& rec,
SkArenaAlloc* alloc,
SkGlyph* glyph) override {
+ gMetricsImage += 1;
//SK_ABORT("generateMetricsAndImage should not be called.");
// Send generateMetricsAndImage
SkScalerContextRecDescriptor rd{rec};
-#if 1
+#if INSTRUMENT
std::cout << " metrics image op rec tf: " << rec.fFontID
<< " tf id: " << tf.fontID()
<< " rec: " << rd.desc().getChecksum()
- << " glyphid: " << glyph->getPackedID().getPackedID()
+ << " glyphid: " << glyph->getPackedID().getPackedID() << "\n"
<< rec.dump().c_str() << std::endl;
#endif
Op* op = this->startOpWrite(OpCode::kGlyphMetricsAndImage, tf, rec);
@@ -690,6 +725,7 @@ public:
void generatePath(const SkTypefaceProxy& tf,
const SkScalerContextRec& rec,
SkGlyphID glyph, SkPath* path) override {
+ gPath += 1;
// Send generatePath
SkScalerContextRecDescriptor rd{rec};
@@ -722,7 +758,7 @@ static void prepopulate_cache(
sk_sp<SkPicture> pic,
TextBlobFilterCanvas* filter) {
- filter->drawPicture(pic);
+ pic->playback(filter);
transport->startEmplace<Op>(OpCode::kPrepopulateCache, SkFontID{0},
SkScalerContextRec{});
@@ -747,7 +783,7 @@ static void prepopulate_cache(
};
strike = SkGlyphCache::CreateStrikeExclusive(*desc,creator);
}
-#if 1
+#if INSTRUMENT
std::cout << std::hex << "prepop cache " << (intptr_t)cache
<< " desc: " << desc->getChecksum()
<< " typeface id: " << tf->uniqueID()
@@ -771,7 +807,9 @@ static void prepopulate_cache(
// needed for font metrics mistake.
Transport in = Transport::DoubleBuffer(*transport);
+#if INSTRUMENT
SkDebugf("========= Sending prep cache ========\n");
+#endif
in.startRead();
filter->readDataFromTransport(&in, perStrike, perGlyph, finishStrike);
@@ -797,7 +835,8 @@ static void final_draw(std::string outFilename,
SkMatrix deviceMatrix = SkMatrix::I();
// kFakeGammaAndBoostContrast
TextBlobFilterCanvas filter(
- r.width(), r.height(), deviceMatrix, s->props(), SkScalerContextFlags::kFakeGammaAndBoostContrast);
+ r.width(), r.height(), deviceMatrix, s->props(),
+ SkScalerContextFlags::kFakeGammaAndBoostContrast);
if (cache != nullptr) {
for (int i = 0; i < 0; i++) {
@@ -815,7 +854,7 @@ static void final_draw(std::string outFilename,
}
std::chrono::duration<double> total_seconds{0.0};
- for (int i = 0; i < 1; i++) { // 20
+ for (int i = 0; i < 100; i++) { // 20
if (gPurgeFontCaches) {
SkGraphics::PurgeFontCache();
}
@@ -860,6 +899,10 @@ static void gpu(int readFd, int writeFd) {
rc.prepareDeserializeProcs(&procs);
final_draw("test.png", &transport, &procs, picData.get(), &rc);
+
+ if (gFontMetrics + gMetricsImage + gPath > 0) {
+ fprintf(stderr, "exceptions - fm: %d mi: %d p: %d\n", gFontMetrics, gMetricsImage, gPath);
+ }
}
static int renderer(