GrWindowRectangles.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Copyright 2016 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #ifndef GrWindowRectangles_DEFINED
  8. #define GrWindowRectangles_DEFINED
  9. #include "include/core/SkRect.h"
  10. #include "src/gpu/GrNonAtomicRef.h"
  11. class GrWindowRectangles {
  12. public:
  13. constexpr static int kMaxWindows = 8;
  14. GrWindowRectangles() : fCount(0) {}
  15. GrWindowRectangles(const GrWindowRectangles& that) : fCount(0) { *this = that; }
  16. ~GrWindowRectangles() { SkSafeUnref(this->rec()); }
  17. GrWindowRectangles makeOffset(int dx, int dy) const;
  18. bool empty() const { return !fCount; }
  19. int count() const { return fCount; }
  20. const SkIRect* data() const;
  21. void reset();
  22. GrWindowRectangles& operator=(const GrWindowRectangles&);
  23. SkIRect& addWindow(const SkIRect& window) { return this->addWindow() = window; }
  24. SkIRect& addWindow();
  25. bool operator!=(const GrWindowRectangles& that) const { return !(*this == that); }
  26. bool operator==(const GrWindowRectangles&) const;
  27. private:
  28. constexpr static int kNumLocalWindows = 1;
  29. struct Rec;
  30. const Rec* rec() const { return fCount <= kNumLocalWindows ? nullptr : fRec; }
  31. int fCount;
  32. union {
  33. SkIRect fLocalWindows[kNumLocalWindows]; // If fCount <= kNumLocalWindows.
  34. Rec* fRec; // If fCount > kNumLocalWindows.
  35. };
  36. };
  37. struct GrWindowRectangles::Rec : public GrNonAtomicRef<Rec> {
  38. Rec(const SkIRect* windows, int numWindows) {
  39. SkASSERT(numWindows < kMaxWindows);
  40. memcpy(fData, windows, sizeof(SkIRect) * numWindows);
  41. }
  42. Rec() = default;
  43. SkIRect fData[kMaxWindows];
  44. };
  45. inline const SkIRect* GrWindowRectangles::data() const {
  46. return fCount <= kNumLocalWindows ? fLocalWindows : fRec->fData;
  47. }
  48. inline void GrWindowRectangles::reset() {
  49. SkSafeUnref(this->rec());
  50. fCount = 0;
  51. }
  52. inline GrWindowRectangles& GrWindowRectangles::operator=(const GrWindowRectangles& that) {
  53. SkSafeUnref(this->rec());
  54. fCount = that.fCount;
  55. if (fCount <= kNumLocalWindows) {
  56. memcpy(fLocalWindows, that.fLocalWindows, fCount * sizeof(SkIRect));
  57. } else {
  58. fRec = SkRef(that.fRec);
  59. }
  60. return *this;
  61. }
  62. inline GrWindowRectangles GrWindowRectangles::makeOffset(int dx, int dy) const {
  63. if (!dx && !dy) {
  64. return *this;
  65. }
  66. GrWindowRectangles result;
  67. result.fCount = fCount;
  68. SkIRect* windows;
  69. if (result.fCount > kNumLocalWindows) {
  70. result.fRec = new Rec();
  71. windows = result.fRec->fData;
  72. } else {
  73. windows = result.fLocalWindows;
  74. }
  75. for (int i = 0; i < fCount; ++i) {
  76. windows[i] = this->data()[i].makeOffset(dx, dy);
  77. }
  78. return result;
  79. }
  80. inline SkIRect& GrWindowRectangles::addWindow() {
  81. SkASSERT(fCount < kMaxWindows);
  82. if (fCount < kNumLocalWindows) {
  83. return fLocalWindows[fCount++];
  84. }
  85. if (fCount == kNumLocalWindows) {
  86. fRec = new Rec(fLocalWindows, kNumLocalWindows);
  87. } else if (!fRec->unique()) { // Simple copy-on-write.
  88. fRec->unref();
  89. fRec = new Rec(fRec->fData, fCount);
  90. }
  91. return fRec->fData[fCount++];
  92. }
  93. inline bool GrWindowRectangles::operator==(const GrWindowRectangles& that) const {
  94. if (fCount != that.fCount) {
  95. return false;
  96. }
  97. if (fCount > kNumLocalWindows && fRec == that.fRec) {
  98. return true;
  99. }
  100. return !fCount || !memcmp(this->data(), that.data(), sizeof(SkIRect) * fCount);
  101. }
  102. #endif