• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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