1 /*
2 * Copyright 2020 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 ManagedBackendTexture_DEFINED
9 #define ManagedBackendTexture_DEFINED
10
11 #include "include/core/SkRefCnt.h"
12 #include "include/core/SkYUVAInfo.h"
13 #include "include/gpu/GrDirectContext.h"
14
15 class GrRefCntedCallback;
16 struct SkImageInfo;
17
18 namespace sk_gpu_test {
19
20 class ManagedBackendTexture : public SkNVRefCnt<ManagedBackendTexture> {
21 public:
22 /**
23 * Make a managed backend texture with initial pixmap/color data. The 'Args' are any valid set
24 * of arguments to GrDirectContext::createBackendTexture that takes data but with the release
25 * proc/context omitted as the ManagedBackendTexture will provide them.
26 */
27 template <typename... Args>
28 static sk_sp<ManagedBackendTexture> MakeWithData(GrDirectContext*, Args&&...);
29
30 /**
31 * Make a managed backend texture without initial data. The 'Args' are any valid set of
32 * arguments to GrDirectContext::createBackendTexture that does not take data. Because our
33 * createBackendTexture methods that *do* take data also use default args for the proc/context
34 * this can be used to make a texture with data but then the MBET won't be able to ensure that
35 * the upload has completed before the texture is deleted. Use the WithData variant instead to
36 * avoid this issue.
37 */
38 template <typename... Args>
39 static sk_sp<ManagedBackendTexture> MakeWithoutData(GrDirectContext*, Args&&...);
40
41
42 static sk_sp<ManagedBackendTexture> MakeFromInfo(GrDirectContext* dContext,
43 const SkImageInfo&,
44 GrMipmapped = GrMipmapped::kNo,
45 GrRenderable = GrRenderable::kNo,
46 GrProtected = GrProtected::kNo);
47
48 static sk_sp<ManagedBackendTexture> MakeFromBitmap(GrDirectContext*,
49 const SkBitmap&,
50 GrMipmapped,
51 GrRenderable,
52 GrProtected = GrProtected::kNo);
53
54 static sk_sp<ManagedBackendTexture> MakeFromPixmap(GrDirectContext*,
55 const SkPixmap&,
56 GrMipmapped,
57 GrRenderable,
58 GrProtected = GrProtected::kNo);
59
60 /** GrGpuFinishedProc or image/surface release proc. */
61 static void ReleaseProc(void* context);
62
63 ~ManagedBackendTexture();
64
65 /**
66 * The context to use with ReleaseProc. This adds a ref so it *must* be balanced by a call to
67 * ReleaseProc. If a wrappedProc is provided then it will be called by ReleaseProc.
68 */
69 void* releaseContext(GrGpuFinishedProc wrappedProc = nullptr,
70 GrGpuFinishedContext wrappedContext = nullptr) const;
71
72 sk_sp<GrRefCntedCallback> refCountedCallback() const;
73
74 /**
75 * Call if the underlying GrBackendTexture was adopted by a GrContext. This clears this out the
76 * MBET without deleting the texture.
77 */
78 void wasAdopted();
79
80 /**
81 * SkImage::MakeFromYUVATextures takes a single release proc that is called once for all the
82 * textures. This makes a single release context for the group of textures. It's used with the
83 * standard ReleaseProc. Like releaseContext(), it must be balanced by a ReleaseProc call for
84 * proper ref counting.
85 */
86 static void* MakeYUVAReleaseContext(const sk_sp<ManagedBackendTexture>[SkYUVAInfo::kMaxPlanes]);
87
texture()88 const GrBackendTexture& texture() { return fTexture; }
89
90 private:
91 ManagedBackendTexture() = default;
92 ManagedBackendTexture(const ManagedBackendTexture&) = delete;
93 ManagedBackendTexture(ManagedBackendTexture&&) = delete;
94
95 sk_sp<GrDirectContext> fDContext;
96 GrBackendTexture fTexture;
97 };
98
99 template <typename... Args>
MakeWithData(GrDirectContext * dContext,Args &&...args)100 inline sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeWithData(GrDirectContext* dContext,
101 Args&&... args) {
102 sk_sp<ManagedBackendTexture> mbet(new ManagedBackendTexture);
103 mbet->fDContext = sk_ref_sp(dContext);
104 mbet->fTexture = dContext->createBackendTexture(std::forward<Args>(args)...,
105 ReleaseProc,
106 mbet->releaseContext());
107 if (!mbet->fTexture.isValid()) {
108 return nullptr;
109 }
110 return mbet;
111 }
112
113 template <typename... Args>
MakeWithoutData(GrDirectContext * dContext,Args &&...args)114 inline sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeWithoutData(
115 GrDirectContext* dContext,
116 Args&&... args) {
117 GrBackendTexture texture =
118 dContext->createBackendTexture(std::forward<Args>(args)...);
119 if (!texture.isValid()) {
120 return nullptr;
121 }
122 sk_sp<ManagedBackendTexture> mbet(new ManagedBackendTexture);
123 mbet->fDContext = sk_ref_sp(dContext);
124 mbet->fTexture = std::move(texture);
125 return mbet;
126 }
127
128 } // namespace sk_gpu_test
129
130 #endif
131