123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- /*
- * 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
|