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