1/*
2 * Copyright 2019 Google LLC
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#ifndef GrSurfaceProxyView_DEFINED
9#define GrSurfaceProxyView_DEFINED
10
11#include "include/core/SkRefCnt.h"
12#include "include/gpu/GrTypes.h"
13#include "src/gpu/GrRenderTargetProxy.h"
14#include "src/gpu/GrSurfaceProxy.h"
15#include "src/gpu/GrSwizzle.h"
16#include "src/gpu/GrTextureProxy.h"
17
18class GrSurfaceProxyView {
19public:
20    GrSurfaceProxyView() = default;
21
22    GrSurfaceProxyView(sk_sp<GrSurfaceProxy> proxy, GrSurfaceOrigin origin, GrSwizzle swizzle)
23            : fProxy(std::move(proxy)), fOrigin(origin), fSwizzle(swizzle) {}
24
25    // This entry point is used when we don't care about the origin or the swizzle.
26    explicit GrSurfaceProxyView(sk_sp<GrSurfaceProxy> proxy)
27            : fProxy(std::move(proxy)), fOrigin(kTopLeft_GrSurfaceOrigin) {}
28
29    GrSurfaceProxyView(GrSurfaceProxyView&& view) = default;
30    GrSurfaceProxyView(const GrSurfaceProxyView&) = default;
31
32    operator bool() const { return SkToBool(fProxy.get()); }
33
34    GrSurfaceProxyView& operator=(const GrSurfaceProxyView&) = default;
35    GrSurfaceProxyView& operator=(GrSurfaceProxyView&& view) = default;
36
37    bool operator==(const GrSurfaceProxyView& view) const {
38        return fProxy->uniqueID() == view.fProxy->uniqueID() &&
39               fOrigin == view.fOrigin &&
40               fSwizzle == view.fSwizzle;
41    }
42    bool operator!=(const GrSurfaceProxyView& other) const { return !(*this == other); }
43
44    int width() const { return this->proxy()->width(); }
45    int height() const { return this->proxy()->height(); }
46    SkISize dimensions() const { return this->proxy()->dimensions(); }
47
48    GrMipmapped mipmapped() const {
49        if (const GrTextureProxy* proxy = this->asTextureProxy()) {
50            return proxy->mipmapped();
51        }
52        return GrMipmapped::kNo;
53    }
54
55    GrSurfaceProxy* proxy() const { return fProxy.get(); }
56    sk_sp<GrSurfaceProxy> refProxy() const { return fProxy; }
57
58    GrTextureProxy* asTextureProxy() const {
59        if (!fProxy) {
60            return nullptr;
61        }
62        return fProxy->asTextureProxy();
63    }
64    sk_sp<GrTextureProxy> asTextureProxyRef() const {
65        return sk_ref_sp<GrTextureProxy>(this->asTextureProxy());
66    }
67
68    GrRenderTargetProxy* asRenderTargetProxy() const {
69        if (!fProxy) {
70            return nullptr;
71        }
72        return fProxy->asRenderTargetProxy();
73    }
74
75    sk_sp<GrRenderTargetProxy> asRenderTargetProxyRef() const {
76        return sk_ref_sp<GrRenderTargetProxy>(this->asRenderTargetProxy());
77    }
78
79    GrSurfaceOrigin origin() const { return fOrigin; }
80    GrSwizzle swizzle() const { return fSwizzle; }
81
82    void concatSwizzle(GrSwizzle swizzle) { fSwizzle = GrSwizzle::Concat(fSwizzle, swizzle); }
83
84    GrSurfaceProxyView makeSwizzle(GrSwizzle swizzle) const & {
85        return {fProxy, fOrigin, GrSwizzle::Concat(fSwizzle, swizzle)};
86    }
87
88    GrSurfaceProxyView makeSwizzle(GrSwizzle swizzle) && {
89        return {std::move(fProxy), fOrigin, GrSwizzle::Concat(fSwizzle, swizzle)};
90    }
91
92    void reset() {
93        *this = {};
94    }
95
96    // Helper that copies a rect of a src view'' proxy and then creates a view for the copy with
97    // the same origin and swizzle as the src view.
98    static GrSurfaceProxyView Copy(GrRecordingContext* context,
99                                   GrSurfaceProxyView src,
100                                   GrMipmapped mipMapped,
101                                   SkIRect srcRect,
102                                   SkBackingFit fit,
103                                   SkBudgeted budgeted) {
104        auto copy = GrSurfaceProxy::Copy(context,
105                                         src.refProxy(),
106                                         src.origin(),
107                                         mipMapped,
108                                         srcRect,
109                                         fit,
110                                         budgeted);
111        return {std::move(copy), src.origin(), src.swizzle()};
112    }
113
114    static GrSurfaceProxyView Copy(GrRecordingContext* rContext,
115                                   GrSurfaceProxyView src,
116                                   GrMipmapped mipMapped,
117                                   SkBackingFit fit,
118                                   SkBudgeted budgeted) {
119        auto copy = GrSurfaceProxy::Copy(rContext,
120                                         src.refProxy(),
121                                         src.origin(),
122                                         mipMapped,
123                                         fit,
124                                         budgeted);
125        return {std::move(copy), src.origin(), src.swizzle()};
126    }
127
128    // This does not reset the origin or swizzle, so the View can still be used to access those
129    // properties associated with the detached proxy.
130    sk_sp<GrSurfaceProxy> detachProxy() {
131        return std::move(fProxy);
132    }
133
134private:
135    sk_sp<GrSurfaceProxy> fProxy;
136    GrSurfaceOrigin fOrigin = kTopLeft_GrSurfaceOrigin;
137    GrSwizzle fSwizzle;
138};
139
140#endif
141
142