Flutter Engine
The Flutter Engine
GrAHardwareBufferImageGenerator.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2017 Google Inc.
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
9
10#if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
11
13
31#include "src/gpu/ganesh/SkGr.h"
32
34
35std::unique_ptr<SkImageGenerator> GrAHardwareBufferImageGenerator::Make(
36 AHardwareBuffer* graphicBuffer, SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace,
37 GrSurfaceOrigin surfaceOrigin) {
38 AHardwareBuffer_Desc bufferDesc;
39 AHardwareBuffer_describe(graphicBuffer, &bufferDesc);
40
42 AHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
43 SkImageInfo info = SkImageInfo::Make(bufferDesc.width, bufferDesc.height, colorType,
44 alphaType, std::move(colorSpace));
45
46 bool createProtectedImage = 0 != (bufferDesc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT);
47 return std::unique_ptr<SkImageGenerator>(new GrAHardwareBufferImageGenerator(
48 info, graphicBuffer, alphaType, createProtectedImage,
49 bufferDesc.format, surfaceOrigin));
50}
51
52GrAHardwareBufferImageGenerator::GrAHardwareBufferImageGenerator(const SkImageInfo& info,
53 AHardwareBuffer* hardwareBuffer, SkAlphaType alphaType, bool isProtectedContent,
54 uint32_t bufferFormat, GrSurfaceOrigin surfaceOrigin)
56 , fHardwareBuffer(hardwareBuffer)
57 , fBufferFormat(bufferFormat)
58 , fIsProtectedContent(isProtectedContent)
59 , fSurfaceOrigin(surfaceOrigin) {
60 AHardwareBuffer_acquire(fHardwareBuffer);
61}
62
64 AHardwareBuffer_release(fHardwareBuffer);
65}
66
67///////////////////////////////////////////////////////////////////////////////////////////////////
68
69GrSurfaceProxyView GrAHardwareBufferImageGenerator::makeView(GrRecordingContext* context) {
70 if (context->abandoned()) {
71 return {};
72 }
73
74 auto direct = context->asDirectContext();
75 if (!direct) {
76 return {};
77 }
78
79 GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(direct,
80 fHardwareBuffer,
81 fBufferFormat,
82 false);
83
85
86 int width = this->getInfo().width();
87 int height = this->getInfo().height();
88
89 auto proxyProvider = context->priv().proxyProvider();
90
91 AHardwareBuffer* hardwareBuffer = fHardwareBuffer;
92 AHardwareBuffer_acquire(hardwareBuffer);
93
94 class AutoAHBRelease {
95 public:
96 AutoAHBRelease(AHardwareBuffer* ahb) : fAhb(ahb) {}
97 // std::function() must be CopyConstructible, but ours should never actually be copied.
98 AutoAHBRelease(const AutoAHBRelease&) { SkASSERT(0); }
99 AutoAHBRelease(AutoAHBRelease&& that) : fAhb(that.fAhb) { that.fAhb = nullptr; }
100 ~AutoAHBRelease() { fAhb ? AHardwareBuffer_release(fAhb) : void(); }
101
102 AutoAHBRelease& operator=(AutoAHBRelease&& that) {
103 fAhb = std::exchange(that.fAhb, nullptr);
104 return *this;
105 }
106 AutoAHBRelease& operator=(const AutoAHBRelease&) = delete;
107
108 AHardwareBuffer* get() const { return fAhb; }
109
110 private:
111 AHardwareBuffer* fAhb;
112 };
113
114 sk_sp<GrTextureProxy> texProxy = proxyProvider->createLazyProxy(
115 [direct, buffer = AutoAHBRelease(hardwareBuffer)](
116 GrResourceProvider* resourceProvider,
119 GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
120 GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr;
121 GrAHardwareBufferUtils::TexImageCtx texImageCtx = nullptr;
122
123 bool isProtected = desc.fProtected == GrProtected::kYes;
124 GrBackendTexture backendTex =
125 GrAHardwareBufferUtils::MakeBackendTexture(direct,
126 buffer.get(),
127 desc.fDimensions.width(),
128 desc.fDimensions.height(),
129 &deleteImageProc,
130 &updateImageProc,
131 &texImageCtx,
133 desc.fFormat,
134 false);
135 if (!backendTex.isValid()) {
136 return {};
137 }
138 SkASSERT(deleteImageProc && texImageCtx);
139
140 // We make this texture cacheable to avoid recreating a GrTexture every time this
141 // is invoked. We know the owning SkImage will send an invalidation message when the
142 // image is destroyed, so the texture will be removed at that time. Note that the
143 // proxy will be keyed in GrProxyProvider but that cache just allows extant proxies
144 // to be reused. It does not retain them. After a flush the proxy will be deleted
145 // and a subsequent use of the image will recreate a new proxy around the GrTexture
146 // found in the GrResourceCache.
147 // This is the last use of GrWrapCacheable::kYes so if we actually cached the proxy
148 // we could remove wrapped GrGpuResource caching.
149 sk_sp<GrTexture> tex = resourceProvider->wrapBackendTexture(
151 if (!tex) {
152 deleteImageProc(texImageCtx);
153 return {};
154 }
155
156 if (deleteImageProc) {
157 tex->setRelease(deleteImageProc, texImageCtx);
158 }
159
160 return tex;
161 },
162 backendFormat,
163 {width, height},
169 GrProtected(fIsProtectedContent),
171 "AHardwareBufferImageGenerator_MakeView");
172
173 skgpu::Swizzle readSwizzle = context->priv().caps()->getReadSwizzle(backendFormat, grColorType);
174
175 return GrSurfaceProxyView(std::move(texProxy), fSurfaceOrigin, readSwizzle);
176}
177
178GrSurfaceProxyView GrAHardwareBufferImageGenerator::onGenerateTexture(
179 GrRecordingContext* context,
180 const SkImageInfo& info,
181 skgpu::Mipmapped mipmapped,
182 GrImageTexGenPolicy texGenPolicy) {
183 GrSurfaceProxyView texProxyView = this->makeView(context);
184 if (!texProxyView.proxy()) {
185 return {};
186 }
187 SkASSERT(texProxyView.asTextureProxy());
188
189 if (texGenPolicy == GrImageTexGenPolicy::kDraw && mipmapped == skgpu::Mipmapped::kNo) {
190 // If we have the correct mip support, we're done
191 return texProxyView;
192 }
193
194 // Otherwise, make a copy for the requested MIP map setting.
198
199 return GrSurfaceProxyView::Copy(context,
200 std::move(texProxyView),
201 mipmapped,
202 SkIRect::MakeWH(info.width(), info.height()),
204 budgeted,
205 /*label=*/"AHardwareBufferImageGenerator_GenerateTexture");
206}
207
208bool GrAHardwareBufferImageGenerator::onIsValid(GrRecordingContext* context) const {
209 if (nullptr == context) {
210 return false; //CPU backend is not supported, because hardware buffer can be swizzled
211 }
212 return GrBackendApi::kOpenGL == context->backend() ||
213 GrBackendApi::kVulkan == context->backend();
214}
215
216#endif //SK_BUILD_FOR_ANDROID_FRAMEWORK
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
struct AHardwareBuffer AHardwareBuffer
@ kRead_GrIOType
Definition: GrTypesPriv.h:403
@ kBorrow_GrWrapOwnership
Definition: GrTypesPriv.h:79
GrColorType
Definition: GrTypesPriv.h:540
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
skgpu::Protected GrProtected
Definition: GrTypes.h:139
GrSurfaceOrigin
Definition: GrTypes.h:147
SkAlphaType
Definition: SkAlphaType.h:26
#define SkASSERT(cond)
Definition: SkAssert.h:116
SkColorType
Definition: SkColorType.h:19
GrImageTexGenPolicy
Definition: SkGr.h:141
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static std::unique_ptr< SkImageGenerator > Make(AHardwareBuffer *, SkAlphaType, sk_sp< SkColorSpace >, GrSurfaceOrigin)
bool isValid() const
const GrCaps * caps() const
skgpu::Swizzle getReadSwizzle(const GrBackendFormat &format, GrColorType colorType) const
Definition: GrCaps.cpp:443
virtual GrDirectContext * asDirectContext()
SK_API GrBackendApi backend() const
GrProxyProvider * proxyProvider()
GrRecordingContextPriv priv()
bool abandoned() override
sk_sp< GrTexture > wrapBackendTexture(const GrBackendTexture &tex, GrWrapOwnership, GrWrapCacheable, GrIOType)
GrTextureProxy * asTextureProxy() const
GrSurfaceProxy * proxy() const
static GrSurfaceProxyView Copy(GrRecordingContext *context, GrSurfaceProxyView src, skgpu::Mipmapped mipmapped, SkIRect srcRect, SkBackingFit fit, skgpu::Budgeted budgeted, std::string_view label)
void setRelease(sk_sp< skgpu::RefCntedCallback > releaseHelper)
Definition: GrSurface.cpp:60
const SkImageInfo & getInfo() const
bool isProtected() const
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
const myers::Point & get(const myers::Segment &)
Budgeted
Definition: GpuTypes.h:35
Mipmapped
Definition: GpuTypes.h:53
int32_t height
int32_t width
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
Definition: SkRect.h:56
int width() const
Definition: SkImageInfo.h:365
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
int height() const
Definition: SkImageInfo.h:371