xref: /aosp_15_r20/external/skia/tools/gpu/ManagedBackendTexture.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #include "tools/gpu/ManagedBackendTexture.h"
9 
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkImageInfo.h"
12 #include "src/core/SkMipmap.h"
13 #include "src/gpu/RefCntedCallback.h"
14 #ifdef SK_GANESH
15 #include "include/private/gpu/ganesh/GrTypesPriv.h"
16 #endif
17 #ifdef SK_GRAPHITE
18 #include "include/gpu/graphite/Recorder.h"
19 #include "src/gpu/graphite/Caps.h"
20 #endif
21 
22 using Mipmapped = skgpu::Mipmapped;
23 using Protected = skgpu::Protected;
24 using Renderable = skgpu::Renderable;
25 
26 #ifdef SK_GANESH
27 namespace {
28 
29 struct Context {
30     GrGpuFinishedProc fWrappedProc = nullptr;
31     GrGpuFinishedContext fWrappedContext = nullptr;
32     sk_sp<sk_gpu_test::ManagedBackendTexture> fMBETs[SkYUVAInfo::kMaxPlanes];
33 };
34 
35 }  // anonymous namespace
36 
37 namespace sk_gpu_test {
38 
ReleaseProc(void * ctx)39 void ManagedBackendTexture::ReleaseProc(void* ctx) {
40     std::unique_ptr<Context> context(static_cast<Context*>(ctx));
41     if (context->fWrappedProc) {
42         context->fWrappedProc(context->fWrappedContext);
43     }
44 }
45 
~ManagedBackendTexture()46 ManagedBackendTexture::~ManagedBackendTexture() {
47     if (fDContext && fTexture.isValid()) {
48         fDContext->deleteBackendTexture(fTexture);
49     }
50 }
51 
releaseContext(GrGpuFinishedProc wrappedProc,GrGpuFinishedContext wrappedCtx) const52 void* ManagedBackendTexture::releaseContext(GrGpuFinishedProc wrappedProc,
53                                             GrGpuFinishedContext wrappedCtx) const {
54     // Make sure we don't get a wrapped ctx without a wrapped proc
55     SkASSERT(!wrappedCtx || wrappedProc);
56     return new Context{wrappedProc, wrappedCtx, {sk_ref_sp(this)}};
57 }
58 
MakeYUVAReleaseContext(const sk_sp<ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes])59 void* ManagedBackendTexture::MakeYUVAReleaseContext(
60         const sk_sp<ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes]) {
61     auto context = new Context;
62     for (int i = 0; i < SkYUVAInfo::kMaxPlanes; ++i) {
63         context->fMBETs[i] = mbets[i];
64     }
65     return context;
66 }
67 
refCountedCallback() const68 sk_sp<skgpu::RefCntedCallback> ManagedBackendTexture::refCountedCallback() const {
69     return skgpu::RefCntedCallback::Make(ReleaseProc, this->releaseContext());
70 }
71 
wasAdopted()72 void ManagedBackendTexture::wasAdopted() { fTexture = {}; }
73 
MakeFromInfo(GrDirectContext * dContext,const SkImageInfo & ii,Mipmapped mipmapped,Renderable renderable,Protected isProtected)74 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromInfo(GrDirectContext* dContext,
75                                                                  const SkImageInfo& ii,
76                                                                  Mipmapped mipmapped,
77                                                                  Renderable renderable,
78                                                                  Protected isProtected) {
79     return MakeWithoutData(dContext,
80                            ii.width(),
81                            ii.height(),
82                            ii.colorType(),
83                            mipmapped,
84                            renderable,
85                            isProtected);
86 }
87 
MakeFromBitmap(GrDirectContext * dContext,const SkBitmap & src,Mipmapped mipmapped,Renderable renderable,Protected isProtected)88 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromBitmap(GrDirectContext* dContext,
89                                                                    const SkBitmap& src,
90                                                                    Mipmapped mipmapped,
91                                                                    Renderable renderable,
92                                                                    Protected isProtected) {
93     SkPixmap srcPixmap;
94     if (!src.peekPixels(&srcPixmap)) {
95         return nullptr;
96     }
97 
98     return MakeFromPixmap(dContext, srcPixmap, mipmapped, renderable, isProtected);
99 }
100 
MakeFromPixmap(GrDirectContext * dContext,const SkPixmap & src,Mipmapped mipmapped,Renderable renderable,Protected isProtected)101 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromPixmap(GrDirectContext* dContext,
102                                                                    const SkPixmap& src,
103                                                                    Mipmapped mipmapped,
104                                                                    Renderable renderable,
105                                                                    Protected isProtected) {
106     std::vector<SkPixmap> levels({src});
107     std::unique_ptr<SkMipmap> mm;
108 
109     if (mipmapped == Mipmapped::kYes) {
110         mm.reset(SkMipmap::Build(src, nullptr));
111         if (!mm) {
112             return nullptr;
113         }
114         for (int i = 0; i < mm->countLevels(); ++i) {
115             SkMipmap::Level level;
116             SkAssertResult(mm->getLevel(i, &level));
117             levels.push_back(level.fPixmap);
118         }
119     }
120     return MakeWithData(dContext,
121                         levels.data(),
122                         static_cast<int>(levels.size()),
123                         kTopLeft_GrSurfaceOrigin,
124                         renderable,
125                         isProtected);
126 }
127 
128 }  // namespace sk_gpu_test
129 
130 #endif  // SK_GANESH
131 
132 #ifdef SK_GRAPHITE
133 using Recorder = skgpu::graphite::Recorder;
134 
135 namespace {
136 
137 struct MBETContext {
MBETContext__anon71a6d1300211::MBETContext138     MBETContext(const sk_sp<sk_gpu_test::ManagedGraphiteTexture>& tex)
139             : fMBETs{tex, nullptr, nullptr, nullptr} {}
MBETContext__anon71a6d1300211::MBETContext140     MBETContext(const sk_sp<sk_gpu_test::ManagedGraphiteTexture> mbets[SkYUVAInfo::kMaxPlanes])
141             : fMBETs{mbets[0], mbets[1], mbets[2], mbets[3]} {}
142     sk_sp<sk_gpu_test::ManagedGraphiteTexture> fMBETs[SkYUVAInfo::kMaxPlanes];
143 };
144 
145 }  // anonymous namespace
146 
147 namespace sk_gpu_test {
148 
ReleaseProc(void * ctx)149 void ManagedGraphiteTexture::ReleaseProc(void* ctx) {
150     std::unique_ptr<MBETContext> context(static_cast<MBETContext*>(ctx));
151 }
152 
FinishedProc(void * ctx,skgpu::CallbackResult)153 void ManagedGraphiteTexture::FinishedProc(void* ctx, skgpu::CallbackResult) {
154     std::unique_ptr<MBETContext> context(static_cast<MBETContext*>(ctx));
155 }
ImageReleaseProc(void * ctx)156 void ManagedGraphiteTexture::ImageReleaseProc(void* ctx) {
157     std::unique_ptr<MBETContext> context(static_cast<MBETContext*>(ctx));
158 }
159 
~ManagedGraphiteTexture()160 ManagedGraphiteTexture::~ManagedGraphiteTexture() {
161     if (fContext && fTexture.isValid()) {
162         fContext->deleteBackendTexture(fTexture);
163     }
164 }
165 
releaseContext() const166 void* ManagedGraphiteTexture::releaseContext() const {
167     return new MBETContext{{sk_ref_sp(this)}};
168 }
169 
MakeYUVAReleaseContext(const sk_sp<ManagedGraphiteTexture> mbets[SkYUVAInfo::kMaxPlanes])170 void* ManagedGraphiteTexture::MakeYUVAReleaseContext(
171         const sk_sp<ManagedGraphiteTexture> mbets[SkYUVAInfo::kMaxPlanes]) {
172     return new MBETContext(mbets);
173 }
174 
refCountedCallback() const175 sk_sp<skgpu::RefCntedCallback> ManagedGraphiteTexture::refCountedCallback() const {
176     return skgpu::RefCntedCallback::Make(FinishedProc, this->releaseContext());
177 }
178 
MakeUnInit(Recorder * recorder,const SkImageInfo & ii,Mipmapped mipmapped,Renderable renderable,Protected isProtected)179 sk_sp<ManagedGraphiteTexture> ManagedGraphiteTexture::MakeUnInit(Recorder* recorder,
180                                                                  const SkImageInfo& ii,
181                                                                  Mipmapped mipmapped,
182                                                                  Renderable renderable,
183                                                                  Protected isProtected) {
184     sk_sp<ManagedGraphiteTexture> mbet(new ManagedGraphiteTexture);
185     mbet->fContext = recorder->priv().context();
186     const skgpu::graphite::Caps* caps = recorder->priv().caps();
187 
188     skgpu::graphite::TextureInfo info = caps->getDefaultSampledTextureInfo(ii.colorType(),
189                                                                            mipmapped,
190                                                                            isProtected,
191                                                                            renderable);
192 
193     mbet->fTexture = recorder->createBackendTexture(ii.dimensions(), info);
194     if (!mbet->fTexture.isValid()) {
195         return nullptr;
196     }
197 
198     recorder->addFinishInfo({mbet->releaseContext(), FinishedProc});
199 
200     return mbet;
201 }
202 
MakeFromPixmap(Recorder * recorder,const SkPixmap & src,Mipmapped mipmapped,Renderable renderable,Protected isProtected)203 sk_sp<ManagedGraphiteTexture> ManagedGraphiteTexture::MakeFromPixmap(Recorder* recorder,
204                                                                      const SkPixmap& src,
205                                                                      Mipmapped mipmapped,
206                                                                      Renderable renderable,
207                                                                      Protected isProtected) {
208     sk_sp<ManagedGraphiteTexture> mbet = MakeUnInit(recorder, src.info(), mipmapped, renderable,
209                                                     isProtected);
210     if (!mbet) {
211         return nullptr;
212     }
213 
214     std::vector<SkPixmap> levels({src});
215     std::unique_ptr<SkMipmap> mm;
216 
217     if (mipmapped == Mipmapped::kYes) {
218         mm.reset(SkMipmap::Build(src, nullptr));
219         if (!mm) {
220             return nullptr;
221         }
222         for (int i = 0; i < mm->countLevels(); ++i) {
223             SkMipmap::Level level;
224             SkAssertResult(mm->getLevel(i, &level));
225             levels.push_back(level.fPixmap);
226         }
227     }
228 
229     if (!recorder->updateBackendTexture(mbet->fTexture,
230                                         levels.data(),
231                                         static_cast<int>(levels.size()))) {
232         return nullptr;
233     }
234 
235     return mbet;
236 }
237 
MakeMipmappedFromPixmaps(Recorder * recorder,SkSpan<const SkPixmap> levels,skgpu::Renderable renderable,skgpu::Protected isProtected)238 sk_sp<ManagedGraphiteTexture> ManagedGraphiteTexture::MakeMipmappedFromPixmaps(
239         Recorder* recorder,
240         SkSpan<const SkPixmap> levels,
241         skgpu::Renderable renderable,
242         skgpu::Protected isProtected) {
243     if (levels.empty()) {
244         return nullptr;
245     }
246     sk_sp<ManagedGraphiteTexture> mbet = MakeUnInit(recorder,
247                                                     levels[0].info(),
248                                                     Mipmapped::kYes,
249                                                     renderable,
250                                                     isProtected);
251     if (!recorder->updateBackendTexture(mbet->fTexture,
252                                         levels.data(),
253                                         static_cast<int>(levels.size()))) {
254         return nullptr;
255     }
256 
257     return mbet;
258 }
259 
MakeFromCompressedData(Recorder * recorder,SkISize dimensions,SkTextureCompressionType compression,sk_sp<SkData> src,skgpu::Mipmapped mipmapped,skgpu::Protected isProtected)260 sk_sp<ManagedGraphiteTexture> ManagedGraphiteTexture::MakeFromCompressedData(
261         Recorder* recorder,
262         SkISize dimensions,
263         SkTextureCompressionType compression,
264         sk_sp<SkData> src,
265         skgpu::Mipmapped mipmapped,
266         skgpu::Protected isProtected) {
267     sk_sp<ManagedGraphiteTexture> mbet(new ManagedGraphiteTexture);
268     mbet->fContext = recorder->priv().context();
269     const skgpu::graphite::Caps* caps = recorder->priv().caps();
270 
271     skgpu::graphite::TextureInfo info = caps->getDefaultCompressedTextureInfo(compression,
272                                                                               mipmapped,
273                                                                               isProtected);
274 
275     mbet->fTexture = recorder->createBackendTexture(dimensions, info);
276     if (!mbet->fTexture.isValid()) {
277         return nullptr;
278     }
279 
280     recorder->addFinishInfo({mbet->releaseContext(), FinishedProc});
281 
282     if (!recorder->updateCompressedBackendTexture(mbet->fTexture,
283                                                   src->data(),
284                                                   src->size())) {
285         return nullptr;
286     }
287 
288     return mbet;
289 }
290 
291 }  // namespace sk_gpu_test
292 
293 #endif  // SK_GRAPHITE
294