1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef IMAGE_H
17 #define IMAGE_H
18
19 #include "drawing/engine_adapter/impl_interface/image_impl.h"
20 #include "include/core/SkImage.h"
21 #include "utils/drawing_macros.h"
22 #ifdef RS_ENABLE_VK
23 #include "vulkan/vulkan.h"
24 #endif
25
26 #include "yuv_info.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 namespace Drawing {
31 enum class BitDepth {
32 KU8,
33 KF16,
34 };
35
36 enum class CompressedType {
37 NoneType,
38 ETC2_RGB8_UNORM, // the same ad ETC1
39 BC1_RGB8_UNORM,
40 BC1_RGBA8_UNORM,
41 ASTC_RGBA8_4x4,
42 ASTC_RGBA8_6x6,
43 ASTC_RGBA8_8x8,
44 };
45
46 enum class TextureOrigin {
47 TOP_LEFT,
48 BOTTOM_LEFT,
49 };
50
51 class Surface;
52
53 #ifdef RS_ENABLE_VK
54 struct VKAlloc {
55 VkDeviceMemory memory = VK_NULL_HANDLE;
56 VkDeviceSize offset = 0;
57 VkDeviceSize size = 0;
58 uint32_t flags = 0;
59 std::string statName = "";
60 };
61
62 struct VKYcbcrConversionInfo {
63 VkFormat format = VK_FORMAT_UNDEFINED;
64 uint64_t externalFormat = 0;
65 VkSamplerYcbcrModelConversion ycbcrModel = VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY;
66 VkSamplerYcbcrRange ycbcrRange = VK_SAMPLER_YCBCR_RANGE_ITU_FULL;
67 VkChromaLocation xChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
68 VkChromaLocation yChromaOffset = VK_CHROMA_LOCATION_COSITED_EVEN;
69 VkFilter chromaFilter = VK_FILTER_NEAREST;
70 VkBool32 forceExplicitReconstruction = false;
71 VkFormatFeatureFlags formatFeatures = 0;
72 };
73
74 struct VKTextureInfo {
75 VkImage vkImage = VK_NULL_HANDLE;
76 VKAlloc vkAlloc;
77 VkImageTiling imageTiling = VK_IMAGE_TILING_OPTIMAL;
78 VkImageLayout imageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
79 VkFormat format = VK_FORMAT_UNDEFINED;
80 VkImageUsageFlags imageUsageFlags = 0;
81 uint32_t sampleCount = 1;
82 uint32_t levelCount = 0;
83 uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED;
84 bool vkProtected = false;
85 VKYcbcrConversionInfo ycbcrConversionInfo;
86 VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE;
87 };
88 #endif
89
90 class DRAWING_API TextureInfo {
91 public:
92 /*
93 * @brief Sets the width value of Texture.
94 */
SetWidth(int width)95 void SetWidth(int width)
96 {
97 width_ = width;
98 }
99
100 /*
101 * @brief Sets the height value of Texture.
102 */
SetHeight(int height)103 void SetHeight(int height)
104 {
105 height_ = height;
106 }
107
108 /*
109 * @brief Used to say whether a texture has mip levels allocated or not.
110 */
SetIsMipMapped(bool isMipMapped)111 void SetIsMipMapped(bool isMipMapped)
112 {
113 isMipMapped_ = isMipMapped;
114 }
115
116 /*
117 * @brief Sets the target type of texture to render.
118 * @param target The target type of texture.
119 */
SetTarget(unsigned int target)120 void SetTarget(unsigned int target)
121 {
122 target_ = target;
123 }
124
125 /*
126 * @brief Sets the Id of texture to render.
127 * @param id Texture Id value.
128 */
SetID(unsigned int id)129 void SetID(unsigned int id)
130 {
131 id_ = id;
132 }
133
134 /*
135 * @brief Set the format of texture.
136 * @param format The format of texture.
137 */
SetFormat(unsigned int format)138 void SetFormat(unsigned int format)
139 {
140 format_ = format;
141 }
142
143 /*
144 * @brief Gets the width of TextureInfo.
145 */
GetWidth()146 int GetWidth() const
147 {
148 return width_;
149 }
150
151 /*
152 * @brief Gets the height of TextureInfo.
153 */
GetHeight()154 int GetHeight() const
155 {
156 return height_;
157 }
158
159 /*
160 * @brief Gets whether the texture has mip levels allocated.
161 */
GetIsMipMapped()162 bool GetIsMipMapped() const
163 {
164 return isMipMapped_;
165 }
166
167 /*
168 * @brief Gets the target type of TextureInfo.
169 * @return The target type of TextureInfo.
170 */
GetTarget()171 unsigned int GetTarget() const
172 {
173 return target_;
174 }
175
176 /*
177 * @brief Gets the Id of TextureInfo.
178 * @return The Id of TextureInfo.
179 */
GetID()180 unsigned int GetID() const
181 {
182 return id_;
183 }
184
185 /*
186 * @brief Gets the format of TextureInfo.
187 * @return The target format of TextureInfo.
188 */
GetFormat()189 unsigned int GetFormat() const
190 {
191 return format_;
192 }
193
194 #ifdef RS_ENABLE_VK
GetVKTextureInfo()195 std::shared_ptr<VKTextureInfo> GetVKTextureInfo() const
196 {
197 return vkTextureInfo_;
198 }
SetVKTextureInfo(std::shared_ptr<VKTextureInfo> vkTextureInfo)199 void SetVKTextureInfo(std::shared_ptr<VKTextureInfo> vkTextureInfo)
200 {
201 vkTextureInfo_ = vkTextureInfo;
202 }
203 #endif
204 private:
205 int width_ = 0;
206 int height_ = 0;
207 bool isMipMapped_ = false;
208 unsigned int target_ = 0;
209 unsigned int id_ = 0;
210 unsigned int format_ = 0;
211 #ifdef RS_ENABLE_VK
212 std::shared_ptr<VKTextureInfo> vkTextureInfo_ = nullptr;
213 #endif
214 };
215
216 class DRAWING_API BackendTexture {
217 public:
218 BackendTexture() noexcept;
219 BackendTexture(bool isValid) noexcept;
~BackendTexture()220 virtual ~BackendTexture() {};
221
222 bool IsValid() const;
223 void SetTextureInfo(const TextureInfo& textureInfo);
224 const TextureInfo& GetTextureInfo() const;
225
226 private:
227 bool isValid_;
228 TextureInfo textureInfo_;
229 };
230
231 class DRAWING_API Image {
232 public:
233 Image() noexcept;
234 // constructor adopt a raw image ptr, using for ArkUI, should remove after enable multi-media image decode.
235 explicit Image(void* rawImg) noexcept;
236 explicit Image(std::shared_ptr<ImageImpl> imageImpl);
~Image()237 virtual ~Image() {};
238 bool BuildFromBitmap(const Bitmap& bitmap);
239
240 /**
241 * @brief Create Image from Pixmap.
242 * @param pixmap pixmap.
243 * @param rasterReleaseProc function called when pixels can be released; or nullptr.
244 * @param releaseContext state passed to rasterReleaseProc; or nullptr.
245 * @return Image sharing pixmap.
246 */
247 static std::shared_ptr<Image> MakeFromRaster(const Pixmap& pixmap,
248 RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext);
249
250 /**
251 * @brief Create Image from ImageInfo, sharing pixels.
252 * @param info Image info which contains width, height, alpha type, color type and color space.
253 * @param pixels Address or pixel storage.
254 * @param rowBytes Image sharing pixels, or nullptr.
255 * @return A shared pointer to Image.
256 */
257 static std::shared_ptr<Image> MakeRasterData(const ImageInfo& info, std::shared_ptr<Data> pixels,
258 size_t rowBytes);
259 #ifdef RS_ENABLE_GPU
260 /**
261 * @brief Create YUV Image from pixelmap.
262 * @param gpuContext GPU context.
263 * @param info YUV Info.
264 * @param memory A pointer of pixelmap memory.
265 * @return A shared pointer to Image.
266 */
267 static std::shared_ptr<Image> MakeFromYUVAPixmaps(GPUContext& gpuContext, const YUVInfo& info, void* memory);
268
269 /**
270 * @brief Create Image from Bitmap. Image is uploaded to GPU back-end using context.
271 * @param gpuContext GPU context.
272 * @param bitmap BitmapInfo, pixel address and row bytes.
273 * @return True if Image is created succeeded.
274 */
275 bool BuildFromBitmap(GPUContext& gpuContext, const Bitmap& bitmap);
276
277 bool MakeFromEncoded(const std::shared_ptr<Data>& data);
278
279 /**
280 * @brief Create a GPU-backed Image from compressed data.
281 * @param gpuContext GPU context.
282 * @param data Compressed data to store in Image.
283 * @param width Width of full Image.
284 * @param height Height of full Image.
285 * @param type Type of compression used.
286 * @return True if Image is created succeeded.
287 */
288 bool BuildFromCompressed(GPUContext& gpuContext, const std::shared_ptr<Data>& data, int width, int height,
289 CompressedType type, const std::shared_ptr<ColorSpace>& colorSpace = nullptr);
290
291 /**
292 * @brief Create Image from GPU texture associated with context.
293 * @param gpuContext GPU context.
294 * @param info Texture info.
295 * @param origin The origin of the texture space corresponds to the context pixel.
296 One of TextureOrigin::Top_Left, TextureOrigion::Bottom_Left.
297 * @param bitmapFormat It contains ColorType and AlphaType.
298 * @param colorSpace Range of colors, may be nullptr.
299 * @return True if Image is created succeeded.
300 */
301 bool BuildFromTexture(GPUContext& gpuContext, const TextureInfo& info, TextureOrigin origin,
302 BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace,
303 void (*deleteFunc)(void*) = nullptr, void* cleanupHelper = nullptr);
304
305 /**
306 * @brief GetBackendTexture from surface, then create Image from GPU texture associated with context.
307 * @param gpuContext GPU context
308 * @param surface surface
309 * @param origin The origin of the texture space corresponds to the context pixel.
310 One of TextureOrigin::Top_Left, TextureOrigion::Bottom_Left.
311 * @param bitmapFormat It contains ColorType and AlphaType.
312 * @param colorSpace Range of colors, may be nullptr.
313 * @return True if Image is created succeeded.
314 */
315 bool BuildFromSurface(GPUContext& gpuContext, Surface& surface, TextureOrigin origin,
316 BitmapFormat bitmapFormat, const std::shared_ptr<ColorSpace>& colorSpace);
317
318 /**
319 * @brief Returns subset of this image.
320 * image nullptr if any of the following are true:
321 * - Subset is empty
322 * - Subset is not contained inside the image's bounds
323 * - Pixels in the image could not be read or copied
324 * If this image is texture-backed, the context parameter is required and must match the
325 * context of the source image. If the context parameter is provided, and the image is
326 * raster-backed, the subset will be converted to texture-backed.
327 * @param image subset of this image
328 * @param rect bounds of subset
329 * @param gpuContext the GPUContext in play
330 * @return true if build success
331 */
332 bool BuildSubset(const std::shared_ptr<Image>& image, const RectI& rect, GPUContext& gpuContext);
333
334 BackendTexture GetBackendTexture(bool flushPendingGrContextIO, TextureOrigin* origin) const;
335
336 bool IsValid(GPUContext* context) const;
337 #endif
338
339 /**
340 * @brief Creates raster Bitmap with same pixels as Image.
341 */
342 bool AsLegacyBitmap(Bitmap& bitmap) const;
343
344 /**
345 * @brief Gets the width of Image.
346 * @return width of Image
347 */
348 int GetWidth() const;
349
350 /**
351 * @brief Gets the height of Image.
352 * @return height of image
353 */
354 int GetHeight() const;
355
356 /**
357 * @brief Gets the color type of Image.
358 * @return color Type of Image
359 */
360 ColorType GetColorType() const;
361
362 /**
363 * @brief Gets the alpha type of Image.
364 * @return alpha type of Image
365 */
366 AlphaType GetAlphaType() const;
367
368 /**
369 * @brief Gets the color space of Image.
370 * @return a shared pointer to ColorSpace
371 */
372 std::shared_ptr<ColorSpace> GetColorSpace() const;
373
374 /**
375 * @brief Gets the unique Id of Image.
376 * @return the unique Id of Image
377 */
378 uint32_t GetUniqueID() const;
379
380 /**
381 * @brief Gets the ImageInfo of Image.
382 * @return the ImageInfo of Image
383 */
384 ImageInfo GetImageInfo();
385
386 /**
387 * @brief Copies a Rect of pixels from Image to Bitmap.
388 * @param bitmap Destination Bitmap.
389 * @param x Column index whose absolute value is less than Image width.
390 * @param y Row index whose absolute value is less than Image height.
391 * @return True of pixels are copied to Bitmap.
392 */
393 bool ReadPixels(Bitmap& bitmap, int x, int y);
394
395 /**
396 * @brief Copies a Rect of pixels from Image to Pixmap.
397 * @param pixmap Destination Pixmap.
398 * @param x Column index whose absolute value is less than Image width.
399 * @param y Row index whose absolute value is less than Image height.
400 * @return True of pixels are copied to Pixmap.
401 */
402 bool ReadPixels(Pixmap& pixmap, int x, int y);
403
404 bool ReadPixels(const ImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
405 int32_t srcX, int32_t srcY) const;
406
407 bool ScalePixels(const Bitmap& bitmap, const SamplingOptions& sampling,
408 bool allowCachingHint = true) const;
409
410 std::shared_ptr<Data> EncodeToData(EncodedImageFormat encodedImageFormat, int quality) const;
411
412 bool IsLazyGenerated() const;
413
414 /**
415 * @brief Get Bitmap by image's directContext, can call it if IsLazyGenerated return false.
416 */
417 bool GetROPixels(Bitmap& bitmap) const;
418
419 std::shared_ptr<Image> MakeRasterImage() const;
420
421 bool CanPeekPixels() const;
422
423 /**
424 * @brief Returns true the contents of Image was created on or uploaded to GPU memory,
425 and is available as a GPU texture.
426 * @return True if Image is a GPU texture.
427 */
428 bool IsTextureBacked() const;
429
430 bool IsOpaque() const;
431
432 /*
433 * @brief Tell engine try to cache gpu resource when texture resource create.
434 */
435 void HintCacheGpuResource() const;
436
437 inline void Dump(std::string& out) const;
438
439 template<typename T>
GetImpl()440 T* GetImpl() const
441 {
442 return imageImplPtr->DowncastingTo<T>();
443 }
444
445 // using for recording, should to remove after using shared memory
446 std::shared_ptr<Data> Serialize() const;
447 bool Deserialize(std::shared_ptr<Data> data);
448
449 private:
450 std::shared_ptr<ImageImpl> imageImplPtr;
451 };
452
Dump(std::string & out)453 inline void Image::Dump(std::string& out) const
454 {
455 out += "[width:" + std::to_string(GetWidth());
456 out += " height:" + std::to_string(GetHeight());
457 out += " colorType:" + std::to_string(static_cast<int>(GetColorType()));
458 out += " alphaType:" + std::to_string(static_cast<int>(GetAlphaType()));
459 out += " uniqueID:" + std::to_string(static_cast<int>(GetUniqueID()));
460 out += ']';
461 }
462 } // namespace Drawing
463 } // namespace Rosen
464 } // namespace OHOS
465 #endif
466