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 "include/private/GrTypesPriv.h"
13 #include "src/core/SkMipmap.h"
14 
15 namespace {
16 
17 struct Context {
18     GrGpuFinishedProc fWrappedProc = nullptr;
19     GrGpuFinishedContext fWrappedContext = nullptr;
20     sk_sp<sk_gpu_test::ManagedBackendTexture> fMBETs[SkYUVAInfo::kMaxPlanes];
21 };
22 
23 }  // anonymous namespace
24 
25 namespace sk_gpu_test {
26 
ReleaseProc(void * ctx)27 void ManagedBackendTexture::ReleaseProc(void* ctx) {
28     std::unique_ptr<Context> context(static_cast<Context*>(ctx));
29     if (context->fWrappedProc) {
30         context->fWrappedProc(context->fWrappedContext);
31     }
32 }
33 
~ManagedBackendTexture()34 ManagedBackendTexture::~ManagedBackendTexture() {
35     if (fDContext && fTexture.isValid()) {
36         fDContext->deleteBackendTexture(fTexture);
37     }
38 }
39 
releaseContext(GrGpuFinishedProc wrappedProc,GrGpuFinishedContext wrappedCtx) const40 void* ManagedBackendTexture::releaseContext(GrGpuFinishedProc wrappedProc,
41                                             GrGpuFinishedContext wrappedCtx) const {
42     // Make sure we don't get a wrapped ctx without a wrapped proc
43     SkASSERT(!wrappedCtx || wrappedProc);
44     return new Context{wrappedProc, wrappedCtx, {sk_ref_sp(this)}};
45 }
46 
MakeYUVAReleaseContext(const sk_sp<ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes])47 void* ManagedBackendTexture::MakeYUVAReleaseContext(
48         const sk_sp<ManagedBackendTexture> mbets[SkYUVAInfo::kMaxPlanes]) {
49     auto context = new Context;
50     for (int i = 0; i < SkYUVAInfo::kMaxPlanes; ++i) {
51         context->fMBETs[i] = mbets[i];
52     }
53     return context;
54 }
55 
refCountedCallback() const56 sk_sp<GrRefCntedCallback> ManagedBackendTexture::refCountedCallback() const {
57     return GrRefCntedCallback::Make(ReleaseProc, this->releaseContext());
58 }
59 
wasAdopted()60 void ManagedBackendTexture::wasAdopted() { fTexture = {}; }
61 
MakeFromInfo(GrDirectContext * dContext,const SkImageInfo & ii,GrMipmapped mipmapped,GrRenderable renderable,GrProtected isProtected)62 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromInfo(GrDirectContext* dContext,
63                                                                  const SkImageInfo& ii,
64                                                                  GrMipmapped mipmapped,
65                                                                  GrRenderable renderable,
66                                                                  GrProtected isProtected) {
67     return MakeWithoutData(
68             dContext, ii.width(), ii.height(), ii.colorType(), mipmapped, renderable, isProtected);
69 }
70 
MakeFromBitmap(GrDirectContext * dContext,const SkBitmap & src,GrMipmapped mipmapped,GrRenderable renderable,GrProtected isProtected)71 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromBitmap(GrDirectContext* dContext,
72                                                                    const SkBitmap& src,
73                                                                    GrMipmapped mipmapped,
74                                                                    GrRenderable renderable,
75                                                                    GrProtected isProtected) {
76     SkPixmap srcPixmap;
77     if (!src.peekPixels(&srcPixmap)) {
78         return nullptr;
79     }
80 
81     return MakeFromPixmap(dContext, srcPixmap, mipmapped, renderable, isProtected);
82 }
83 
MakeFromPixmap(GrDirectContext * dContext,const SkPixmap & src,GrMipmapped mipmapped,GrRenderable renderable,GrProtected isProtected)84 sk_sp<ManagedBackendTexture> ManagedBackendTexture::MakeFromPixmap(GrDirectContext* dContext,
85                                                                    const SkPixmap& src,
86                                                                    GrMipmapped mipmapped,
87                                                                    GrRenderable renderable,
88                                                                    GrProtected isProtected) {
89     std::vector<SkPixmap> levels({src});
90     std::unique_ptr<SkMipmap> mm;
91 
92     if (mipmapped == GrMipmapped::kYes) {
93         mm.reset(SkMipmap::Build(src, nullptr));
94         if (!mm) {
95             return nullptr;
96         }
97         for (int i = 0; i < mm->countLevels(); ++i) {
98             SkMipmap::Level level;
99             SkAssertResult(mm->getLevel(i, &level));
100             levels.push_back(level.fPixmap);
101         }
102     }
103     return MakeWithData(dContext,
104                         levels.data(),
105                         static_cast<int>(levels.size()),
106                         kTopLeft_GrSurfaceOrigin,
107                         renderable,
108                         isProtected);
109 }
110 
111 }  // namespace sk_gpu_test
112