1 /*
2 * Copyright (c) 2022 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 IOS_PLATFORM
17 #include "egl_manager.h"
18 #endif
19
20 #if defined(NEW_SKIA)
21 #include <include/gpu/GrDirectContext.h>
22 #else
23 #include <include/gpu/GrContext.h>
24 #endif
25 #include "include/gpu/gl/GrGLInterface.h"
26
27 #if (!defined(ANDROID_PLATFORM)) && (!defined(IOS_PLATFORM))
28 #include "rs_trace.h"
29 #endif
30
31 #include "sk_image_chain.h"
32 #include "platform/common/rs_system_properties.h"
33
34 namespace OHOS {
35 namespace Rosen {
SKImageChain(SkCanvas * canvas,sk_sp<SkImage> image)36 SKImageChain::SKImageChain(SkCanvas* canvas, sk_sp<SkImage> image) : canvas_(canvas), image_(image)
37 {}
38
SKImageChain(std::shared_ptr<Media::PixelMap> srcPixelMap)39 SKImageChain::SKImageChain(std::shared_ptr<Media::PixelMap> srcPixelMap) : srcPixelMap_(srcPixelMap)
40 {}
41
~SKImageChain()42 SKImageChain::~SKImageChain()
43 {
44 canvas_ = nullptr;
45 gpuSurface_ = nullptr;
46 dstPixmap_ = nullptr;
47 srcPixelMap_ = nullptr;
48 dstPixelMap_ = nullptr;
49 filters_ = nullptr;
50 cpuSurface_ = nullptr;
51 image_ = nullptr;
52 }
53
Render(const std::vector<sk_sp<SkImageFilter>> & skFilters,const bool & forceCPU,std::shared_ptr<Media::PixelMap> & dstPixelMap)54 DrawError SKImageChain::Render(const std::vector<sk_sp<SkImageFilter>>& skFilters, const bool& forceCPU,
55 std::shared_ptr<Media::PixelMap>& dstPixelMap)
56 {
57 for (auto filter : skFilters) {
58 SetFilters(filter);
59 }
60
61 ForceCPU(forceCPU);
62 DrawError ret = Draw();
63 if (ret == DrawError::ERR_OK) {
64 dstPixelMap = GetPixelMap();
65 } else {
66 LOGE("skImage.Draw() = %{public}d", ret);
67 }
68
69 return ret;
70 }
71
InitWithoutCanvas()72 DrawError SKImageChain::InitWithoutCanvas()
73 {
74 if (srcPixelMap_ == nullptr) {
75 LOGE("The srcPixelMap_ is nullptr.");
76 return DrawError::ERR_IMAGE_NULL;
77 }
78 imageInfo_ = SkImageInfo::Make(srcPixelMap_->GetWidth(), srcPixelMap_->GetHeight(),
79 PixelFormatConvert(srcPixelMap_->GetPixelFormat()), static_cast<SkAlphaType>(srcPixelMap_->GetAlphaType()));
80 SkPixmap srcPixmap(imageInfo_, srcPixelMap_->GetPixels(), srcPixelMap_->GetRowStride());
81 SkBitmap srcBitmap;
82 srcBitmap.installPixels(srcPixmap);
83 image_ = SkImage::MakeFromBitmap(srcBitmap);
84 Media::InitializationOptions opts;
85 opts.size.width = srcPixelMap_->GetWidth();
86 opts.size.height = srcPixelMap_->GetHeight();
87 opts.editable = true;
88 auto dstPixelMap = Media::PixelMap::Create(opts);
89 if (dstPixelMap != nullptr) {
90 dstPixmap_ = std::make_shared<SkPixmap>(imageInfo_, dstPixelMap->GetPixels(), dstPixelMap->GetRowStride());
91 dstPixelMap_ = std::shared_ptr<Media::PixelMap>(dstPixelMap.release());
92 } else {
93 LOGE("Failed to create the dstPixelMap.");
94 return DrawError::ERR_IMAGE_NULL;
95 }
96
97 return DrawError::ERR_OK;
98 }
99
CreateCPUCanvas()100 bool SKImageChain::CreateCPUCanvas()
101 {
102 if (dstPixmap_ == nullptr) {
103 LOGE("The dstPixmap_ is nullptr.");
104 return false;
105 }
106 cpuSurface_ = SkSurface::MakeRasterDirect(imageInfo_, const_cast<void*>(dstPixmap_->addr()),
107 dstPixelMap_->GetRowStride());
108 if (!cpuSurface_) {
109 LOGE("Failed to create surface for CPU.");
110 return false;
111 }
112 canvas_ = cpuSurface_->getCanvas();
113 if (canvas_ == nullptr) {
114 LOGE("Failed to getCanvas for CPU.");
115 return false;
116 }
117
118 return true;
119 }
120
CreateGPUCanvas()121 bool SKImageChain::CreateGPUCanvas()
122 {
123 #if defined(ACE_ENABLE_GL) && (!defined(IOS_PLATFORM))
124 if (!EglManager::GetInstance().Init()) {
125 LOGE("Failed to init for GPU.");
126 return false;
127 }
128 sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
129 #if defined(NEW_SKIA)
130 sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface)));
131 #else
132 sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface)));
133 #endif
134 gpuSurface_ = SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kNo, imageInfo_);
135 if (!gpuSurface_) {
136 LOGE("Failed to create surface for GPU.");
137 return false;
138 }
139 canvas_ = gpuSurface_->getCanvas();
140 if (canvas_ == nullptr) {
141 LOGE("Failed to getCanvas for GPU.");
142 return false;
143 }
144
145 return true;
146 #else
147 LOGI("GPU rendering is not supported.");
148 return false;
149 #endif
150 }
151
ForceCPU(bool forceCPU)152 void SKImageChain::ForceCPU(bool forceCPU)
153 {
154 if (forceCPU_ == forceCPU) {
155 LOGI("Same result without change.");
156 return;
157 }
158 forceCPU_ = forceCPU;
159 if (canvas_ == nullptr) {
160 LOGI("The canvas_ is nullptr.");
161 return;
162 }
163 if (forceCPU) {
164 if (cpuSurface_ != nullptr) {
165 canvas_ = cpuSurface_->getCanvas();
166 } else {
167 canvas_ = nullptr;
168 }
169 } else {
170 if (gpuSurface_ != nullptr) {
171 canvas_ = gpuSurface_->getCanvas();
172 } else {
173 canvas_ = nullptr;
174 }
175 }
176 }
177
SetFilters(sk_sp<SkImageFilter> filter)178 void SKImageChain::SetFilters(sk_sp<SkImageFilter> filter)
179 {
180 if (filters_ == nullptr) {
181 filters_ = filter;
182 } else {
183 filters_ = SkImageFilters::Compose(filter, filters_);
184 }
185 }
186
SetClipRect(SkRect * rect)187 void SKImageChain::SetClipRect(SkRect* rect)
188 {
189 rect_ = rect;
190 }
191
SetClipPath(SkPath * path)192 void SKImageChain::SetClipPath(SkPath* path)
193 {
194 path_ = path;
195 }
196
SetClipRRect(SkRRect * rRect)197 void SKImageChain::SetClipRRect(SkRRect* rRect)
198 {
199 rRect_ = rRect;
200 }
201
GetPixelMap()202 std::shared_ptr<Media::PixelMap> SKImageChain::GetPixelMap()
203 {
204 return dstPixelMap_;
205 }
206
InitializeCanvas()207 bool SKImageChain::InitializeCanvas()
208 {
209 DrawError ret = InitWithoutCanvas();
210 if (ret != DrawError::ERR_OK) {
211 LOGE("Failed to init.");
212 return false;
213 }
214
215 if (forceCPU_) {
216 if (!CreateCPUCanvas()) {
217 LOGE("Failed to create canvas for CPU.");
218 return false;
219 }
220 } else {
221 if (!CreateGPUCanvas()) {
222 LOGE("Failed to create canvas for GPU.");
223 return false;
224 }
225 }
226 return canvas_ != nullptr;
227 }
228
CheckForErrors()229 DrawError SKImageChain::CheckForErrors()
230 {
231 if (canvas_ == nullptr) {
232 LOGE("Failed to create canvas");
233 return DrawError::ERR_CANVAS_NULL;
234 }
235 if (image_ == nullptr) {
236 LOGE("The image_ is nullptr, nothing to draw.");
237 return DrawError::ERR_IMAGE_NULL;
238 }
239 return DrawError::ERR_OK;
240 }
241
SetupPaint(SkPaint & paint)242 void SKImageChain::SetupPaint(SkPaint& paint)
243 {
244 paint.setAntiAlias(true);
245 paint.setBlendMode(SkBlendMode::kSrc);
246 paint.setImageFilter(filters_);
247 }
248
ApplyClipping()249 void SKImageChain::ApplyClipping()
250 {
251 if (rect_ != nullptr) {
252 canvas_->clipRect(*rect_, true);
253 } else if (path_ != nullptr) {
254 canvas_->clipPath(*path_, true);
255 } else if (rRect_ != nullptr) {
256 canvas_->clipRRect(*rRect_, true);
257 }
258 }
259
DrawImage(SkPaint & paint)260 bool SKImageChain::DrawImage(SkPaint& paint)
261 {
262 canvas_->save();
263 canvas_->resetMatrix();
264 #if defined(NEW_SKIA)
265 canvas_->drawImage(image_.get(), 0, 0, SkSamplingOptions(), &paint);
266 #else
267 canvas_->drawImage(image_.get(), 0, 0, &paint);
268 #endif
269 if (!forceCPU_ && dstPixmap_ != nullptr) {
270 if (!canvas_->readPixels(*dstPixmap_.get(), 0, 0)) {
271 LOGE("Failed to readPixels to target Pixmap.");
272 canvas_->restore();
273 return false;
274 }
275 }
276 canvas_->restore();
277 return true;
278 }
279
Draw()280 DrawError SKImageChain::Draw()
281 {
282 if (!InitializeCanvas()) {
283 return DrawError::ERR_CPU_CANVAS;
284 }
285
286 DrawError error = CheckForErrors();
287 if (error != DrawError::ERR_OK) {
288 return error;
289 }
290 #if (!defined(ANDROID_PLATFORM)) && (!defined(IOS_PLATFORM))
291 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "SKImageChain::Draw");
292 #endif
293 SkPaint paint;
294 SetupPaint(paint);
295 ApplyClipping();
296
297 if (!DrawImage(paint)) {
298 return DrawError::ERR_PIXEL_READ;
299 }
300 #if (!defined(ANDROID_PLATFORM)) && (!defined(IOS_PLATFORM))
301 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
302 #endif
303 return DrawError::ERR_OK;
304 }
305
PixelFormatConvert(const Media::PixelFormat & pixelFormat)306 SkColorType SKImageChain::PixelFormatConvert(const Media::PixelFormat& pixelFormat)
307 {
308 SkColorType colorType;
309 switch (pixelFormat) {
310 case Media::PixelFormat::BGRA_8888:
311 colorType = SkColorType::kBGRA_8888_SkColorType;
312 break;
313 case Media::PixelFormat::RGBA_8888:
314 colorType = SkColorType::kRGBA_8888_SkColorType;
315 break;
316 case Media::PixelFormat::RGB_565:
317 colorType = SkColorType::kRGB_565_SkColorType;
318 break;
319 case Media::PixelFormat::ALPHA_8:
320 colorType = SkColorType::kAlpha_8_SkColorType;
321 break;
322 default:
323 colorType = SkColorType::kUnknown_SkColorType;
324 break;
325 }
326 return colorType;
327 }
328 } // namespcae Rosen
329 } // namespace OHOS