1 /*
2  * Copyright 2015 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 
8 #include "GrOp.h"
9 
10 std::atomic<uint32_t> GrOp::gCurrOpClassID {GrOp::kIllegalOpID + 1};
11 std::atomic<uint32_t> GrOp::gCurrOpUniqueID{GrOp::kIllegalOpID + 1};
12 
13 #ifdef SK_DEBUG
14 void* GrOp::operator new(size_t size) {
15     // All GrOp-derived class should be allocated in a GrMemoryPool
16     SkASSERT(0);
17     return ::operator new(size);
18 }
19 
20 void GrOp::operator delete(void* target) {
21     // All GrOp-derived class should be released from their owning GrMemoryPool
22     SkASSERT(0);
23     ::operator delete(target);
24 }
25 #endif
26 
27 GrOp::GrOp(uint32_t classID) : fClassID(classID) {
28     SkASSERT(classID == SkToU32(fClassID));
29     SkASSERT(classID);
30     SkDEBUGCODE(fBoundsFlags = kUninitialized_BoundsFlag);
31 }
32 
33 GrOp::CombineResult GrOp::combineIfPossible(GrOp* that, const GrCaps& caps) {
34     SkASSERT(this != that);
35     if (this->classID() != that->classID()) {
36         return CombineResult::kCannotCombine;
37     }
38     auto result = this->onCombineIfPossible(that, caps);
39     if (result == CombineResult::kMerged) {
40         this->joinBounds(*that);
41     }
42     return result;
43 }
44 
45 void GrOp::chainConcat(std::unique_ptr<GrOp> next) {
46     SkASSERT(next);
47     SkASSERT(this->classID() == next->classID());
48     SkASSERT(this->isChainTail());
49     SkASSERT(next->isChainHead());
50     fNextInChain = std::move(next);
51     fNextInChain->fPrevInChain = this;
52 }
53 
54 std::unique_ptr<GrOp> GrOp::cutChain() {
55     if (fNextInChain) {
56         fNextInChain->fPrevInChain = nullptr;
57         return std::move(fNextInChain);
58     }
59     return nullptr;
60 }
61 
62 #ifdef SK_DEBUG
63 void GrOp::validateChain(GrOp* expectedTail) const {
64     SkASSERT(this->isChainHead());
65     uint32_t classID = this->classID();
66     const GrOp* op = this;
67     while (op) {
68         SkASSERT(op == this || (op->prevInChain() && op->prevInChain()->nextInChain() == op));
69         SkASSERT(classID == op->classID());
70         if (op->nextInChain()) {
71             SkASSERT(op->nextInChain()->prevInChain() == op);
72             SkASSERT(op != expectedTail);
73         } else {
74             SkASSERT(!expectedTail || op == expectedTail);
75         }
76         op = op->nextInChain();
77     }
78 }
79 #endif
80