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