176948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips/*
276948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips * Copyright 2016 Google Inc.
376948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips *
476948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips * Use of this source code is governed by a BSD-style license that can be
576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips * found in the LICENSE file.
676948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips */
776948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
876948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips#ifndef GrSurfaceProxy_DEFINED
976948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips#define GrSurfaceProxy_DEFINED
1076948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
1176948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips#include "GrGpuResource.h"
12c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips#include "GrSurface.h"
1393f1633abca95e302fdd31ece0f4d602b0b26708Robert Phillips
14bf4a8f90c87dddf6290aa774536715e55e6a12f5csmartdalton#include "SkRect.h"
1576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
167ef28f35a2f7d17b90c776f76d4b374ccee6c347Greg Danielclass GrBackendTexture;
173743013f755d23c215d852af7d829c3cd74f34a2Robert Phillipsclass GrCaps;
18c589b0b5c0235c3adedc574c8846fb62414ed93cRobert Phillipsclass GrOpList;
191afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillipsclass GrProxyProvider;
2045580d3e3024c1536e8e1b2017b704805442b634Brian Osmanclass GrRenderTargetOpList;
2176948d4faaca9fd7730576e2f79790ca8d93c10brobertphillipsclass GrRenderTargetProxy;
2232342f032e1dfd133040324f851f0365f9d4cb51Brian Osmanclass GrResourceProvider;
23d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillipsclass GrSurfaceContext;
24757914d26b337b04cf270875bce28d7d1e2407deRobert Phillipsclass GrSurfaceProxyPriv;
2545580d3e3024c1536e8e1b2017b704805442b634Brian Osmanclass GrTextureOpList;
2645580d3e3024c1536e8e1b2017b704805442b634Brian Osmanclass GrTextureProxy;
2776948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
28c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips// This class replicates the functionality GrIORef<GrSurface> but tracks the
29c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips// utilitization for later resource allocation (for the deferred case) and
30c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips// forwards on the utilization in the wrapped case
31c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillipsclass GrIORefProxy : public SkNoncopyable {
32c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillipspublic:
33c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    void ref() const {
34c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        this->validate();
35c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
36c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        ++fRefCnt;
37c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        if (fTarget) {
38c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips            fTarget->ref();
39c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        }
40c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    }
41c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
42c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    void unref() const {
43c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        this->validate();
44c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
45c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        if (fTarget) {
46c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips            fTarget->unref();
47c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        }
48c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
49b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips        --fRefCnt;
50b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips        this->didRemoveRefOrPendingIO();
51c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    }
52c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
53a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton#ifdef SK_DEBUG
54a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton    bool isUnique_debugOnly() const { // For asserts.
55a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton        SkASSERT(fRefCnt >= 0 && fPendingWrites >= 0 && fPendingReads >= 0);
56a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton        return 1 == fRefCnt + fPendingWrites + fPendingReads;
57a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton    }
58a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton#endif
59a32a3c32c32e02baecffb537f6f26c0a67a1c130Chris Dalton
604bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips    void release() {
614bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        SkASSERT(1 == fRefCnt);
624bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        SkASSERT(0 == fPendingReads);
634bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        SkASSERT(0 == fPendingWrites);
644bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips
654bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        SkASSERT(fTarget->internalHasUniqueRef());
664bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        SkASSERT(!fTarget->internalHasPendingIO());
674bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        fTarget->unref();
684bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        fTarget = nullptr;
694bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips    }
704bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips
71c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    void validate() const {
72b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips#ifdef SK_DEBUG
73b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips        SkASSERT(fRefCnt >= 0);
741125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        SkASSERT(fPendingReads >= 0);
751125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        SkASSERT(fPendingWrites >= 0);
761125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        SkASSERT(fRefCnt + fPendingReads + fPendingWrites >= 1);
771125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
781125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        if (fTarget) {
791125a030c726854f94fd2b8eed49d1323fc1d038robertphillips            // The backing GrSurface can have more refs than the proxy if the proxy
801125a030c726854f94fd2b8eed49d1323fc1d038robertphillips            // started off wrapping an external resource (that came in with refs).
811125a030c726854f94fd2b8eed49d1323fc1d038robertphillips            // The GrSurface should never have fewer refs than the proxy however.
821125a030c726854f94fd2b8eed49d1323fc1d038robertphillips            SkASSERT(fTarget->fRefCnt >= fRefCnt);
83b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips            SkASSERT(fTarget->fPendingReads >= fPendingReads);
84b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips            SkASSERT(fTarget->fPendingWrites >= fPendingWrites);
851125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        }
86c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips#endif
87c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    }
88c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
891125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    int32_t getProxyRefCnt_TestOnly() const;
901125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    int32_t getBackingRefCnt_TestOnly() const;
911125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    int32_t getPendingReadCnt_TestOnly() const;
921125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    int32_t getPendingWriteCnt_TestOnly() const;
931125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
94cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    void addPendingRead() const {
95cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->validate();
96cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
97cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        ++fPendingReads;
98cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        if (fTarget) {
99cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon            fTarget->addPendingRead();
100cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        }
101cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    }
102cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
103cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    void completedRead() const {
104cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->validate();
105cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
106cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        if (fTarget) {
107cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon            fTarget->completedRead();
108cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        }
109cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
110cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        --fPendingReads;
111cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->didRemoveRefOrPendingIO();
112cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    }
113cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
114cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    void addPendingWrite() const {
115cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->validate();
116cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
117cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        ++fPendingWrites;
118cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        if (fTarget) {
119cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon            fTarget->addPendingWrite();
120cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        }
121cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    }
122cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
123cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    void completedWrite() const {
124cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->validate();
125cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
126cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        if (fTarget) {
127cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon            fTarget->completedWrite();
128cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        }
129cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
130cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        --fPendingWrites;
131cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon        this->didRemoveRefOrPendingIO();
132cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon    }
133cf75b00ff0b59871e11f23bcbab2884eb083ac4cBrian Salomon
134c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillipsprotected:
1351125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    GrIORefProxy() : fTarget(nullptr), fRefCnt(1), fPendingReads(0), fPendingWrites(0) {}
1361125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    GrIORefProxy(sk_sp<GrSurface> surface) : fRefCnt(1), fPendingReads(0), fPendingWrites(0) {
137c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        // Since we're manually forwarding on refs & unrefs we don't want sk_sp doing
138c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        // anything extra.
139c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        fTarget = surface.release();
140c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    }
141c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    virtual ~GrIORefProxy() {
142c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips        // We don't unref 'fTarget' here since the 'unref' method will already
1434bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips        // have forwarded on the unref call that got us here.
144c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    }
145c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
1461125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    // This GrIORefProxy was deferred before but has just been instantiated. To
1471125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    // make all the reffing & unreffing work out we now need to transfer any deferred
1481125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    // refs & unrefs to the new GrSurface
1491125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    void transferRefs() {
1501125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        SkASSERT(fTarget);
1511125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
152f8e2502819499894dff40c4f2f46e46edda15507Robert Phillips        SkASSERT(fTarget->fRefCnt > 0);
1532d9cb57c83553be3434c04f860d5e9fec30cb453Robert Phillips        fTarget->fRefCnt += (fRefCnt-1); // don't xfer the proxy's creation ref
1541125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        fTarget->fPendingReads += fPendingReads;
1551125a030c726854f94fd2b8eed49d1323fc1d038robertphillips        fTarget->fPendingWrites += fPendingWrites;
1561125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    }
157c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
158757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    bool internalHasPendingIO() const {
159757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips        if (fTarget) {
160757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips            return fTarget->internalHasPendingIO();
161757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips        }
162757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
163757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips        return SkToBool(fPendingWrites | fPendingReads);
164757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    }
165757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
1667ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    bool internalHasPendingWrite() const {
1677ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        if (fTarget) {
1687ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips            return fTarget->internalHasPendingWrite();
1697ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        }
1707ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
1717ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        return SkToBool(fPendingWrites);
1727ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    }
1737ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
174c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    // For deferred proxies this will be null. For wrapped proxies it will point to the
175c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    // wrapped resource.
176c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    GrSurface* fTarget;
1771125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
1781125a030c726854f94fd2b8eed49d1323fc1d038robertphillipsprivate:
1791125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    // This class is used to manage conversion of refs to pending reads/writes.
180b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips    friend class GrSurfaceProxyRef;
1811125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    template <typename, GrIOType> friend class GrPendingIOResource;
1821125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
183b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips    void didRemoveRefOrPendingIO() const {
184b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips        if (0 == fPendingReads && 0 == fPendingWrites && 0 == fRefCnt) {
185b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips            delete this;
186b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips        }
1871125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    }
1881125a030c726854f94fd2b8eed49d1323fc1d038robertphillips
1891125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    mutable int32_t fRefCnt;
1901125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    mutable int32_t fPendingReads;
1911125a030c726854f94fd2b8eed49d1323fc1d038robertphillips    mutable int32_t fPendingWrites;
192c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips};
193c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips
194c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillipsclass GrSurfaceProxy : public GrIORefProxy {
19576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillipspublic:
196457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    enum class LazyInstantiationType {
197457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel        kSingleUse,    // Instantiation callback is allowed to be called only once
198457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel        kMultipleUse,  // Instantiation callback can be called multiple times.
199457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    };
200457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel
20165fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    enum class LazyState {
2020a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel        kNot,       // The proxy is instantiated or does not have a lazy callback
20365fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        kPartially, // The proxy has a lazy callback but knows basic information about itself.
20465fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        kFully,     // The proxy has a lazy callback and also doesn't know its width, height, etc.
20565fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    };
20665fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel
20765fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    LazyState lazyInstantiationState() const {
2080a375db9a4c1dc96f9d5856526e074ab2802fb0eGreg Daniel        if (fTarget || !SkToBool(fLazyInstantiateCallback)) {
20965fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel            return LazyState::kNot;
21065fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        } else {
21165fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel            if (fWidth <= 0) {
21265fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel                SkASSERT(fHeight <= 0);
21365fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel                return LazyState::kFully;
21465fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel            } else {
21565fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel                SkASSERT(fHeight > 0);
21665fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel                return LazyState::kPartially;
21765fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel            }
21865fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        }
21965fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    }
220706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton
221706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    GrPixelConfig config() const { return fConfig; }
22265fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    int width() const {
22365fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        SkASSERT(LazyState::kFully != this->lazyInstantiationState());
22465fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        return fWidth;
22565fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    }
22665fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    int height() const {
22765fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        SkASSERT(LazyState::kFully != this->lazyInstantiationState());
22865fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        return fHeight;
22965fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel    }
230706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    int worstCaseWidth() const;
231706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    int worstCaseHeight() const;
23276948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    GrSurfaceOrigin origin() const {
233bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon        SkASSERT(kTopLeft_GrSurfaceOrigin == fOrigin || kBottomLeft_GrSurfaceOrigin == fOrigin);
234bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon        return fOrigin;
23576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    }
236706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton
237294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    class UniqueID {
238294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    public:
2397ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        static UniqueID InvalidID() {
2407ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips            return UniqueID(uint32_t(SK_InvalidUniqueID));
2417ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        }
2427ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
243294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        // wrapped
244294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        explicit UniqueID(const GrGpuResource::UniqueID& id) : fID(id.asUInt()) { }
245706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton        // deferred and lazy-callback
246294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        UniqueID() : fID(GrGpuResource::CreateUniqueID()) { }
247294870ff119b89fc902773643b054f14e5d1f554Robert Phillips
248294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        uint32_t asUInt() const { return fID; }
249294870ff119b89fc902773643b054f14e5d1f554Robert Phillips
250294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        bool operator==(const UniqueID& other) const {
251294870ff119b89fc902773643b054f14e5d1f554Robert Phillips            return fID == other.fID;
252294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        }
253294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        bool operator!=(const UniqueID& other) const {
254294870ff119b89fc902773643b054f14e5d1f554Robert Phillips            return !(*this == other);
255294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        }
256294870ff119b89fc902773643b054f14e5d1f554Robert Phillips
2577ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        void makeInvalid() { fID = SK_InvalidUniqueID; }
258294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        bool isInvalid() const { return SK_InvalidUniqueID == fID; }
259294870ff119b89fc902773643b054f14e5d1f554Robert Phillips
260294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    private:
2617ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        explicit UniqueID(uint32_t id) : fID(id) {}
2627ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
2637ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        uint32_t fID;
264294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    };
265294870ff119b89fc902773643b054f14e5d1f554Robert Phillips
266294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    /*
267294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     * The contract for the uniqueID is:
268294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *   for wrapped resources:
269294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *      the uniqueID will match that of the wrapped resource
270294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *
271294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *   for deferred resources:
272294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *      the uniqueID will be different from the real resource, when it is allocated
273294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *      the proxy's uniqueID will not change across the instantiate call
274294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *
275294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *    the uniqueIDs of the proxies and the resources draw from the same pool
276294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     *
277294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     * What this boils down to is that the uniqueID of a proxy can be used to consistently
278294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     * track/identify a proxy but should never be used to distinguish between
279294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     * resources and proxies - beware!
280294870ff119b89fc902773643b054f14e5d1f554Robert Phillips     */
281294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    UniqueID uniqueID() const { return fUniqueID; }
28276948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
283159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips    UniqueID underlyingUniqueID() const {
284159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips        if (fTarget) {
285159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips            return UniqueID(fTarget->uniqueID());
286159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips        }
287159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips
288159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips        return fUniqueID;
289159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips    }
290159e3c6c925d55b397c8c75273c773e18946b493Robert Phillips
291eee4d6e4e8cc5c4c79f065abcc3ce609f71238f9Robert Phillips    virtual bool instantiate(GrResourceProvider* resourceProvider) = 0;
2923743013f755d23c215d852af7d829c3cd74f34a2Robert Phillips
2934bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips    void deInstantiate();
2944bc7011802e411da74eb2d213d6328e42f7dce1cRobert Phillips
29576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    /**
29613a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips     * Helper that gets the width and height of the surface as a bounding rectangle.
29713a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips     */
298706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    SkRect getBoundsRect() const {
29965fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        SkASSERT(LazyState::kFully != this->lazyInstantiationState());
300706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton        return SkRect::MakeIWH(this->width(), this->height());
301706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    }
302784b7bf493c37236e3fe571aed6105939a9bc0c3Robert Phillips
30313a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips    /**
30476948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips     * @return the texture proxy associated with the surface proxy, may be NULL.
30576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips     */
30676948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    virtual GrTextureProxy* asTextureProxy() { return nullptr; }
30776948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    virtual const GrTextureProxy* asTextureProxy() const { return nullptr; }
30876948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
30976948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    /**
31076948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips     * @return the render target proxy associated with the surface proxy, may be NULL.
31176948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips     */
31276948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    virtual GrRenderTargetProxy* asRenderTargetProxy() { return nullptr; }
31376948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips    virtual const GrRenderTargetProxy* asRenderTargetProxy() const { return nullptr; }
31476948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
31513a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips    /**
31613a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips     * Does the resource count against the resource budget?
31713a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips     */
31813a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips    SkBudgeted isBudgeted() const { return fBudgeted; }
31913a7eee2504e7deb0e27ed3e69a787696d57b037robertphillips
320f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    void setLastOpList(GrOpList* opList);
321f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    GrOpList* getLastOpList() { return fLastOpList; }
322f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips
32345580d3e3024c1536e8e1b2017b704805442b634Brian Osman    GrRenderTargetOpList* getLastRenderTargetOpList();
32445580d3e3024c1536e8e1b2017b704805442b634Brian Osman    GrTextureOpList* getLastTextureOpList();
32545580d3e3024c1536e8e1b2017b704805442b634Brian Osman
3268bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    /**
327f5442bb4c152e7c8138c83d27140e55d846f7ea5Robert Phillips     * Retrieves the amount of GPU memory that will be or currently is used by this resource
3288bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips     * in bytes. It is approximate since we aren't aware of additional padding or copies made
3298bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips     * by the driver.
3308bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips     *
3318bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips     * @return the amount of GPU memory used in bytes
3328bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips     */
3338bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    size_t gpuMemorySize() const {
33465fa8ca85ef146340ddea61bb08c182df499ca62Greg Daniel        SkASSERT(LazyState::kFully != this->lazyInstantiationState());
335bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon        if (fTarget) {
336bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon            return fTarget->gpuMemorySize();
337bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon        }
3388bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips        if (kInvalidGpuMemorySize == fGpuMemorySize) {
339bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon            fGpuMemorySize = this->onUninstantiatedGpuMemorySize();
3408bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips            SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
3418bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips        }
3428bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips        return fGpuMemorySize;
3438bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    }
3448bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips
345e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Helper function that creates a temporary SurfaceContext to perform the copy
3460ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips    // It always returns a kExact-backed proxy bc it is used when converting an SkSpecialImage
34763e7973d1f01bd03216659b9d2267f83a752c8fbBrian Salomon    // to an SkImage. The copy is is not a render target and not multisampled.
34865c7f662ba4ec1c78dc5fc67b184ee9c7b614f55Greg Daniel    static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src, GrMipMapped,
349e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips                                      SkIRect srcRect, SkBudgeted);
350e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
351e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Copy the entire 'src'
3520ae6faa34d73ffc7ebec3d13f0473703bade821bRobert Phillips    // It always returns a kExact-backed proxy bc it is used in SkGpuDevice::snapSpecial
35365c7f662ba4ec1c78dc5fc67b184ee9c7b614f55Greg Daniel    static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src, GrMipMapped,
35463c67461ed07b5fca35182ac62657b2cb16afbb4Robert Phillips                                      SkBudgeted budgeted);
355e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
356e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Test-only entry point - should decrease in use as proxies propagate
357d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    static sk_sp<GrSurfaceContext> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
358d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            GrSurfaceProxy* srcProxy);
359e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
360eaa862569dc91d55fc79d057df6e69b139e46888Robert Phillips    bool isWrapped_ForTesting() const;
361eaa862569dc91d55fc79d057df6e69b139e46888Robert Phillips
36245580d3e3024c1536e8e1b2017b704805442b634Brian Osman    SkDEBUGCODE(void validate(GrContext*) const;)
36345580d3e3024c1536e8e1b2017b704805442b634Brian Osman
364757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    // Provides access to functions that aren't part of the public API.
365420c4cfcd75189c03c735b1f02dee360e705c3e9Robert Phillips    inline GrSurfaceProxyPriv priv();
366420c4cfcd75189c03c735b1f02dee360e705c3e9Robert Phillips    inline const GrSurfaceProxyPriv priv() const;
367757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
36876948d4faaca9fd7730576e2f79790ca8d93c10brobertphillipsprotected:
3698abb370aca280516f4861c6c942ec453aad018farobertphillips    // Deferred version
370c787e495e28d3a37945e74e24bb6ee8f635d86b7Robert Phillips    GrSurfaceProxy(const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted, uint32_t flags)
371457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel            : GrSurfaceProxy(nullptr, LazyInstantiationType::kSingleUse,
372457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel                             desc, fit, budgeted, flags) {
373294870ff119b89fc902773643b054f14e5d1f554Robert Phillips        // Note: this ctor pulls a new uniqueID from the same pool at the GrGpuResources
3748abb370aca280516f4861c6c942ec453aad018farobertphillips    }
3758abb370aca280516f4861c6c942ec453aad018farobertphillips
376ce5209a8a5711fde34f28c740f5cd74bdb560e21Robert Phillips    using LazyInstantiateCallback = std::function<sk_sp<GrSurface>(GrResourceProvider*)>;
377777707be8445b7d2f9cb235cd040cd1994dd2996Robert Phillips
378706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    // Lazy-callback version
379457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    GrSurfaceProxy(LazyInstantiateCallback&& callback, LazyInstantiationType lazyType,
380457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel                   const GrSurfaceDesc& desc, SkBackingFit fit, SkBudgeted budgeted,
381457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel                   uint32_t flags);
382706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton
3838abb370aca280516f4861c6c942ec453aad018farobertphillips    // Wrapped version
384066f020bb6cb9dbb12b977fcddd93982201777feRobert Phillips    GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit);
38576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
386f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    virtual ~GrSurfaceProxy();
387f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips
388757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    friend class GrSurfaceProxyPriv;
389757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
390757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    // Methods made available via GrSurfaceProxyPriv
391757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    bool hasPendingIO() const {
392757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips        return this->internalHasPendingIO();
393757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips    }
394757914d26b337b04cf270875bce28d7d1e2407deRobert Phillips
3957ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    bool hasPendingWrite() const {
3967ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips        return this->internalHasPendingWrite();
3977ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips    }
3987ee385e1dc3cd6a47dc8f7297fef6e175eaba224Robert Phillips
39957aa367aa3c5911cd4a21230799b147e44190282Robert Phillips    void computeScratchKey(GrScratchKey*) const;
40057aa367aa3c5911cd4a21230799b147e44190282Robert Phillips
4015af44defbd5fc7ef0053ec4b61f0859170f2fb15Robert Phillips    virtual sk_sp<GrSurface> createSurface(GrResourceProvider*) const = 0;
4025af44defbd5fc7ef0053ec4b61f0859170f2fb15Robert Phillips    void assign(sk_sp<GrSurface> surface);
4035af44defbd5fc7ef0053ec4b61f0859170f2fb15Robert Phillips
40465048139bd26c8edbc6796f220e79b6c848151d7Robert Phillips    sk_sp<GrSurface> createSurfaceImpl(GrResourceProvider*, int sampleCnt, bool needsStencil,
405d2d8e92e5e6014b746e9928a8ffc1ba4b95cb016Greg Daniel                                       GrSurfaceFlags flags, GrMipMapped mipMapped) const;
4065af44defbd5fc7ef0053ec4b61f0859170f2fb15Robert Phillips
40765048139bd26c8edbc6796f220e79b6c848151d7Robert Phillips    bool instantiateImpl(GrResourceProvider* resourceProvider, int sampleCnt, bool needsStencil,
408d2d8e92e5e6014b746e9928a8ffc1ba4b95cb016Greg Daniel                         GrSurfaceFlags flags, GrMipMapped mipMapped, const GrUniqueKey*);
409bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon
410706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Daltonprivate:
411bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    // For wrapped resources, 'fConfig', 'fWidth', 'fHeight', and 'fOrigin; will always be filled in
412bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    // from the wrapped resource.
413bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    GrPixelConfig        fConfig;
414bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    int                  fWidth;
415bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    int                  fHeight;
416bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    GrSurfaceOrigin      fOrigin;
417706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    SkBackingFit         fFit;      // always kApprox for lazy-callback resources
418706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton                                    // always kExact for wrapped resources
419706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    mutable SkBudgeted   fBudgeted; // always kYes for lazy-callback resources
420706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton                                    // set from the backing resource for wrapped resources
421b726d58efc91c4eefa5cea0881a823ee108db8fdRobert Phillips                                    // mutable bc of SkSurface/SkImage wishy-washiness
422c787e495e28d3a37945e74e24bb6ee8f635d86b7Robert Phillips    const uint32_t       fFlags;
423a4c41b3e83bc684b3535d36590519d6fb676742dRobert Phillips
424294870ff119b89fc902773643b054f14e5d1f554Robert Phillips    const UniqueID       fUniqueID; // set from the backing resource for wrapped resources
42576948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
426706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton    LazyInstantiateCallback fLazyInstantiateCallback;
427457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    // If this is set to kSingleuse, then after one call to fLazyInstantiateCallback we will cleanup
428457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    // the lazy callback and then delete it. This will allow for any refs and resources being held
429457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    // by the standard function to be released. This is specifically useful in non-dll cases where
430457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    // we make lazy proxies and instantiate them immediately.
431457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    // Note: This is ignored if fLazyInstantiateCallback is null.
432457469c7a0c879b9d8ff8ed9fabe3f3dcab06097Greg Daniel    LazyInstantiationType fLazyInstantiationType;
433e8fabb2665d12ee289bc3af5b7e93c5b12396e2dRobert Phillips    SkDEBUGCODE(virtual void validateLazySurface(const GrSurface*) = 0;)
434706a6ff60c55bee85cff06fc9f8f3764f6e5154bChris Dalton
4358bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
43629e52f13f632c701bd33d802701f5ff29a567eeaRobert Phillips    SkDEBUGCODE(size_t getRawGpuMemorySize_debugOnly() const { return fGpuMemorySize; })
43729e52f13f632c701bd33d802701f5ff29a567eeaRobert Phillips
438bb5711a5e4b9c83f0fc49f2d4ee19ca1e4592e14Brian Salomon    virtual size_t onUninstantiatedGpuMemorySize() const = 0;
43929e52f13f632c701bd33d802701f5ff29a567eeaRobert Phillips
440d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon    bool                 fNeedsClear;
441d17b4a678b4b1df49a8eb84fb8c3c954d292a12cBrian Salomon
4428bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    // This entry is lazily evaluated so, when the proxy wraps a resource, the resource
4438bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    // will be called but, when the proxy is deferred, it will compute the answer itself.
4448bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    // If the proxy computes its own answer that answer is checked (in debug mode) in
4458bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    // the instantiation method.
4468bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips    mutable size_t      fGpuMemorySize;
4478bc06d07f57ede17ccabfa38f1d7e31bbf311ab5Robert Phillips
448f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    // The last opList that wrote to or is currently going to write to this surface
449b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips    // The opList can be closed (e.g., no surface context is currently bound
450b6deea8f0ed61475382fc48c7359118bfdcbff85Robert Phillips    // to this proxy).
451f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    // This back-pointer is required so that we can add a dependancy between
452f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    // the opList used to create the current contents of this surface
453f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    // and the opList of a destination surface to which this one is being drawn or copied.
4546cdc22cde8e6297d34fdaaa3ed5e69ae86c30a77Robert Phillips    // This pointer is unreffed. OpLists own a ref on their surface proxies.
455f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips    GrOpList* fLastOpList;
456f2361d2d93c200cd4555b5e8ecea4531801abaaaRobert Phillips
457c7635fa374b87711e5ccd8222957a8fbdc772f7bRobert Phillips    typedef GrIORefProxy INHERITED;
45876948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips};
45976948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips
46076948d4faaca9fd7730576e2f79790ca8d93c10brobertphillips#endif
461