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