1 /*
2 * Copyright (c) 2022-2023 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 "platform/ohos/overdraw/rs_gpu_overdraw_canvas_listener.h"
17
18 #include "draw/blend_mode.h"
19 #include "draw/color.h"
20 #include "effect/color_matrix.h"
21 #include "image/bitmap.h"
22
23 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
24
25 namespace OHOS {
26 namespace Rosen {
RSGPUOverdrawCanvasListener(Drawing::Canvas & canvas)27 RSGPUOverdrawCanvasListener::RSGPUOverdrawCanvasListener(Drawing::Canvas& canvas)
28 : RSCanvasListener(canvas)
29 {
30 auto gpuContext = canvas.GetGPUContext();
31 if (gpuContext == nullptr) {
32 ROSEN_LOGE("RSGPUOverdrawCanvasListener, construction failed: need gpu canvas");
33 return;
34 }
35
36 Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_BGRA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
37 auto width = canvas.GetWidth();
38 auto height = canvas.GetHeight();
39 Drawing::Bitmap bitmap;
40 bitmap.Build(width, height, format);
41 Drawing::Image image;
42 image.BuildFromBitmap(*gpuContext, bitmap);
43
44 auto surface = std::make_shared<Drawing::Surface>();
45 surface->Bind(image);
46 listenedSurface_ = surface;
47 overdrawCanvas_ = std::make_shared<Drawing::OverDrawCanvas>(surface->GetCanvas());
48 }
49
~RSGPUOverdrawCanvasListener()50 RSGPUOverdrawCanvasListener::~RSGPUOverdrawCanvasListener()
51 {
52 }
53
Draw()54 void RSGPUOverdrawCanvasListener::Draw()
55 {
56 auto image = listenedSurface_->GetImageSnapshot();
57 if (image == nullptr) {
58 ROSEN_LOGE("image is nullptr");
59 return;
60 }
61 Drawing::Brush brush;
62 auto overdrawColors = RSOverdrawController::GetInstance().GetColorArray();
63 auto colorFilter = Drawing::ColorFilter::CreateOverDrawColorFilter(overdrawColors.data());
64 Drawing::Filter filter;
65 filter.SetColorFilter(colorFilter);
66 brush.SetFilter(filter);
67 canvas_.AttachBrush(brush);
68 canvas_.DrawImage(*image, 0, 0, Drawing::SamplingOptions());
69 canvas_.DetachBrush();
70 }
71
IsValid() const72 bool RSGPUOverdrawCanvasListener::IsValid() const
73 {
74 return listenedSurface_ != nullptr;
75 }
76
DrawPoint(const Drawing::Point & point)77 void RSGPUOverdrawCanvasListener::DrawPoint(const Drawing::Point& point)
78 {
79 DrawRect(Drawing::Rect(point.GetX(), point.GetY(), 1 + point.GetX(), 1 + point.GetY()));
80 }
81
DrawLine(const Drawing::Point & startPt,const Drawing::Point & endPt)82 void RSGPUOverdrawCanvasListener::DrawLine(const Drawing::Point& startPt, const Drawing::Point& endPt)
83 {
84 if (overdrawCanvas_ == nullptr) {
85 ROSEN_LOGE("overdrawCanvas_ is nullptr");
86 return;
87 }
88
89 Drawing::Path path;
90 path.MoveTo(startPt.GetX(), startPt.GetY());
91 path.LineTo(endPt.GetX(), endPt.GetY());
92 overdrawCanvas_->DrawPath(path);
93 }
94
DrawRect(const Drawing::Rect & rect)95 void RSGPUOverdrawCanvasListener::DrawRect(const Drawing::Rect& rect)
96 {
97 if (overdrawCanvas_ == nullptr) {
98 ROSEN_LOGE("overdrawCanvas_ is nullptr");
99 return;
100 }
101 overdrawCanvas_->DrawRect(rect);
102 }
103
DrawRoundRect(const Drawing::RoundRect & roundRect)104 void RSGPUOverdrawCanvasListener::DrawRoundRect(const Drawing::RoundRect& roundRect)
105 {
106 if (overdrawCanvas_ == nullptr) {
107 ROSEN_LOGE("overdrawCanvas_ is nullptr");
108 return;
109 }
110 overdrawCanvas_->DrawRoundRect(roundRect);
111 }
112
DrawNestedRoundRect(const Drawing::RoundRect & outer,const Drawing::RoundRect & inner)113 void RSGPUOverdrawCanvasListener::DrawNestedRoundRect(const Drawing::RoundRect& outer, const Drawing::RoundRect& inner)
114 {
115 if (overdrawCanvas_ == nullptr) {
116 ROSEN_LOGE("overdrawCanvas_ is nullptr");
117 return;
118 }
119 overdrawCanvas_->DrawNestedRoundRect(outer, inner);
120 }
121
DrawArc(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)122 void RSGPUOverdrawCanvasListener::DrawArc(
123 const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
124 {
125 if (overdrawCanvas_ == nullptr) {
126 ROSEN_LOGE("overdrawCanvas_ is nullptr");
127 return;
128 }
129 Drawing::Path path;
130 path.AddArc(oval, startAngle, sweepAngle);
131 overdrawCanvas_->DrawPath(path);
132 }
133
DrawPie(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)134 void RSGPUOverdrawCanvasListener::DrawPie(
135 const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
136 {
137 if (overdrawCanvas_ == nullptr) {
138 ROSEN_LOGE("overdrawCanvas_ is nullptr");
139 return;
140 }
141 Drawing::Path path;
142 path.AddArc(oval, startAngle, sweepAngle);
143 overdrawCanvas_->DrawPath(path);
144 }
145
DrawOval(const Drawing::Rect & oval)146 void RSGPUOverdrawCanvasListener::DrawOval(const Drawing::Rect& oval)
147 {
148 if (overdrawCanvas_ == nullptr) {
149 ROSEN_LOGE("overdrawCanvas_ is nullptr");
150 return;
151 }
152 Drawing::Path path;
153 path.AddOval(oval);
154 overdrawCanvas_->DrawPath(path);
155 }
156
DrawCircle(const Drawing::Point & centerPt,Drawing::scalar radius)157 void RSGPUOverdrawCanvasListener::DrawCircle(const Drawing::Point& centerPt, Drawing::scalar radius)
158 {
159 if (overdrawCanvas_ == nullptr) {
160 ROSEN_LOGE("overdrawCanvas_ is nullptr");
161 return;
162 }
163 Drawing::Path path;
164 path.AddCircle(centerPt.GetX(), centerPt.GetY(), radius);
165 overdrawCanvas_->DrawPath(path);
166 }
167
DrawPath(const Drawing::Path & path)168 void RSGPUOverdrawCanvasListener::DrawPath(const Drawing::Path& path)
169 {
170 if (overdrawCanvas_ == nullptr) {
171 ROSEN_LOGE("overdrawCanvas_ is nullptr");
172 return;
173 }
174 overdrawCanvas_->DrawPath(path);
175 }
176
DrawBackground(const Drawing::Brush & brush)177 void RSGPUOverdrawCanvasListener::DrawBackground(const Drawing::Brush& brush)
178 {
179 // need know canvas rect region
180 }
181
DrawShadow(const Drawing::Path & path,const Drawing::Point3 & planeParams,const Drawing::Point3 & devLightPos,Drawing::scalar lightRadius,Drawing::Color ambientColor,Drawing::Color spotColor,Drawing::ShadowFlags flag)182 void RSGPUOverdrawCanvasListener::DrawShadow(const Drawing::Path& path, const Drawing::Point3& planeParams,
183 const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, Drawing::Color ambientColor,
184 Drawing::Color spotColor, Drawing::ShadowFlags flag)
185 {
186 // need know shadow rect region
187 }
188
DrawShadowStyle(const Drawing::Path & path,const Drawing::Point3 & planeParams,const Drawing::Point3 & devLightPos,Drawing::scalar lightRadius,Drawing::Color ambientColor,Drawing::Color spotColor,Drawing::ShadowFlags flag,bool isLimitElevation)189 void RSGPUOverdrawCanvasListener::DrawShadowStyle(const Drawing::Path& path, const Drawing::Point3& planeParams,
190 const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, Drawing::Color ambientColor,
191 Drawing::Color spotColor, Drawing::ShadowFlags flag, bool isLimitElevation)
192 {
193 // need know shadow rect region
194 }
195
DrawRegion(const Drawing::Region & region)196 void RSGPUOverdrawCanvasListener::DrawRegion(const Drawing::Region& region)
197 {
198 // need know region path region
199 }
200
DrawBitmap(const Drawing::Bitmap & bitmap,const Drawing::scalar px,const Drawing::scalar py)201 void RSGPUOverdrawCanvasListener::DrawBitmap(
202 const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py)
203 {
204 if (overdrawCanvas_ == nullptr) {
205 ROSEN_LOGE("overdrawCanvas_ is nullptr");
206 return;
207 }
208 overdrawCanvas_->DrawRect(Drawing::Rect(px, py, bitmap.GetWidth() + px, bitmap.GetHeight() + py));
209 }
210
DrawImage(const Drawing::Image & image,const Drawing::scalar px,const Drawing::scalar py,const Drawing::SamplingOptions & sampling)211 void RSGPUOverdrawCanvasListener::DrawImage(const Drawing::Image& image, const Drawing::scalar px,
212 const Drawing::scalar py, const Drawing::SamplingOptions& sampling)
213 {
214 if (overdrawCanvas_ == nullptr) {
215 ROSEN_LOGE("overdrawCanvas_ is nullptr");
216 return;
217 }
218 overdrawCanvas_->DrawRect(Drawing::Rect(px, py, image.GetWidth() + px, image.GetHeight() + py));
219 }
220
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & src,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)221 void RSGPUOverdrawCanvasListener::DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src,
222 const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
223 {
224 if (overdrawCanvas_ == nullptr) {
225 ROSEN_LOGE("overdrawCanvas_ is nullptr");
226 return;
227 }
228 overdrawCanvas_->DrawRect(dst);
229 }
230
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling)231 void RSGPUOverdrawCanvasListener::DrawImageRect(
232 const Drawing::Image& image, const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling)
233 {
234 if (overdrawCanvas_ == nullptr) {
235 ROSEN_LOGE("overdrawCanvas_ is nullptr");
236 return;
237 }
238 overdrawCanvas_->DrawRect(dst);
239 }
240
DrawPicture(const Drawing::Picture & picture)241 void RSGPUOverdrawCanvasListener::DrawPicture(const Drawing::Picture& picture)
242 {
243 // need know picture rect region
244 }
245
Clear(Drawing::ColorQuad color)246 void RSGPUOverdrawCanvasListener::Clear(Drawing::ColorQuad color)
247 {
248 // need know canvas rect region
249 }
250
AttachPen(const Drawing::Pen & pen)251 void RSGPUOverdrawCanvasListener::AttachPen(const Drawing::Pen& pen)
252 {
253 if (overdrawCanvas_ == nullptr) {
254 ROSEN_LOGE("RSGPUOverdrawCanvasListener::AttachPen overdrawCanvas_ is nullptr");
255 return;
256 }
257 overdrawCanvas_->AttachPen(pen);
258 }
259
AttachBrush(const Drawing::Brush & brush)260 void RSGPUOverdrawCanvasListener::AttachBrush(const Drawing::Brush& brush)
261 {
262 if (overdrawCanvas_ == nullptr) {
263 ROSEN_LOGE("RSGPUOverdrawCanvasListener::AttachBrush overdrawCanvas_ is nullptr");
264 return;
265 }
266 overdrawCanvas_->AttachBrush(brush);
267 }
268
DetachPen()269 void RSGPUOverdrawCanvasListener::DetachPen()
270 {
271 if (overdrawCanvas_ == nullptr) {
272 ROSEN_LOGE("RSGPUOverdrawCanvasListener::DetachPen overdrawCanvas_ is nullptr");
273 return;
274 }
275 overdrawCanvas_->DetachPen();
276 }
277
DetachBrush()278 void RSGPUOverdrawCanvasListener::DetachBrush()
279 {
280 if (overdrawCanvas_ == nullptr) {
281 ROSEN_LOGE("RSGPUOverdrawCanvasListener::DetachBrush overdrawCanvas_ is nullptr");
282 return;
283 }
284 overdrawCanvas_->DetachBrush();
285 }
286
287 } // namespace Rosen
288 } // namespace OHOS
289