xref: /aosp_15_r20/external/skia/src/image/SkImage_AndroidFactories.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkTypes.h"
9 
10 #if defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
11 
12 #include "include/android/SkImageAndroid.h"
13 
14 #include "include/android/AHardwareBufferUtils.h"
15 #include "include/android/GrAHardwareBufferUtils.h"
16 #include "include/core/SkAlphaType.h"
17 #include "include/core/SkBitmap.h"
18 #include "include/core/SkColorSpace.h"
19 #include "include/core/SkData.h"
20 #include "include/core/SkImage.h"
21 #include "include/core/SkImageGenerator.h"
22 #include "include/core/SkImageInfo.h"
23 #include "include/core/SkPixmap.h"
24 #include "include/core/SkRect.h"
25 #include "include/core/SkSize.h"
26 #include "include/core/SkSurface.h"
27 #include "include/gpu/GpuTypes.h"
28 #include "include/gpu/ganesh/GrBackendSurface.h"
29 #include "include/gpu/ganesh/GrContextThreadSafeProxy.h"
30 #include "include/gpu/ganesh/GrDirectContext.h"
31 #include "include/gpu/ganesh/GrRecordingContext.h"
32 #include "include/gpu/ganesh/GrTypes.h"
33 #include "include/gpu/ganesh/SkImageGanesh.h"
34 #include "include/private/base/SkAssert.h"
35 #include "include/private/gpu/ganesh/GrImageContext.h"
36 #include "include/private/gpu/ganesh/GrTypesPriv.h"
37 #include "src/core/SkAutoPixmapStorage.h"
38 #include "src/core/SkImageInfoPriv.h"
39 #include "src/gpu/RefCntedCallback.h"
40 #include "src/gpu/SkBackingFit.h"
41 #include "src/gpu/ganesh/GrAHardwareBufferImageGenerator.h"
42 #include "src/gpu/ganesh/GrBackendTextureImageGenerator.h"
43 #include "src/gpu/ganesh/GrBackendUtils.h"
44 #include "src/gpu/ganesh/GrCaps.h"
45 #include "src/gpu/ganesh/GrColorInfo.h"
46 #include "src/gpu/ganesh/GrColorSpaceXform.h"
47 #include "src/gpu/ganesh/GrContextThreadSafeProxyPriv.h"
48 #include "src/gpu/ganesh/GrDirectContextPriv.h"
49 #include "src/gpu/ganesh/GrDrawingManager.h"
50 #include "src/gpu/ganesh/GrFragmentProcessor.h"
51 #include "src/gpu/ganesh/GrGpu.h"
52 #include "src/gpu/ganesh/GrGpuResourcePriv.h"
53 #include "src/gpu/ganesh/GrImageContextPriv.h"
54 #include "src/gpu/ganesh/GrImageInfo.h"
55 #include "src/gpu/ganesh/GrProxyProvider.h"
56 #include "src/gpu/ganesh/GrRecordingContextPriv.h"
57 #include "src/gpu/ganesh/GrRenderTask.h"
58 #include "src/gpu/ganesh/GrSemaphore.h"
59 #include "src/gpu/ganesh/GrSurfaceProxy.h"
60 #include "src/gpu/ganesh/GrTexture.h"
61 #include "src/gpu/ganesh/GrTextureProxy.h"
62 #include "src/gpu/ganesh/SkGr.h"
63 #include "src/gpu/ganesh/SurfaceContext.h"
64 #include "src/gpu/ganesh/SurfaceFillContext.h"
65 #include "src/gpu/ganesh/effects/GrTextureEffect.h"
66 #include "src/gpu/ganesh/image/SkImage_Ganesh.h"
67 #include "src/image/SkImage_Base.h"
68 
69 #include <algorithm>
70 #include <cstddef>
71 #include <utility>
72 
73 #include <android/hardware_buffer.h>
74 
75 namespace SkImages {
76 
DeferredFromAHardwareBuffer(AHardwareBuffer * graphicBuffer,SkAlphaType at)77 sk_sp<SkImage> DeferredFromAHardwareBuffer(AHardwareBuffer* graphicBuffer, SkAlphaType at) {
78     auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, nullptr,
79                                                      kTopLeft_GrSurfaceOrigin);
80     return DeferredFromGenerator(std::move(gen));
81 }
82 
DeferredFromAHardwareBuffer(AHardwareBuffer * graphicBuffer,SkAlphaType at,sk_sp<SkColorSpace> cs,GrSurfaceOrigin surfaceOrigin)83 sk_sp<SkImage> DeferredFromAHardwareBuffer(AHardwareBuffer* graphicBuffer,
84                                            SkAlphaType at,
85                                            sk_sp<SkColorSpace> cs,
86                                            GrSurfaceOrigin surfaceOrigin) {
87     auto gen = GrAHardwareBufferImageGenerator::Make(graphicBuffer, at, cs, surfaceOrigin);
88     return DeferredFromGenerator(std::move(gen));
89 }
90 
TextureFromAHardwareBufferWithData(GrDirectContext * dContext,const SkPixmap & pixmap,AHardwareBuffer * hardwareBuffer,GrSurfaceOrigin surfaceOrigin)91 sk_sp<SkImage> TextureFromAHardwareBufferWithData(GrDirectContext* dContext,
92                                                   const SkPixmap& pixmap,
93                                                   AHardwareBuffer* hardwareBuffer,
94                                                   GrSurfaceOrigin surfaceOrigin) {
95     AHardwareBuffer_Desc bufferDesc;
96     AHardwareBuffer_describe(hardwareBuffer, &bufferDesc);
97 
98     if (!SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE)) {
99         return nullptr;
100     }
101 
102 
103     GrBackendFormat backendFormat = GrAHardwareBufferUtils::GetBackendFormat(dContext,
104                                                                              hardwareBuffer,
105                                                                              bufferDesc.format,
106                                                                              true);
107 
108     if (!backendFormat.isValid()) {
109         return nullptr;
110     }
111 
112     GrAHardwareBufferUtils::DeleteImageProc deleteImageProc = nullptr;
113     GrAHardwareBufferUtils::UpdateImageProc updateImageProc = nullptr;
114     GrAHardwareBufferUtils::TexImageCtx deleteImageCtx = nullptr;
115 
116     const bool isRenderable = SkToBool(bufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER);
117 
118     GrBackendTexture backendTexture =
119             GrAHardwareBufferUtils::MakeBackendTexture(dContext, hardwareBuffer,
120                                                        bufferDesc.width, bufferDesc.height,
121                                                        &deleteImageProc, &updateImageProc,
122                                                        &deleteImageCtx, false, backendFormat,
123                                                        isRenderable);
124     if (!backendTexture.isValid()) {
125         return nullptr;
126     }
127     SkASSERT(deleteImageProc);
128 
129     auto releaseHelper = skgpu::RefCntedCallback::Make(deleteImageProc, deleteImageCtx);
130 
131     SkColorType colorType =
132             AHardwareBufferUtils::GetSkColorTypeFromBufferFormat(bufferDesc.format);
133 
134     GrColorType grColorType = SkColorTypeToGrColorType(colorType);
135 
136     GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();
137     if (!proxyProvider) {
138         return nullptr;
139     }
140 
141     sk_sp<GrTextureProxy> proxy = proxyProvider->wrapBackendTexture(
142             backendTexture, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType,
143             std::move(releaseHelper));
144     if (!proxy) {
145         return nullptr;
146     }
147 
148     skgpu::Swizzle swizzle = dContext->priv().caps()->getReadSwizzle(backendFormat, grColorType);
149     GrSurfaceProxyView framebufferView(std::move(proxy), surfaceOrigin, swizzle);
150     SkColorInfo colorInfo = pixmap.info().colorInfo().makeColorType(colorType);
151     sk_sp<SkImage> image = sk_make_sp<SkImage_Ganesh>(
152             sk_ref_sp(dContext), kNeedNewImageUniqueID, framebufferView, std::move(colorInfo));
153     if (!image) {
154         return nullptr;
155     }
156 
157     GrDrawingManager* drawingManager = dContext->priv().drawingManager();
158     if (!drawingManager) {
159         return nullptr;
160     }
161 
162     skgpu::ganesh::SurfaceContext surfaceContext(
163             dContext, std::move(framebufferView), image->imageInfo().colorInfo());
164 
165     surfaceContext.writePixels(dContext, pixmap, {0, 0});
166 
167     GrSurfaceProxy* p[1] = {surfaceContext.asSurfaceProxy()};
168     drawingManager->flush(p, SkSurfaces::BackendSurfaceAccess::kNoAccess, {}, nullptr);
169 
170     return image;
171 }
172 
173 }  // namespace SkImages
174 
175 #endif // defined(SK_BUILD_FOR_ANDROID) && __ANDROID_API__ >= 26
176