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 #include "egl_manager.h"
17 #include "include/gpu/GrContext.h"
18 #include "include/gpu/gl/GrGLInterface.h"
19 #include "rs_trace.h"
20 #include "sk_image_chain.h"
21
22 namespace OHOS {
23 namespace Rosen {
SKImageChain(SkCanvas * canvas,sk_sp<SkImage> image)24 SKImageChain::SKImageChain(SkCanvas* canvas, sk_sp<SkImage> image) : canvas_(canvas), image_(image)
25 {}
26
SKImageChain(std::shared_ptr<Media::PixelMap> srcPixelMap)27 SKImageChain::SKImageChain(std::shared_ptr<Media::PixelMap> srcPixelMap) : srcPixelMap_(srcPixelMap)
28 {}
29
InitWithoutCanvas()30 void SKImageChain::InitWithoutCanvas()
31 {
32 if (srcPixelMap_ == nullptr) {
33 LOGE("The srcPixelMap_ is nullptr.");
34 return;
35 }
36 imageInfo_ = SkImageInfo::Make(srcPixelMap_->GetWidth(), srcPixelMap_->GetHeight(),
37 PixelFormatConvert(srcPixelMap_->GetPixelFormat()), static_cast<SkAlphaType>(srcPixelMap_->GetAlphaType()));
38 SkPixmap srcPixmap(imageInfo_, srcPixelMap_->GetPixels(), srcPixelMap_->GetRowBytes());
39 SkBitmap srcBitmap;
40 srcBitmap.installPixels(srcPixmap);
41 image_ = SkImage::MakeFromBitmap(srcBitmap);
42 Media::InitializationOptions opts;
43 opts.size.width = srcPixelMap_->GetWidth();
44 opts.size.height = srcPixelMap_->GetHeight();
45 opts.editable = true;
46 auto dstPixelMap = Media::PixelMap::Create(opts);
47 if (dstPixelMap != nullptr) {
48 dstPixmap_ = std::make_shared<SkPixmap>(imageInfo_, dstPixelMap->GetPixels(), dstPixelMap->GetRowBytes());
49 dstPixelMap_ = std::shared_ptr<Media::PixelMap>(dstPixelMap.release());
50 }
51 }
52
CreateCPUCanvas()53 bool SKImageChain::CreateCPUCanvas()
54 {
55 if (dstPixmap_ == nullptr) {
56 LOGE("The dstPixmap_ is nullptr.");
57 return false;
58 }
59 cpuSurface_ = SkSurface::MakeRasterDirect(imageInfo_, const_cast<void*>(dstPixmap_->addr()),
60 dstPixelMap_->GetRowBytes());
61 if (!cpuSurface_) {
62 LOGE("Failed to create surface for CPU.");
63 return false;
64 }
65 canvas_ = cpuSurface_->getCanvas();
66 return true;
67 }
68
CreateGPUCanvas()69 bool SKImageChain::CreateGPUCanvas()
70 {
71 #ifdef ACE_ENABLE_GL
72 EglManager::GetInstance().Init();
73 sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
74 sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface)));
75 gpuSurface_ = SkSurface::MakeRenderTarget(grContext.get(), SkBudgeted::kNo, imageInfo_);
76 if (!gpuSurface_) {
77 LOGE("Failed to create surface for GPU.");
78 return false;
79 }
80 canvas_ = gpuSurface_->getCanvas();
81 return true;
82 #else
83 LOGI("GPU rendering is not supported.");
84 return false;
85 #endif
86 }
87
ForceCPU(bool forceCPU)88 void SKImageChain::ForceCPU(bool forceCPU)
89 {
90 if (forceCPU_ == forceCPU) {
91 LOGI("Same result without change.");
92 return;
93 }
94 forceCPU_ = forceCPU;
95 if (canvas_ == nullptr) {
96 LOGI("The canvas_ is nullptr.");
97 return;
98 }
99 if (forceCPU) {
100 if (cpuSurface_ != nullptr) {
101 canvas_ = cpuSurface_->getCanvas();
102 } else {
103 canvas_ = nullptr;
104 }
105 } else {
106 if (gpuSurface_ != nullptr) {
107 canvas_ = gpuSurface_->getCanvas();
108 } else {
109 canvas_ = nullptr;
110 }
111 }
112 }
113
SetFilters(sk_sp<SkImageFilter> filter)114 void SKImageChain::SetFilters(sk_sp<SkImageFilter> filter)
115 {
116 if (filters_ == nullptr) {
117 filters_ = filter;
118 } else {
119 filters_ = SkImageFilters::Compose(filter, filters_);
120 }
121 }
122
SetClipRect(SkRect * rect)123 void SKImageChain::SetClipRect(SkRect* rect)
124 {
125 rect_ = rect;
126 }
127
SetClipPath(SkPath * path)128 void SKImageChain::SetClipPath(SkPath* path)
129 {
130 path_ = path;
131 }
132
SetClipRRect(SkRRect * rRect)133 void SKImageChain::SetClipRRect(SkRRect* rRect)
134 {
135 rRect_ = rRect;
136 }
137
GetPixelMap()138 std::shared_ptr<Media::PixelMap> SKImageChain::GetPixelMap()
139 {
140 return dstPixelMap_;
141 }
142
Draw()143 void SKImageChain::Draw()
144 {
145 if (canvas_ == nullptr) {
146 InitWithoutCanvas();
147 if (forceCPU_) {
148 if (!CreateCPUCanvas()) {
149 LOGE("Failed to create canvas for CPU.");
150 return;
151 }
152 } else {
153 if (!CreateGPUCanvas()) {
154 LOGE("Failed to create canvas for GPU.");
155 return;
156 }
157 }
158 }
159 if (image_ == nullptr) {
160 LOGE("The image_ is nullptr, nothing to draw.");
161 return;
162 }
163 ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "SKImageChain::Draw");
164 SkPaint paint;
165 paint.setAntiAlias(true);
166 paint.setBlendMode(SkBlendMode::kSrc);
167 paint.setImageFilter(filters_);
168 if (rect_ != nullptr) {
169 canvas_->clipRect(*rect_, true);
170 } else if (path_ != nullptr) {
171 canvas_->clipPath(*path_, true);
172 } else if (rRect_ != nullptr) {
173 canvas_->clipRRect(*rRect_, true);
174 }
175 canvas_->save();
176 canvas_->resetMatrix();
177 canvas_->drawImage(image_.get(), 0, 0, &paint);
178 if (!forceCPU_ && dstPixmap_ != nullptr) {
179 if (!canvas_->readPixels(*dstPixmap_.get(), 0, 0)) {
180 LOGE("Failed to readPixels to target Pixmap.");
181 }
182 }
183 canvas_->restore();
184 ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
185 }
186
PixelFormatConvert(const Media::PixelFormat & pixelFormat)187 SkColorType SKImageChain::PixelFormatConvert(const Media::PixelFormat& pixelFormat)
188 {
189 SkColorType colorType;
190 switch (pixelFormat) {
191 case Media::PixelFormat::BGRA_8888:
192 colorType = SkColorType::kBGRA_8888_SkColorType;
193 break;
194 case Media::PixelFormat::RGBA_8888:
195 colorType = SkColorType::kRGBA_8888_SkColorType;
196 break;
197 case Media::PixelFormat::RGB_565:
198 colorType = SkColorType::kRGB_565_SkColorType;
199 break;
200 case Media::PixelFormat::ALPHA_8:
201 colorType = SkColorType::kAlpha_8_SkColorType;
202 break;
203 default:
204 colorType = SkColorType::kUnknown_SkColorType;
205 break;
206 }
207 return colorType;
208 }
209 } // namespcae Rosen
210 } // namespace OHOS