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