diff options
Diffstat (limited to 'gfx/skia/skia/src/gpu/GrWindowRectangles.h')
-rw-r--r-- | gfx/skia/skia/src/gpu/GrWindowRectangles.h | 123 |
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 |