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