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