• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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