Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Unified Diff: src/core/SkMiniRecorder.cpp

Issue 1112523006: Sketch splitting SkPicture into an interface and SkBigPicture. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: tweaks Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkMiniRecorder.cpp
diff --git a/src/core/SkMiniRecorder.cpp b/src/core/SkMiniRecorder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cefc6567ce57635f0646cc974a8c239fb5cd9d1f
--- /dev/null
+++ b/src/core/SkMiniRecorder.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkCanvas.h"
+#include "SkLazyPtr.h"
+#include "SkMiniRecorder.h"
+#include "SkPicture.h"
+#include "SkRecordDraw.h"
+#include "SkRecords.h"
+#include "SkTextBlob.h"
+
+using namespace SkRecords;
+
+class SkEmptyPicture : public SkPicture {
+public:
+ void playback(SkCanvas*, AbortCallback*) const override { }
+
+ size_t approximateBytesUsed() const override { return sizeof(*this); }
+ int approximateOpCount() const override { return 0; }
+ SkRect cullRect() const override { return SkRect::MakeEmpty(); }
+ bool hasText() const override { return false; }
+ int numSlowPaths() const override { return 0; }
+ bool willPlayBackBitmaps() const override { return false; }
+ bool suitableForGpuRasterization(GrContext*, const char**) const override { return true; }
+};
+SK_DECLARE_STATIC_LAZY_PTR(SkEmptyPicture, gEmptyPicture);
+
+template <typename T>
+class SkMiniPicture : public SkPicture {
+public:
+ SkMiniPicture(SkRect cull, T* op) : fCull(cull) {
+ memcpy(&fOp, op, sizeof(fOp)); // We take ownership of op's guts.
+ }
+
+ void playback(SkCanvas* c, AbortCallback*) const override {
+ SkRecords::Draw(c, nullptr, nullptr, 0, nullptr)(fOp);
+ }
+
+ size_t approximateBytesUsed() const override { return sizeof(*this); }
+ int approximateOpCount() const override { return 1; }
+ SkRect cullRect() const override { return fCull; }
+
+ // TODO: These trivial implementations are not all correct for all types.
+ // But I suspect these will never be called on SkMiniPictures, so assert for now.
+ bool hasText() const override { SkASSERT(false); return false; }
+ int numSlowPaths() const override { SkASSERT(false); return 0; }
+ bool willPlayBackBitmaps() const override { SkASSERT(false); return false; }
+ bool suitableForGpuRasterization(GrContext*, const char**) const override {
+ SkASSERT(false);
+ return true;
+ }
+
+private:
+ SkRect fCull;
+ T fOp;
+};
+
+
+SkMiniRecorder::SkMiniRecorder() : fState(State::kEmpty) {}
+SkMiniRecorder::~SkMiniRecorder() {
+ // We've done something wrong if no one's called detachAsPicture() or flushToCanvas().
+ SkASSERT(fState == State::kEmpty);
+}
+
+#define TRY_TO_STORE(Type, ...) \
+ if (fState != State::kEmpty) { return false; } \
+ fState = State::k##Type; \
+ new (fBuffer) Type(__VA_ARGS__); \
+ return true
+
+bool SkMiniRecorder::drawRect(const SkRect& rect, const SkPaint& paint) {
+ TRY_TO_STORE(DrawRect, paint, rect);
+}
+
+bool SkMiniRecorder::drawPath(const SkPath& path, const SkPaint& paint) {
+ TRY_TO_STORE(DrawPath, paint, path);
+}
+
+bool SkMiniRecorder::drawTextBlob(const SkTextBlob* b, SkScalar x, SkScalar y, const SkPaint& p) {
+ TRY_TO_STORE(DrawTextBlob, p, b, x, y);
+}
+#undef TRY_TO_STORE
+
+#define CASE(Type) \
+ case State::k##Type: \
+ fState = State::kEmpty; \
+ return SkNEW_ARGS(SkMiniPicture<Type>, (cull, reinterpret_cast<Type*>(fBuffer)))
+
+SkPicture* SkMiniRecorder::detachAsPicture(const SkRect& cull) {
+ switch (fState) {
+ case State::kEmpty: return SkRef(gEmptyPicture.get());
+ CASE(DrawPath);
+ CASE(DrawRect);
+ CASE(DrawTextBlob);
+ }
reed1 2015/05/04 13:26:34 return NULL; ?
mtklein 2015/05/04 15:52:45 Done.
+}
+#undef CASE
+
+void SkMiniRecorder::flushToCanvas(SkCanvas* canvas) {
+ // TODO: This method could be made quite a bit more efficient. It's lazy, but correct.
+ SkAutoTUnref<SkPicture> p(this->detachAsPicture(SkRect::MakeEmpty()));
+ p->playback(canvas);
+}

Powered by Google App Engine
This is Rietveld 408576698