1 /*
2 * Copyright (c) 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 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
17
18 #include <utility>
19
20 #include "base/image/pixel_map.h"
21 #include "frameworks/core/components_ng/render/adapter/image_painter_utils.h"
22 #include "frameworks/core/image/flutter_image_cache.h"
23 #ifdef ENABLE_ROSEN_BACKEND
24 #include "pipeline/rs_recording_canvas.h"
25 #endif
26
27 namespace OHOS::Ace::NG {
Create(void * rawImage)28 RefPtr<CanvasImage> CanvasImage::Create(void* rawImage)
29 {
30 auto* rsImagePtr = reinterpret_cast<std::shared_ptr<RSImage>*>(rawImage);
31 return AceType::MakeRefPtr<DrawingImage>(*rsImagePtr);
32 }
33
Create()34 RefPtr<CanvasImage> CanvasImage::Create()
35 {
36 return AceType::MakeRefPtr<DrawingImage>();
37 }
38
MakeRSImageFromPixmap(const RefPtr<PixelMap> & pixmap)39 std::shared_ptr<RSImage> DrawingImage::MakeRSImageFromPixmap(const RefPtr<PixelMap>& pixmap)
40 {
41 RSColorType colorType = PixelFormatToRSColorType(pixmap);
42 RSAlphaType alphaType = AlphaTypeToRSAlphaType(pixmap);
43 RSBitmapFormat bitmapFormat = { colorType, alphaType };
44 auto bitmap = std::make_shared<RSBitmap>();
45 bitmap->Build(pixmap->GetWidth(), pixmap->GetHeight(), bitmapFormat);
46 bitmap->SetPixels(const_cast<void*>(reinterpret_cast<const void*>(pixmap->GetPixels())));
47
48 auto image = std::make_shared<RSImage>();
49 image->BuildFromBitmap(*bitmap);
50 return image;
51 }
52
AlphaTypeToRSAlphaType(const RefPtr<PixelMap> & pixmap)53 RSAlphaType DrawingImage::AlphaTypeToRSAlphaType(const RefPtr<PixelMap>& pixmap)
54 {
55 switch (pixmap->GetAlphaType()) {
56 case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
57 return RSAlphaType::ALPHATYPE_UNKNOWN;
58 case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
59 return RSAlphaType::ALPHATYPE_OPAQUE;
60 case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
61 return RSAlphaType::ALPHATYPE_PREMUL;
62 case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
63 return RSAlphaType::ALPHATYPE_UNPREMUL;
64 default:
65 return RSAlphaType::ALPHATYPE_UNKNOWN;
66 }
67 }
68
PixelFormatToRSColorType(const RefPtr<PixelMap> & pixmap)69 RSColorType DrawingImage::PixelFormatToRSColorType(const RefPtr<PixelMap>& pixmap)
70 {
71 switch (pixmap->GetPixelFormat()) {
72 case PixelFormat::RGB_565:
73 return RSColorType::COLORTYPE_RGB_565;
74 case PixelFormat::RGBA_8888:
75 return RSColorType::COLORTYPE_RGBA_8888;
76 case PixelFormat::BGRA_8888:
77 return RSColorType::COLORTYPE_BGRA_8888;
78 case PixelFormat::ALPHA_8:
79 return RSColorType::COLORTYPE_ALPHA_8;
80 case PixelFormat::RGBA_F16:
81 case PixelFormat::UNKNOWN:
82 case PixelFormat::ARGB_8888:
83 case PixelFormat::RGB_888:
84 case PixelFormat::NV21:
85 case PixelFormat::NV12:
86 case PixelFormat::CMYK:
87 default:
88 return RSColorType::COLORTYPE_UNKNOWN;
89 }
90 }
91
ReplaceRSImage(std::shared_ptr<RSImage> image)92 void DrawingImage::ReplaceRSImage(std::shared_ptr<RSImage> image)
93 {
94 image_ = std::move(image);
95 }
96
GetWidth() const97 int32_t DrawingImage::GetWidth() const
98 {
99 return image_ ? image_->GetWidth() : compressWidth_;
100 }
101
GetHeight() const102 int32_t DrawingImage::GetHeight() const
103 {
104 return image_ ? image_->GetHeight() : compressHeight_;
105 }
106
Clone()107 RefPtr<CanvasImage> DrawingImage::Clone()
108 {
109 auto clone = MakeRefPtr<DrawingImage>(image_);
110 clone->uniqueId_ = uniqueId_;
111 clone->compressData_ = std::move(compressData_);
112 clone->compressWidth_ = compressWidth_;
113 clone->compressHeight_ = compressHeight_;
114 return clone;
115 }
116
Cache(const std::string & key)117 void DrawingImage::Cache(const std::string& key)
118 {
119 auto pipelineCtx = PipelineContext::GetCurrentContext();
120 CHECK_NULL_VOID(pipelineCtx);
121 auto cache = pipelineCtx->GetImageCache();
122 CHECK_NULL_VOID(cache);
123
124 auto cached = std::make_shared<CachedImage>(GetImage());
125 cached->uniqueId = GetUniqueID();
126 pipelineCtx->GetImageCache()->CacheImage(key, cached);
127 }
128
QueryFromCache(const std::string & key)129 RefPtr<CanvasImage> DrawingImage::QueryFromCache(const std::string& key)
130 {
131 auto pipelineCtx = PipelineContext::GetCurrentContext();
132 CHECK_NULL_RETURN(pipelineCtx, nullptr);
133 auto cache = pipelineCtx->GetImageCache();
134 CHECK_NULL_RETURN(cache, nullptr);
135 auto cacheImage = cache->GetCacheImage(key);
136 CHECK_NULL_RETURN_NOLOG(cacheImage, nullptr);
137 LOGD("rsImage found in cache: %{public}s", key.c_str());
138
139 auto rosenImage = MakeRefPtr<DrawingImage>(cacheImage->imagePtr);
140 rosenImage->SetUniqueID(cacheImage->uniqueId);
141
142 return rosenImage;
143 }
144
GetPixelMap() const145 RefPtr<PixelMap> DrawingImage::GetPixelMap() const
146 {
147 CHECK_NULL_RETURN(GetImage(), nullptr);
148 auto rsImage = GetImage();
149 RSBitmapFormat rsBitmapFormat = { RSColorType::COLORTYPE_BGRA_8888, rsImage->GetAlphaType() };
150 RSBitmap rsBitmap;
151 rsBitmap.Build(rsImage->GetWidth(), rsImage->GetHeight(), rsBitmapFormat);
152 CHECK_NULL_RETURN(rsImage->ReadPixels(rsBitmap, 0, 0), nullptr);
153 const auto* addr = static_cast<uint32_t*>(rsBitmap.GetPixels());
154 auto width = static_cast<int32_t>(rsBitmap.GetWidth());
155 auto height = static_cast<int32_t>(rsBitmap.GetHeight());
156 int32_t length = width * height;
157 return PixelMap::ConvertSkImageToPixmap(addr, length, width, height);
158 }
159
DrawToRSCanvas(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)160 void DrawingImage::DrawToRSCanvas(
161 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY)
162 {
163 auto image = GetImage();
164 CHECK_NULL_VOID(image || GetCompressData());
165 if (isDrawAnimate_) {
166 RSSamplingOptions options;
167 ImagePainterUtils::ClipRRect(canvas, dstRect, radiusXY);
168 canvas.DrawImageRect(*image, srcRect, dstRect, options);
169 } else {
170 DrawWithRecordingCanvas(canvas, radiusXY);
171 }
172 }
173
DrawWithRecordingCanvas(RSCanvas & canvas,const BorderRadiusArray & radiusXY)174 bool DrawingImage::DrawWithRecordingCanvas(RSCanvas& canvas, const BorderRadiusArray& radiusXY)
175 {
176 #ifdef ENABLE_ROSEN_BACKEND
177 RSBrush brush;
178 auto config = GetPaintConfig();
179 RSSamplingOptions options;
180 ImagePainterUtils::AddFilter(brush, options, config);
181 auto radii = ImagePainterUtils::ToRSRadius(radiusXY);
182 auto recordingCanvas = static_cast<RSRecordingCanvas&>(canvas);
183 std::vector<RSPoint> radius;
184 for (int ii = 0; ii < 4; ii++) {
185 RSPoint point(radii[ii].GetX(), radii[ii].GetY());
186 radius.emplace_back(point);
187 }
188 recordingCanvas.ClipAdaptiveRoundRect(radius);
189 recordingCanvas.Scale(config.scaleX_, config.scaleY_);
190
191 RSPoint pointRadius[4] = {};
192 for (int i = 0; i < 4; i++) {
193 pointRadius[i] = radius[i];
194 }
195 Rosen::Drawing::AdaptiveImageInfo rsImageInfo =
196 {static_cast<int32_t>(config.imageFit_), static_cast<int32_t>(config.imageRepeat_),
197 {pointRadius[0], pointRadius[1], pointRadius[2], pointRadius[3]}, 1.0, GetUniqueID(),
198 GetCompressWidth(), GetCompressHeight()};
199 auto data = GetCompressData();
200 recordingCanvas.AttachBrush(brush);
201 recordingCanvas.DrawImage(GetImage(), std::move(data), rsImageInfo, options);
202 recordingCanvas.DetachBrush();
203 return true;
204 #else // !ENABLE_ROSEN_BACKEND
205 return false;
206 #endif
207 }
208 } // namespace OHOS::Ace::NG
209