• 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 #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