summaryrefslogtreecommitdiffstats
path: root/gfx/skia/skia/src/gpu/GrWindowRectangles.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/skia/skia/src/gpu/GrWindowRectangles.h')
-rw-r--r--gfx/skia/skia/src/gpu/GrWindowRectangles.h123
1 files changed, 123 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/gpu/GrWindowRectangles.h b/gfx/skia/skia/src/gpu/GrWindowRectangles.h
new file mode 100644
index 0000000000..1b6bc4dfee
--- /dev/null
+++ b/gfx/skia/skia/src/gpu/GrWindowRectangles.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrWindowRectangles_DEFINED
+#define GrWindowRectangles_DEFINED
+
+#include "include/core/SkRect.h"
+#include "src/gpu/GrNonAtomicRef.h"
+
+class GrWindowRectangles {
+public:
+ constexpr static int kMaxWindows = 8;
+
+ GrWindowRectangles() : fCount(0) {}
+ GrWindowRectangles(const GrWindowRectangles& that) : fCount(0) { *this = that; }
+ ~GrWindowRectangles() { SkSafeUnref(this->rec()); }
+
+ GrWindowRectangles makeOffset(int dx, int dy) const;
+
+ bool empty() const { return !fCount; }
+ int count() const { return fCount; }
+ const SkIRect* data() const;
+
+ void reset();
+ GrWindowRectangles& operator=(const GrWindowRectangles&);
+
+ SkIRect& addWindow(const SkIRect& window) { return this->addWindow() = window; }
+ SkIRect& addWindow();
+
+ bool operator!=(const GrWindowRectangles& that) const { return !(*this == that); }
+ bool operator==(const GrWindowRectangles&) const;
+
+private:
+ constexpr static int kNumLocalWindows = 1;
+ struct Rec;
+
+ const Rec* rec() const { return fCount <= kNumLocalWindows ? nullptr : fRec; }
+
+ int fCount;
+ union {
+ SkIRect fLocalWindows[kNumLocalWindows]; // If fCount <= kNumLocalWindows.
+ Rec* fRec; // If fCount > kNumLocalWindows.
+ };
+};
+
+struct GrWindowRectangles::Rec : public GrNonAtomicRef<Rec> {
+ Rec(const SkIRect* windows, int numWindows) {
+ SkASSERT(numWindows < kMaxWindows);
+ memcpy(fData, windows, sizeof(SkIRect) * numWindows);
+ }
+ Rec() = default;
+
+ SkIRect fData[kMaxWindows];
+};
+
+inline const SkIRect* GrWindowRectangles::data() const {
+ return fCount <= kNumLocalWindows ? fLocalWindows : fRec->fData;
+}
+
+inline void GrWindowRectangles::reset() {
+ SkSafeUnref(this->rec());
+ fCount = 0;
+}
+
+inline GrWindowRectangles& GrWindowRectangles::operator=(const GrWindowRectangles& that) {
+ SkSafeUnref(this->rec());
+ fCount = that.fCount;
+ if (fCount <= kNumLocalWindows) {
+ memcpy(fLocalWindows, that.fLocalWindows, fCount * sizeof(SkIRect));
+ } else {
+ fRec = SkRef(that.fRec);
+ }
+ return *this;
+}
+
+inline GrWindowRectangles GrWindowRectangles::makeOffset(int dx, int dy) const {
+ if (!dx && !dy) {
+ return *this;
+ }
+ GrWindowRectangles result;
+ result.fCount = fCount;
+ SkIRect* windows;
+ if (result.fCount > kNumLocalWindows) {
+ result.fRec = new Rec();
+ windows = result.fRec->fData;
+ } else {
+ windows = result.fLocalWindows;
+ }
+ for (int i = 0; i < fCount; ++i) {
+ windows[i] = this->data()[i].makeOffset(dx, dy);
+ }
+ return result;
+}
+
+inline SkIRect& GrWindowRectangles::addWindow() {
+ SkASSERT(fCount < kMaxWindows);
+ if (fCount < kNumLocalWindows) {
+ return fLocalWindows[fCount++];
+ }
+ if (fCount == kNumLocalWindows) {
+ fRec = new Rec(fLocalWindows, kNumLocalWindows);
+ } else if (!fRec->unique()) { // Simple copy-on-write.
+ fRec->unref();
+ fRec = new Rec(fRec->fData, fCount);
+ }
+ return fRec->fData[fCount++];
+}
+
+inline bool GrWindowRectangles::operator==(const GrWindowRectangles& that) const {
+ if (fCount != that.fCount) {
+ return false;
+ }
+ if (fCount > kNumLocalWindows && fRec == that.fRec) {
+ return true;
+ }
+ return !fCount || !memcmp(this->data(), that.data(), sizeof(SkIRect) * fCount);
+}
+
+#endif