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 #ifndef USE_ROSEN_DRAWING
19 #include <include/core/SkDrawable.h>
20 #include <include/core/SkOverdrawCanvas.h>
21 #include <include/core/SkPath.h>
22 #include <include/core/SkPicture.h>
23 #include <include/core/SkRegion.h>
24 #include <include/core/SkTextBlob.h>
25 #include <include/effects/SkOverdrawColorFilter.h>
26 #else
27 #include "draw/blend_mode.h"
28 #include "draw/color.h"
29 #include "effect/color_matrix.h"
30 #include "image/bitmap.h"
31 #endif
32
33 #include "platform/ohos/overdraw/rs_overdraw_controller.h"
34
35 namespace OHOS {
36 namespace Rosen {
37 #ifndef USE_ROSEN_DRAWING
RSGPUOverdrawCanvasListener(SkCanvas & canvas)38 RSGPUOverdrawCanvasListener::RSGPUOverdrawCanvasListener(SkCanvas &canvas)
39 : RSCanvasListener(canvas)
40 {
41 listenedSurface_ = canvas.makeSurface(canvas.imageInfo());
42 if (listenedSurface_ != nullptr) {
43 overdrawCanvas_ = new SkOverdrawCanvas(listenedSurface_->getCanvas());
44 }
45 }
46 #else
47 RSGPUOverdrawCanvasListener::RSGPUOverdrawCanvasListener(Drawing::Canvas& canvas)
48 : RSCanvasListener(canvas)
49 {
50 auto gpuContext = canvas.GetGPUContext();
51 if (gpuContext == nullptr) {
52 ROSEN_LOGE("RSGPUOverdrawCanvasListener, construction failed: need gpu canvas");
53 return;
54 }
55
56 Drawing::BitmapFormat format = { Drawing::ColorType::COLORTYPE_BGRA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL };
57 auto width = canvas.GetWidth();
58 auto height = canvas.GetHeight();
59 Drawing::Bitmap bitmap;
60 bitmap.Build(width, height, format);
61 Drawing::Image image;
62 image.BuildFromBitmap(*gpuContext, bitmap);
63
64 auto surface = std::make_shared<Drawing::Surface>();
65 surface->Bind(image);
66 listenedSurface_ = surface;
67 overdrawCanvas_ = surface->GetCanvas();
68 }
69 #endif
70
~RSGPUOverdrawCanvasListener()71 RSGPUOverdrawCanvasListener::~RSGPUOverdrawCanvasListener()
72 {
73 #ifndef USE_ROSEN_DRAWING
74 if (overdrawCanvas_ != nullptr) {
75 delete overdrawCanvas_;
76 }
77 #endif
78 }
79
Draw()80 void RSGPUOverdrawCanvasListener::Draw()
81 {
82 #ifndef USE_ROSEN_DRAWING
83 auto image = listenedSurface_->makeImageSnapshot();
84 SkPaint paint;
85 auto overdrawColors = RSOverdrawController::GetInstance().GetColorArray();
86 #ifdef NEW_SKIA
87 paint.setColorFilter(SkOverdrawColorFilter::MakeWithSkColors(overdrawColors.data()));
88 canvas_.drawImage(image, 0, 0, SkSamplingOptions(), &paint);
89 #else
90 paint.setColorFilter(SkOverdrawColorFilter::Make(overdrawColors.data()));
91 canvas_.drawImage(image, 0, 0, &paint);
92 #endif
93 #else
94 auto image = listenedSurface_->GetImageSnapshot();
95 if (image == nullptr) {
96 ROSEN_LOGE("image is nullptr");
97 return;
98 }
99 Drawing::Brush brush;
100 canvas_.AttachBrush(brush);
101 canvas_.DrawImage(*image, 0, 0, Drawing::SamplingOptions());
102 canvas_.DetachBrush();
103 #endif
104 }
105
IsValid() const106 bool RSGPUOverdrawCanvasListener::IsValid() const
107 {
108 return listenedSurface_ != nullptr;
109 }
110
111 #ifndef USE_ROSEN_DRAWING
onDrawRect(const SkRect & rect,const SkPaint & paint)112 void RSGPUOverdrawCanvasListener::onDrawRect(const SkRect& rect, const SkPaint& paint)
113 {
114 if (overdrawCanvas_ == nullptr) {
115 ROSEN_LOGE("overdrawCanvas_ is nullptr");
116 return;
117 }
118 overdrawCanvas_->drawRect(rect, paint);
119 }
120
onDrawRRect(const SkRRect & rect,const SkPaint & paint)121 void RSGPUOverdrawCanvasListener::onDrawRRect(const SkRRect& rect, const SkPaint& paint)
122 {
123 if (overdrawCanvas_ == nullptr) {
124 ROSEN_LOGE("overdrawCanvas_ is nullptr");
125 return;
126 }
127 overdrawCanvas_->drawRRect(rect, paint);
128 }
129
onDrawDRRect(const SkRRect & outer,const SkRRect & inner,const SkPaint & paint)130 void RSGPUOverdrawCanvasListener::onDrawDRRect(const SkRRect& outer, const SkRRect& inner,
131 const SkPaint& paint)
132 {
133 if (overdrawCanvas_ == nullptr) {
134 ROSEN_LOGE("overdrawCanvas_ is nullptr");
135 return;
136 }
137 overdrawCanvas_->drawDRRect(outer, inner, paint);
138 }
139
onDrawOval(const SkRect & rect,const SkPaint & paint)140 void RSGPUOverdrawCanvasListener::onDrawOval(const SkRect& rect, const SkPaint& paint)
141 {
142 if (overdrawCanvas_ == nullptr) {
143 ROSEN_LOGE("overdrawCanvas_ is nullptr");
144 return;
145 }
146 overdrawCanvas_->drawOval(rect, paint);
147 }
148
onDrawArc(const SkRect & rect,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)149 void RSGPUOverdrawCanvasListener::onDrawArc(const SkRect& rect, SkScalar startAngle,
150 SkScalar sweepAngle, bool useCenter,
151 const SkPaint& paint)
152 {
153 if (overdrawCanvas_ == nullptr) {
154 ROSEN_LOGE("overdrawCanvas_ is nullptr");
155 return;
156 }
157 overdrawCanvas_->drawArc(rect, startAngle, sweepAngle, useCenter, paint);
158 }
159
onDrawPath(const SkPath & path,const SkPaint & paint)160 void RSGPUOverdrawCanvasListener::onDrawPath(const SkPath& path, const SkPaint& paint)
161 {
162 if (overdrawCanvas_ == nullptr) {
163 ROSEN_LOGE("overdrawCanvas_ is nullptr");
164 return;
165 }
166 overdrawCanvas_->drawPath(path, paint);
167 }
168
onDrawRegion(const SkRegion & region,const SkPaint & paint)169 void RSGPUOverdrawCanvasListener::onDrawRegion(const SkRegion& region, const SkPaint& paint)
170 {
171 if (overdrawCanvas_ == nullptr) {
172 ROSEN_LOGE("overdrawCanvas_ is nullptr");
173 return;
174 }
175 overdrawCanvas_->drawRegion(region, paint);
176 }
177
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)178 void RSGPUOverdrawCanvasListener::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
179 const SkPaint& paint)
180 {
181 if (overdrawCanvas_ == nullptr) {
182 ROSEN_LOGE("overdrawCanvas_ is nullptr");
183 return;
184 }
185 overdrawCanvas_->drawTextBlob(blob, x, y, paint);
186 }
187
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode mode,const SkPaint & paint)188 void RSGPUOverdrawCanvasListener::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
189 const SkPoint texCoords[4], SkBlendMode mode,
190 const SkPaint& paint)
191 {
192 if (overdrawCanvas_ == nullptr) {
193 ROSEN_LOGE("overdrawCanvas_ is nullptr");
194 return;
195 }
196 overdrawCanvas_->drawPatch(cubics, colors, texCoords, mode, paint);
197 }
198
onDrawPoints(SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)199 void RSGPUOverdrawCanvasListener::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[],
200 const SkPaint& paint)
201 {
202 if (overdrawCanvas_ == nullptr) {
203 ROSEN_LOGE("overdrawCanvas_ is nullptr");
204 return;
205 }
206 overdrawCanvas_->drawPoints(mode, count, pts, paint);
207 }
208
onDrawEdgeAAQuad(const SkRect & rect,const SkPoint clip[4],SkCanvas::QuadAAFlags aaFlags,const SkColor4f & color,SkBlendMode mode)209 void RSGPUOverdrawCanvasListener::onDrawEdgeAAQuad(const SkRect& rect, const SkPoint clip[4],
210 SkCanvas::QuadAAFlags aaFlags,
211 const SkColor4f& color, SkBlendMode mode)
212 {
213 if (overdrawCanvas_ == nullptr) {
214 ROSEN_LOGE("overdrawCanvas_ is nullptr");
215 return;
216 }
217 overdrawCanvas_->experimental_DrawEdgeAAQuad(rect, clip, aaFlags, color.toSkColor(), mode);
218 }
219
onDrawAnnotation(const SkRect & rect,const char key[],SkData * value)220 void RSGPUOverdrawCanvasListener::onDrawAnnotation(const SkRect& rect, const char key[], SkData* value)
221 {
222 if (overdrawCanvas_ == nullptr) {
223 ROSEN_LOGE("overdrawCanvas_ is nullptr");
224 return;
225 }
226 overdrawCanvas_->drawAnnotation(rect, key, value);
227 }
228
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rect)229 void RSGPUOverdrawCanvasListener::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rect)
230 {
231 if (overdrawCanvas_ == nullptr) {
232 ROSEN_LOGE("overdrawCanvas_ is nullptr");
233 return;
234 }
235 overdrawCanvas_->private_draw_shadow_rec(path, rect);
236 }
237
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)238 void RSGPUOverdrawCanvasListener::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
239 {
240 if (overdrawCanvas_ == nullptr) {
241 ROSEN_LOGE("overdrawCanvas_ is nullptr");
242 return;
243 }
244 overdrawCanvas_->drawDrawable(drawable, matrix);
245 }
246
onDrawPicture(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)247 void RSGPUOverdrawCanvasListener::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix,
248 const SkPaint* paint)
249 {
250 if (overdrawCanvas_ == nullptr) {
251 ROSEN_LOGE("overdrawCanvas_ is nullptr");
252 return;
253 }
254 overdrawCanvas_->drawPicture(picture, matrix, paint);
255 }
256
257 #else
DrawPoint(const Drawing::Point & point)258 void RSGPUOverdrawCanvasListener::DrawPoint(const Drawing::Point& point)
259 {
260 DrawRect(Drawing::Rect(point.GetX(), point.GetY(), 1 + point.GetX(), 1 + point.GetY()));
261 }
262
DrawLine(const Drawing::Point & startPt,const Drawing::Point & endPt)263 void RSGPUOverdrawCanvasListener::DrawLine(const Drawing::Point& startPt, const Drawing::Point& endPt)
264 {
265 if (overdrawCanvas_ == nullptr) {
266 ROSEN_LOGE("overdrawCanvas_ is nullptr");
267 return;
268 }
269
270 Drawing::Path path;
271 path.MoveTo(startPt.GetX(), startPt.GetY());
272 path.LineTo(endPt.GetX(), endPt.GetY());
273 overdrawCanvas_->DrawPath(path);
274 }
275
DrawRect(const Drawing::Rect & rect)276 void RSGPUOverdrawCanvasListener::DrawRect(const Drawing::Rect& rect)
277 {
278 if (overdrawCanvas_ == nullptr) {
279 ROSEN_LOGE("overdrawCanvas_ is nullptr");
280 return;
281 }
282 overdrawCanvas_->DrawRect(rect);
283 }
284
DrawRoundRect(const Drawing::RoundRect & roundRect)285 void RSGPUOverdrawCanvasListener::DrawRoundRect(const Drawing::RoundRect& roundRect)
286 {
287 if (overdrawCanvas_ == nullptr) {
288 ROSEN_LOGE("overdrawCanvas_ is nullptr");
289 return;
290 }
291 overdrawCanvas_->DrawRoundRect(roundRect);
292 }
293
DrawNestedRoundRect(const Drawing::RoundRect & outer,const Drawing::RoundRect & inner)294 void RSGPUOverdrawCanvasListener::DrawNestedRoundRect(const Drawing::RoundRect& outer, const Drawing::RoundRect& inner)
295 {
296 if (overdrawCanvas_ == nullptr) {
297 ROSEN_LOGE("overdrawCanvas_ is nullptr");
298 return;
299 }
300 overdrawCanvas_->DrawNestedRoundRect(outer, inner);
301 }
302
DrawArc(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)303 void RSGPUOverdrawCanvasListener::DrawArc(
304 const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
305 {
306 if (overdrawCanvas_ == nullptr) {
307 ROSEN_LOGE("overdrawCanvas_ is nullptr");
308 return;
309 }
310 Drawing::Path path;
311 path.AddArc(oval, startAngle, sweepAngle);
312 overdrawCanvas_->DrawPath(path);
313 }
314
DrawPie(const Drawing::Rect & oval,Drawing::scalar startAngle,Drawing::scalar sweepAngle)315 void RSGPUOverdrawCanvasListener::DrawPie(
316 const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle)
317 {
318 if (overdrawCanvas_ == nullptr) {
319 ROSEN_LOGE("overdrawCanvas_ is nullptr");
320 return;
321 }
322 Drawing::Path path;
323 path.AddArc(oval, startAngle, sweepAngle);
324 overdrawCanvas_->DrawPath(path);
325 }
326
DrawOval(const Drawing::Rect & oval)327 void RSGPUOverdrawCanvasListener::DrawOval(const Drawing::Rect& oval)
328 {
329 if (overdrawCanvas_ == nullptr) {
330 ROSEN_LOGE("overdrawCanvas_ is nullptr");
331 return;
332 }
333 Drawing::Path path;
334 path.AddOval(oval);
335 overdrawCanvas_->DrawPath(path);
336 }
337
DrawCircle(const Drawing::Point & centerPt,Drawing::scalar radius)338 void RSGPUOverdrawCanvasListener::DrawCircle(const Drawing::Point& centerPt, Drawing::scalar radius)
339 {
340 if (overdrawCanvas_ == nullptr) {
341 ROSEN_LOGE("overdrawCanvas_ is nullptr");
342 return;
343 }
344 Drawing::Path path;
345 path.AddCircle(centerPt.GetX(), centerPt.GetY(), radius);
346 overdrawCanvas_->DrawPath(path);
347 }
348
DrawPath(const Drawing::Path & path)349 void RSGPUOverdrawCanvasListener::DrawPath(const Drawing::Path& path)
350 {
351 if (overdrawCanvas_ == nullptr) {
352 ROSEN_LOGE("overdrawCanvas_ is nullptr");
353 return;
354 }
355 overdrawCanvas_->DrawPath(path);
356 }
357
DrawBackground(const Drawing::Brush & brush)358 void RSGPUOverdrawCanvasListener::DrawBackground(const Drawing::Brush& brush)
359 {
360 // need know canvas rect region
361 }
362
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)363 void RSGPUOverdrawCanvasListener::DrawShadow(const Drawing::Path& path, const Drawing::Point3& planeParams,
364 const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, Drawing::Color ambientColor,
365 Drawing::Color spotColor, Drawing::ShadowFlags flag)
366 {
367 // need know shadow rect region
368 }
369
DrawRegion(const Drawing::Region & region)370 void RSGPUOverdrawCanvasListener::DrawRegion(const Drawing::Region& region)
371 {
372 // need know region path region
373 }
374
DrawBitmap(const Drawing::Bitmap & bitmap,const Drawing::scalar px,const Drawing::scalar py)375 void RSGPUOverdrawCanvasListener::DrawBitmap(
376 const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py)
377 {
378 if (overdrawCanvas_ == nullptr) {
379 ROSEN_LOGE("overdrawCanvas_ is nullptr");
380 return;
381 }
382 overdrawCanvas_->DrawRect(Drawing::Rect(px, py, bitmap.GetWidth() + px, bitmap.GetHeight() + py));
383 }
384
DrawBitmap(OHOS::Media::PixelMap & pixelMap,const Drawing::scalar px,const Drawing::scalar py)385 void RSGPUOverdrawCanvasListener::DrawBitmap(
386 OHOS::Media::PixelMap& pixelMap, const Drawing::scalar px, const Drawing::scalar py)
387 {
388 // need know pixelMap region
389 }
390
DrawImage(const Drawing::Image & image,const Drawing::scalar px,const Drawing::scalar py,const Drawing::SamplingOptions & sampling)391 void RSGPUOverdrawCanvasListener::DrawImage(const Drawing::Image& image, const Drawing::scalar px,
392 const Drawing::scalar py, const Drawing::SamplingOptions& sampling)
393 {
394 if (overdrawCanvas_ == nullptr) {
395 ROSEN_LOGE("overdrawCanvas_ is nullptr");
396 return;
397 }
398 overdrawCanvas_->DrawRect(Drawing::Rect(px, py, image.GetWidth() + px, image.GetHeight() + py));
399 }
400
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & src,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)401 void RSGPUOverdrawCanvasListener::DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src,
402 const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint)
403 {
404 if (overdrawCanvas_ == nullptr) {
405 ROSEN_LOGE("overdrawCanvas_ is nullptr");
406 return;
407 }
408 overdrawCanvas_->DrawRect(dst);
409 }
410
DrawImageRect(const Drawing::Image & image,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling)411 void RSGPUOverdrawCanvasListener::DrawImageRect(
412 const Drawing::Image& image, const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling)
413 {
414 if (overdrawCanvas_ == nullptr) {
415 ROSEN_LOGE("overdrawCanvas_ is nullptr");
416 return;
417 }
418 overdrawCanvas_->DrawRect(dst);
419 }
420
DrawPicture(const Drawing::Picture & picture)421 void RSGPUOverdrawCanvasListener::DrawPicture(const Drawing::Picture& picture)
422 {
423 // need know picture rect region
424 }
425
Clear(Drawing::ColorQuad color)426 void RSGPUOverdrawCanvasListener::Clear(Drawing::ColorQuad color)
427 {
428 // need know canvas rect region
429 }
430
431 static constexpr Drawing::scalar overdrawColorMatix[Drawing::ColorMatrix::MATRIX_SIZE] = {
432 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
433 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
434 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
435 0.0f, 0.0f, 0.0f, 0.0f, 1.0f/255,
436 };
437
AttachPen(const Drawing::Pen & pen)438 void RSGPUOverdrawCanvasListener::AttachPen(const Drawing::Pen& pen)
439 {
440 if (overdrawPen_ == nullptr) {
441 overdrawPen_ = std::make_shared<Drawing::Pen>();
442
443 Drawing::ColorMatrix cm;
444 cm.SetArray(overdrawColorMatix);
445
446 Drawing::Filter filter;
447 filter.SetColorFilter(Drawing::ColorFilter::CreateMatrixColorFilter(cm));
448 overdrawPen_->SetFilter(filter);
449 overdrawPen_->SetBlendMode(Drawing::BlendMode::PLUS);
450 }
451 if (overdrawCanvas_ == nullptr) {
452 ROSEN_LOGE("RSGPUOverdrawCanvasListener::AttachPen overdrawCanvas_ is nullptr");
453 return;
454 }
455 overdrawCanvas_->AttachPen(*overdrawPen_);
456 }
457
AttachBrush(const Drawing::Brush & brush)458 void RSGPUOverdrawCanvasListener::AttachBrush(const Drawing::Brush& brush)
459 {
460 if (overdrawBrush_ == nullptr) {
461 overdrawBrush_ = std::make_shared<Drawing::Brush>();
462
463 Drawing::ColorMatrix cm;
464 cm.SetArray(overdrawColorMatix);
465
466 Drawing::Filter filter;
467 filter.SetColorFilter(Drawing::ColorFilter::CreateMatrixColorFilter(cm));
468 overdrawBrush_->SetFilter(filter);
469 overdrawBrush_->SetBlendMode(Drawing::BlendMode::PLUS);
470 }
471 if (overdrawCanvas_ == nullptr) {
472 ROSEN_LOGE("RSGPUOverdrawCanvasListener::AttachBrush overdrawCanvas_ is nullptr");
473 return;
474 }
475 overdrawCanvas_->AttachBrush(*overdrawBrush_);
476 }
477
DetachPen()478 void RSGPUOverdrawCanvasListener::DetachPen()
479 {
480 if (overdrawCanvas_ == nullptr) {
481 ROSEN_LOGE("RSGPUOverdrawCanvasListener::DetachPen overdrawCanvas_ is nullptr");
482 return;
483 }
484 overdrawCanvas_->DetachPen();
485 }
486
DetachBrush()487 void RSGPUOverdrawCanvasListener::DetachBrush()
488 {
489 if (overdrawCanvas_ == nullptr) {
490 ROSEN_LOGE("RSGPUOverdrawCanvasListener::DetachBrush overdrawCanvas_ is nullptr");
491 return;
492 }
493 overdrawCanvas_->DetachBrush();
494 }
495
496 #endif // USE_ROSEN_DRAWING
497 } // namespace Rosen
498 } // namespace OHOS
499