summaryrefslogtreecommitdiffstats
path: root/skia
diff options
context:
space:
mode:
authortomhudson@chromium.org <tomhudson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-07 22:08:23 +0000
committertomhudson@chromium.org <tomhudson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-07 22:08:23 +0000
commitc931465a982836e6399a853e03cfde4054d486d6 (patch)
tree39683ac40df5dfbc34f08226d308af9cdeb3087e /skia
parenta09a58dab96bc110dc47533a48d2691ce19738c6 (diff)
downloadchromium_src-c931465a982836e6399a853e03cfde4054d486d6.zip
chromium_src-c931465a982836e6399a853e03cfde4054d486d6.tar.gz
chromium_src-c931465a982836e6399a853e03cfde4054d486d6.tar.bz2
Implementation for cc::Picture::IsCheapInRect().
Minimal implementation for cc::Picture::IsCheapInRect() with new classes skia::AnalysisCanvas and skia::AnalysisDevice. Supercedes http://codereview.chromium.org/12184010/. Based on GatherPixelRefs. Not a good implementation yet, but it does seem to count draw calls and is right more often than a stopped clock. I'm not happy with clipping/culling; something is going very wrong there. TBR=nduca,junov,tomhudson CC=skyostil BUG=173426 Review URL: https://chromiumcodereview.appspot.com/12213018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181369 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'skia')
-rw-r--r--skia/ext/analysis_canvas.cc190
-rw-r--r--skia/ext/analysis_canvas.h113
-rw-r--r--skia/skia.gyp2
3 files changed, 305 insertions, 0 deletions
diff --git a/skia/ext/analysis_canvas.cc b/skia/ext/analysis_canvas.cc
new file mode 100644
index 0000000..72b9eeb
--- /dev/null
+++ b/skia/ext/analysis_canvas.cc
@@ -0,0 +1,190 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/debug/trace_event.h"
+#include "skia/ext/analysis_canvas.h"
+#include "third_party/skia/include/core/SkDevice.h"
+#include "third_party/skia/include/core/SkDraw.h"
+#include "third_party/skia/include/core/SkRRect.h"
+#include "ui/gfx/rect_conversions.h"
+
+namespace {
+
+// FIXME: Arbitrary number. Requires tuning & experimentation.
+// Probably requires per-platform tuning; N10 average draw call takes
+// 25x as long as Z620.
+const int gPictureCostThreshold = 1000;
+
+}
+
+namespace skia {
+
+AnalysisDevice::AnalysisDevice(const SkBitmap& bm)
+ : INHERITED(bm)
+ , estimatedCost_(0) {
+
+}
+
+AnalysisDevice::~AnalysisDevice() {
+
+}
+
+int AnalysisDevice::getEstimatedCost() const {
+ return estimatedCost_;
+}
+
+void AnalysisDevice::clear(SkColor color) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawPaint(const SkDraw&, const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawRect(const SkDraw&, const SkRect& r,
+ const SkPaint& paint) {
+ // FIXME: if there's a pending image decode & resize, more expensive
+ if (paint.getMaskFilter()) {
+ estimatedCost_ += 300;
+ }
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawOval(const SkDraw&, const SkRect& oval,
+ const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawPath(const SkDraw&, const SkPath& path,
+ const SkPaint& paint,
+ const SkMatrix* prePathMatrix ,
+ bool pathIsMutable ) {
+ // On Z620, every antialiased path costs us about 300us.
+ // We've only seen this in practice on filled paths, but
+ // we expect it to apply to all path stroking modes.
+ if (paint.getMaskFilter()) {
+ estimatedCost_ += 300;
+ }
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkIRect* srcRectOrNull,
+ const SkMatrix& matrix, const SkPaint& paint)
+ {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawBitmapRect(const SkDraw&, const SkBitmap&,
+ const SkRect* srcOrNull, const SkRect& dst,
+ const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+
+void AnalysisDevice::drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint)
+ {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) {
+ // FIXME: On Z620, every glyph cache miss costs us about 10us.
+ // We don't have a good mechanism for predicting glyph cache misses.
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+#ifdef SK_BUILD_FOR_ANDROID
+void AnalysisDevice::drawPosTextOnPath(const SkDraw& draw, const void* text,
+ size_t len,
+ const SkPoint pos[], const SkPaint& paint,
+ const SkPath& path, const SkMatrix* matrix)
+ {
+ ++estimatedCost_;
+}
+#endif
+
+void AnalysisDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
+ int vertexCount,
+ const SkPoint verts[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) {
+ ++estimatedCost_;
+}
+
+void AnalysisDevice::drawDevice(const SkDraw&, SkDevice*, int x, int y,
+ const SkPaint&) {
+ ++estimatedCost_;
+}
+
+
+
+
+AnalysisCanvas::AnalysisCanvas(AnalysisDevice* device)
+ : INHERITED(device) {
+
+}
+
+AnalysisCanvas::~AnalysisCanvas() {
+}
+
+
+bool AnalysisCanvas::isCheap() const {
+ return getEstimatedCost() < gPictureCostThreshold;
+}
+
+int AnalysisCanvas::getEstimatedCost() const {
+ return (static_cast<AnalysisDevice*>(getDevice()))->getEstimatedCost();
+}
+
+
+bool AnalysisCanvas::clipRect(const SkRect& rect, SkRegion::Op op,
+ bool doAA) {
+ return INHERITED::clipRect(rect, op, doAA);
+}
+
+bool AnalysisCanvas::clipPath(const SkPath& path, SkRegion::Op op,
+ bool doAA) {
+ return INHERITED::clipRect(path.getBounds(), op, doAA);
+}
+
+bool AnalysisCanvas::clipRRect(const SkRRect& rrect, SkRegion::Op op,
+ bool doAA) {
+ return INHERITED::clipRect(rrect.getBounds(), op, doAA);
+}
+
+int AnalysisCanvas::saveLayer(const SkRect* bounds, const SkPaint*,
+ SkCanvas::SaveFlags flags) {
+ // Actually saving a layer here could cause a new bitmap to be created
+ // and real rendering to occur.
+ int count = SkCanvas::save(flags);
+ if (bounds) {
+ INHERITED::clipRectBounds(bounds, flags, NULL);
+ }
+ return count;
+}
+
+} // namespace skia
+
+
diff --git a/skia/ext/analysis_canvas.h b/skia/ext/analysis_canvas.h
new file mode 100644
index 0000000..e2eedd2
--- /dev/null
+++ b/skia/ext/analysis_canvas.h
@@ -0,0 +1,113 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SKIA_EXT_ANALYSIS_CANVAS_H_
+#define SKIA_EXT_ANALYSIS_CANVAS_H_
+
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/core/SkDevice.h"
+
+namespace skia {
+
+class AnalysisDevice;
+
+// Does not render anything, but gathers statistics about a region
+// (specified as a clip rectangle) of an SkPicture as the picture is
+// played back through it.
+// To use: create a SkBitmap with kNo_Config, create an AnalysisDevice
+// using that bitmap, and create an AnalysisCanvas using the device.
+// Play a picture into the canvas, and then check isCheap().
+class SK_API AnalysisCanvas : public SkCanvas {
+ public:
+ AnalysisCanvas(AnalysisDevice*);
+ virtual ~AnalysisCanvas();
+
+ // Returns true if the estimated cost of drawing is below an
+ // arbitrary threshold.
+ bool isCheap() const;
+
+ // Returns the estimated cost of drawing, in arbitrary units.
+ int getEstimatedCost() const;
+
+ virtual bool clipRect(const SkRect& rect,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false) OVERRIDE;
+ virtual bool clipPath(const SkPath& path,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false) OVERRIDE;
+ virtual bool clipRRect(const SkRRect& rrect,
+ SkRegion::Op op = SkRegion::kIntersect_Op,
+ bool doAntiAlias = false) OVERRIDE;
+
+ virtual int saveLayer(const SkRect* bounds, const SkPaint*,
+ SkCanvas::SaveFlags flags) OVERRIDE;
+ private:
+ typedef SkCanvas INHERITED;
+};
+
+class SK_API AnalysisDevice : public SkDevice {
+ public:
+ AnalysisDevice(const SkBitmap& bm);
+ virtual ~AnalysisDevice();
+
+ int getEstimatedCost() const;
+
+ protected:
+ virtual void clear(SkColor color) OVERRIDE;
+ virtual void drawPaint(const SkDraw&, const SkPaint& paint) OVERRIDE;
+ virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+ size_t count, const SkPoint[],
+ const SkPaint& paint) OVERRIDE;
+ virtual void drawRect(const SkDraw&, const SkRect& r,
+ const SkPaint& paint) OVERRIDE;
+ virtual void drawOval(const SkDraw&, const SkRect& oval,
+ const SkPaint& paint) OVERRIDE;
+ virtual void drawPath(const SkDraw&, const SkPath& path,
+ const SkPaint& paint,
+ const SkMatrix* prePathMatrix = NULL,
+ bool pathIsMutable = false) OVERRIDE;
+ virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+ const SkIRect* srcRectOrNull,
+ const SkMatrix& matrix, const SkPaint& paint)
+ OVERRIDE;
+ virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+ int x, int y, const SkPaint& paint) OVERRIDE;
+ virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+ const SkRect* srcOrNull, const SkRect& dst,
+ const SkPaint& paint) OVERRIDE;
+ virtual void drawText(const SkDraw&, const void* text, size_t len,
+ SkScalar x, SkScalar y, const SkPaint& paint)
+ OVERRIDE;
+ virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
+ const SkScalar pos[], SkScalar constY,
+ int scalarsPerPos, const SkPaint& paint) OVERRIDE;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+ const SkPath& path, const SkMatrix* matrix,
+ const SkPaint& paint) OVERRIDE;
+#ifdef SK_BUILD_FOR_ANDROID
+ virtual void drawPosTextOnPath(const SkDraw& draw, const void* text,
+ size_t len,
+ const SkPoint pos[], const SkPaint& paint,
+ const SkPath& path, const SkMatrix* matrix)
+ OVERRIDE;
+#endif
+ virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode,
+ int vertexCount,
+ const SkPoint verts[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xmode,
+ const uint16_t indices[], int indexCount,
+ const SkPaint& paint) OVERRIDE;
+ virtual void drawDevice(const SkDraw&, SkDevice*, int x, int y,
+ const SkPaint&) OVERRIDE;
+
+ int estimatedCost_;
+
+ private:
+ typedef SkDevice INHERITED;
+};
+
+} // namespace skia
+
+#endif // SKIA_EXT_ANALYSIS_CANVAS_H_
+
diff --git a/skia/skia.gyp b/skia/skia.gyp
index a20e4be..f8bad83 100644
--- a/skia/skia.gyp
+++ b/skia/skia.gyp
@@ -148,6 +148,8 @@
'../third_party/skia/include/utils/SkNullCanvas.h',
'../third_party/skia/include/utils/SkPictureUtils.h',
+ 'ext/analysis_canvas.cc',
+ 'ext/analysis_canvas.h',
'ext/bitmap_platform_device.h',
'ext/bitmap_platform_device_android.cc',
'ext/bitmap_platform_device_android.h',