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