1 /*
2 * Copyright 2023 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 "include/core/SkImageGenerator.h"
9 #include "include/core/SkImageInfo.h"
10 #include "include/core/SkRefCnt.h"
11 #include "include/core/SkSize.h"
12 #include "include/gpu/ganesh/GrBackendSurface.h"
13 #include "include/gpu/ganesh/GrRecordingContext.h"
14 #include "include/gpu/ganesh/GrTypes.h"
15 #include "include/gpu/ganesh/GrExternalTextureGenerator.h"
16 #include "include/private/base/SkAssert.h"
17 #include "include/private/gpu/ganesh/GrTextureGenerator.h"
18 #include "include/private/gpu/ganesh/GrTypesPriv.h"
19 #include "src/gpu/RefCntedCallback.h"
20 #include "src/gpu/Swizzle.h"
21 #include "src/gpu/ganesh/GrCaps.h"
22 #include "src/gpu/ganesh/GrProxyProvider.h"
23 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
24 #include "src/gpu/ganesh/GrSurfaceProxy.h"
25 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
26 #include <cstdint>
27 #include <memory>
28 #include <utility>
29
30 enum class GrImageTexGenPolicy : int;
31
32 namespace skgpu {
33 enum class Mipmapped : bool;
34 }
35
dispose_external_texture(void * context)36 static void dispose_external_texture(void *context) {
37 // Reify the unique_ptr so that we delete the `GrExternalTexture` at the end of scope.
38 auto texture = std::unique_ptr<GrExternalTexture>(reinterpret_cast<GrExternalTexture *>(context));
39 texture->dispose();
40 }
41
GrTextureGenerator(const SkImageInfo & info,uint32_t uniqueID)42 GrTextureGenerator::GrTextureGenerator(const SkImageInfo& info, uint32_t uniqueID)
43 : SkImageGenerator(info, uniqueID) {}
44
generateTexture(GrRecordingContext * ctx,const SkImageInfo & info,skgpu::Mipmapped mipmapped,GrImageTexGenPolicy texGenPolicy)45 GrSurfaceProxyView GrTextureGenerator::generateTexture(GrRecordingContext* ctx,
46 const SkImageInfo& info,
47 skgpu::Mipmapped mipmapped,
48 GrImageTexGenPolicy texGenPolicy) {
49 SkASSERT_RELEASE(fInfo.dimensions() == info.dimensions());
50
51 if (!ctx || ctx->abandoned()) {
52 return {};
53 }
54
55 return this->onGenerateTexture(ctx, info, mipmapped, texGenPolicy);
56 }
57
GrExternalTextureGenerator(const SkImageInfo & info)58 GrExternalTextureGenerator::GrExternalTextureGenerator(const SkImageInfo& info) : GrTextureGenerator(info) {}
59
onGenerateTexture(GrRecordingContext * ctx,const SkImageInfo & info,skgpu::Mipmapped mipmapped,GrImageTexGenPolicy texGenPolicy)60 GrSurfaceProxyView GrExternalTextureGenerator::onGenerateTexture(GrRecordingContext* ctx,
61 const SkImageInfo& info,
62 skgpu::Mipmapped mipmapped,
63 GrImageTexGenPolicy texGenPolicy) {
64 std::unique_ptr<GrExternalTexture> externalTexture = generateExternalTexture(ctx, mipmapped);
65 GrBackendTexture backendTexture = externalTexture->getBackendTexture();
66 const GrBackendFormat& format = backendTexture.getBackendFormat();
67 const GrColorType colorType = SkColorTypeToGrColorType(info.colorType());
68 if (!ctx->priv().caps()->areColorTypeAndFormatCompatible(colorType, format)) {
69 return {};
70 }
71
72 auto cleanupCallback = skgpu::RefCntedCallback::Make(dispose_external_texture, externalTexture.release());
73 sk_sp<GrSurfaceProxy> proxy = ctx->priv().proxyProvider()->wrapBackendTexture(
74 backendTexture,
75 kBorrow_GrWrapOwnership,
76 GrWrapCacheable::kYes,
77 kRead_GrIOType,
78 std::move(cleanupCallback));
79 if (!proxy) {
80 return {};
81 }
82 static constexpr auto kOrigin = kTopLeft_GrSurfaceOrigin;
83 skgpu::Swizzle swizzle = ctx->priv().caps()->getReadSwizzle(format, colorType);
84 return GrSurfaceProxyView(std::move(proxy), kOrigin, swizzle);
85 }
86