• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 "pipeline/rs_paint_filter_canvas.h"
17 
18 #include <algorithm>
19 
20 #include "draw/canvas.h"
21 
22 #include "platform/common/rs_log.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 
27 using namespace Drawing;
28 
RSPaintFilterCanvasBase(Drawing::Canvas * canvas)29 RSPaintFilterCanvasBase::RSPaintFilterCanvasBase(Drawing::Canvas* canvas)
30     : Canvas(canvas ? canvas->GetWidth() : 0, canvas ? canvas->GetHeight() : 0), canvas_(canvas)
31 {
32 #ifdef SKP_RECORDING_ENABLED
33     this->AddCanvas(canvas);
34 #endif
35 }
36 
GetTotalMatrix() const37 Drawing::Matrix RSPaintFilterCanvasBase::GetTotalMatrix() const
38 {
39     return canvas_->GetTotalMatrix();
40 }
41 
GetLocalClipBounds() const42 Drawing::Rect RSPaintFilterCanvasBase::GetLocalClipBounds() const
43 {
44     return canvas_->GetLocalClipBounds();
45 }
46 
GetDeviceClipBounds() const47 Drawing::RectI RSPaintFilterCanvasBase::GetDeviceClipBounds() const
48 {
49     return canvas_->GetDeviceClipBounds();
50 }
51 
GetRoundInDeviceClipBounds() const52 Drawing::RectI RSPaintFilterCanvasBase::GetRoundInDeviceClipBounds() const
53 {
54     return canvas_->GetRoundInDeviceClipBounds();
55 }
56 
GetSaveCount() const57 uint32_t RSPaintFilterCanvasBase::GetSaveCount() const
58 {
59     return canvas_->GetSaveCount();
60 }
61 
62 #ifdef RS_ENABLE_GPU
GetGPUContext()63 std::shared_ptr<Drawing::GPUContext> RSPaintFilterCanvasBase::GetGPUContext()
64 {
65     return canvas_ != nullptr ? canvas_->GetGPUContext() : nullptr;
66 }
67 #endif
68 
DrawPoint(const Point & point)69 void RSPaintFilterCanvasBase::DrawPoint(const Point& point)
70 {
71 #ifdef SKP_RECORDING_ENABLED
72     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
73         if ((*iter) != nullptr && OnFilter()) {
74             (*iter)->DrawPoint(point);
75         }
76     }
77 #else
78     if (canvas_ != nullptr && OnFilter()) {
79         canvas_->DrawPoint(point);
80     }
81 #endif
82 }
83 
DrawSdf(const SDFShapeBase & shape)84 void RSPaintFilterCanvasBase::DrawSdf(const SDFShapeBase& shape)
85 {
86 #ifdef SKP_RECORDING_ENABLED
87     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
88         if ((*iter) != nullptr && OnFilter()) {
89             (*iter)->DrawSdf(shape);
90         }
91     }
92 #else
93     if (canvas_ != nullptr && OnFilter()) {
94         canvas_->DrawSdf(shape);
95     }
96 #endif
97 }
98 
DrawPoints(PointMode mode,size_t count,const Point pts[])99 void RSPaintFilterCanvasBase::DrawPoints(PointMode mode, size_t count, const Point pts[])
100 {
101 #ifdef SKP_RECORDING_ENABLED
102     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
103         if ((*iter) != nullptr && OnFilter()) {
104             (*iter)->DrawPoints(mode, count, pts);
105         }
106     }
107 #else
108     if (canvas_ != nullptr && OnFilter()) {
109         canvas_->DrawPoints(mode, count, pts);
110     }
111 #endif
112 }
113 
DrawLine(const Point & startPt,const Point & endPt)114 void RSPaintFilterCanvasBase::DrawLine(const Point& startPt, const Point& endPt)
115 {
116 #ifdef SKP_RECORDING_ENABLED
117     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
118         if ((*iter) != nullptr && OnFilter()) {
119             (*iter)->DrawLine(startPt, endPt);
120         }
121     }
122 #else
123     if (canvas_ != nullptr && OnFilter()) {
124         canvas_->DrawLine(startPt, endPt);
125     }
126 #endif
127 }
128 
DrawRect(const Rect & rect)129 void RSPaintFilterCanvasBase::DrawRect(const Rect& rect)
130 {
131 #ifdef SKP_RECORDING_ENABLED
132     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
133         if ((*iter) != nullptr && OnFilter()) {
134             (*iter)->DrawRect(rect);
135         }
136     }
137 #else
138     if (canvas_ != nullptr && OnFilter()) {
139         canvas_->DrawRect(rect);
140     }
141 #endif
142 }
143 
DrawRoundRect(const RoundRect & roundRect)144 void RSPaintFilterCanvasBase::DrawRoundRect(const RoundRect& roundRect)
145 {
146 #ifdef SKP_RECORDING_ENABLED
147     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
148         if ((*iter) != nullptr && OnFilter()) {
149             (*iter)->DrawRoundRect(roundRect);
150         }
151     }
152 #else
153     if (canvas_ != nullptr && OnFilter()) {
154         canvas_->DrawRoundRect(roundRect);
155     }
156 #endif
157 }
158 
DrawNestedRoundRect(const RoundRect & outer,const RoundRect & inner)159 void RSPaintFilterCanvasBase::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner)
160 {
161 #ifdef SKP_RECORDING_ENABLED
162     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
163         if ((*iter) != nullptr && OnFilter()) {
164             (*iter)->DrawNestedRoundRect(outer, inner);
165         }
166     }
167 #else
168     if (canvas_ != nullptr && OnFilter()) {
169         canvas_->DrawNestedRoundRect(outer, inner);
170     }
171 #endif
172 }
173 
DrawArc(const Rect & oval,scalar startAngle,scalar sweepAngle)174 void RSPaintFilterCanvasBase::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle)
175 {
176 #ifdef SKP_RECORDING_ENABLED
177     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
178         if ((*iter) != nullptr && OnFilter()) {
179             (*iter)->DrawArc(oval, startAngle, sweepAngle);
180         }
181     }
182 #else
183     if (canvas_ != nullptr && OnFilter()) {
184         canvas_->DrawArc(oval, startAngle, sweepAngle);
185     }
186 #endif
187 }
188 
DrawPie(const Rect & oval,scalar startAngle,scalar sweepAngle)189 void RSPaintFilterCanvasBase::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle)
190 {
191 #ifdef SKP_RECORDING_ENABLED
192     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
193         if ((*iter) != nullptr && OnFilter()) {
194             (*iter)->DrawPie(oval, startAngle, sweepAngle);
195         }
196     }
197 #else
198     if (canvas_ != nullptr && OnFilter()) {
199         canvas_->DrawPie(oval, startAngle, sweepAngle);
200     }
201 #endif
202 }
203 
DrawOval(const Rect & oval)204 void RSPaintFilterCanvasBase::DrawOval(const Rect& oval)
205 {
206 #ifdef SKP_RECORDING_ENABLED
207     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
208         if ((*iter) != nullptr && OnFilter()) {
209             (*iter)->DrawOval(oval);
210         }
211     }
212 #else
213     if (canvas_ != nullptr && OnFilter()) {
214         canvas_->DrawOval(oval);
215     }
216 #endif
217 }
218 
DrawCircle(const Point & centerPt,scalar radius)219 void RSPaintFilterCanvasBase::DrawCircle(const Point& centerPt, scalar radius)
220 {
221 #ifdef SKP_RECORDING_ENABLED
222     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
223         if ((*iter) != nullptr && OnFilter()) {
224             (*iter)->DrawCircle(centerPt, radius);
225         }
226     }
227 #else
228     if (canvas_ != nullptr && OnFilter()) {
229         canvas_->DrawCircle(centerPt, radius);
230     }
231 #endif
232 }
233 
DrawPath(const Path & path)234 void RSPaintFilterCanvasBase::DrawPath(const Path& path)
235 {
236 #ifdef SKP_RECORDING_ENABLED
237     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
238         if ((*iter) != nullptr && OnFilter()) {
239             (*iter)->DrawPath(path);
240         }
241     }
242 #else
243     if (canvas_ != nullptr && OnFilter()) {
244         canvas_->DrawPath(path);
245     }
246 #endif
247 }
248 
DrawPathWithStencil(const Drawing::Path & path,uint32_t stencilVal)249 void RSPaintFilterCanvasBase::DrawPathWithStencil(const Drawing::Path& path, uint32_t stencilVal)
250 {
251 #ifdef SKP_RECORDING_ENABLED
252     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
253         if ((*iter) != nullptr && OnFilter()) {
254             (*iter)->DrawPathWithStencil(path, stencilVal);
255         }
256     }
257 #else
258     if (canvas_ != nullptr && OnFilter()) {
259         canvas_->DrawPathWithStencil(path, stencilVal);
260     }
261 #endif
262 }
263 
DrawBackground(const Brush & brush)264 void RSPaintFilterCanvasBase::DrawBackground(const Brush& brush)
265 {
266     Brush b(brush);
267 #ifdef SKP_RECORDING_ENABLED
268     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
269         if ((*iter) != nullptr && OnFilterWithBrush(b)) {
270             (*iter)->DrawBackground(b);
271         }
272     }
273 #else
274     if (canvas_ != nullptr && OnFilterWithBrush(b)) {
275         canvas_->DrawBackground(b);
276     }
277 #endif
278 }
279 
DrawShadow(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag)280 void RSPaintFilterCanvasBase::DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos,
281     scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag)
282 {
283 #ifdef SKP_RECORDING_ENABLED
284     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
285         if ((*iter) != nullptr && OnFilter()) {
286             (*iter)->DrawShadow(path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag);
287         }
288     }
289 #else
290     if (canvas_ != nullptr && OnFilter()) {
291         canvas_->DrawShadow(path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag);
292     }
293 #endif
294 }
295 
DrawShadowStyle(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag,bool isLimitElevation)296 void RSPaintFilterCanvasBase::DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos,
297     scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation)
298 {
299 #ifdef SKP_RECORDING_ENABLED
300     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
301         if ((*iter) != nullptr && OnFilter()) {
302             (*iter)->DrawShadowStyle(
303                 path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag, isLimitElevation);
304         }
305     }
306 #else
307     if (canvas_ != nullptr && OnFilter()) {
308         canvas_->DrawShadowStyle(
309             path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag, isLimitElevation);
310     }
311 #endif
312 }
313 
DrawColor(Drawing::ColorQuad color,Drawing::BlendMode mode)314 void RSPaintFilterCanvasBase::DrawColor(Drawing::ColorQuad color, Drawing::BlendMode mode)
315 {
316 #ifdef SKP_RECORDING_ENABLED
317     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
318         if ((*iter) != nullptr && OnFilter()) {
319             (*iter)->DrawColor(color, mode);
320         }
321     }
322 #else
323     if (canvas_ != nullptr && OnFilter()) {
324         canvas_->DrawColor(color, mode);
325     }
326 #endif
327 }
328 
DrawRegion(const Drawing::Region & region)329 void RSPaintFilterCanvasBase::DrawRegion(const Drawing::Region& region)
330 {
331 #ifdef SKP_RECORDING_ENABLED
332     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
333         if ((*iter) != nullptr && OnFilter()) {
334             (*iter)->DrawRegion(region);
335         }
336     }
337 #else
338     if (canvas_ != nullptr && OnFilter()) {
339         canvas_->DrawRegion(region);
340     }
341 #endif
342 }
343 
DrawPatch(const Drawing::Point cubics[12],const Drawing::ColorQuad colors[4],const Drawing::Point texCoords[4],Drawing::BlendMode mode)344 void RSPaintFilterCanvasBase::DrawPatch(const Drawing::Point cubics[12], const Drawing::ColorQuad colors[4],
345     const Drawing::Point texCoords[4], Drawing::BlendMode mode)
346 {
347 #ifdef SKP_RECORDING_ENABLED
348     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
349         if ((*iter) != nullptr && OnFilter()) {
350             (*iter)->DrawPatch(cubics, colors, texCoords, mode);
351         }
352     }
353 #else
354     if (canvas_ != nullptr && OnFilter()) {
355         canvas_->DrawPatch(cubics, colors, texCoords, mode);
356     }
357 #endif
358 }
359 
DrawVertices(const Drawing::Vertices & vertices,Drawing::BlendMode mode)360 void RSPaintFilterCanvasBase::DrawVertices(const Drawing::Vertices& vertices, Drawing::BlendMode mode)
361 {
362 #ifdef SKP_RECORDING_ENABLED
363     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
364         if ((*iter) != nullptr && OnFilter()) {
365             (*iter)->DrawVertices(vertices, mode);
366         }
367     }
368 #else
369     if (canvas_ != nullptr && OnFilter()) {
370         canvas_->DrawVertices(vertices, mode);
371     }
372 #endif
373 }
374 
OpCalculateBefore(const Matrix & matrix)375 bool RSPaintFilterCanvasBase::OpCalculateBefore(const Matrix& matrix)
376 {
377     if (canvas_ != nullptr && OnFilter()) {
378         return canvas_->OpCalculateBefore(matrix);
379     }
380     return false;
381 }
382 
OpCalculateAfter(const Drawing::Rect & bound)383 std::shared_ptr<Drawing::OpListHandle> RSPaintFilterCanvasBase::OpCalculateAfter(const Drawing::Rect& bound)
384 {
385     if (canvas_ != nullptr && OnFilter()) {
386         return canvas_->OpCalculateAfter(bound);
387     }
388     return nullptr;
389 }
390 
DrawAtlas(const Drawing::Image * atlas,const Drawing::RSXform xform[],const Drawing::Rect tex[],const Drawing::ColorQuad colors[],int count,Drawing::BlendMode mode,const Drawing::SamplingOptions & sampling,const Drawing::Rect * cullRect)391 void RSPaintFilterCanvasBase::DrawAtlas(const Drawing::Image* atlas, const Drawing::RSXform xform[],
392     const Drawing::Rect tex[], const Drawing::ColorQuad colors[], int count, Drawing::BlendMode mode,
393     const Drawing::SamplingOptions& sampling, const Drawing::Rect* cullRect)
394 {
395 #ifdef SKP_RECORDING_ENABLED
396     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
397         if ((*iter) != nullptr && OnFilter()) {
398             (*iter)->DrawAtlas(atlas, xform, tex, colors, count, mode, sampling, cullRect);
399         }
400     }
401 #else
402     if (canvas_ != nullptr && OnFilter()) {
403         canvas_->DrawAtlas(atlas, xform, tex, colors, count, mode, sampling, cullRect);
404     }
405 #endif
406 }
407 
DrawBitmap(const Bitmap & bitmap,const scalar px,const scalar py)408 void RSPaintFilterCanvasBase::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py)
409 {
410 #ifdef SKP_RECORDING_ENABLED
411     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
412         if ((*iter) != nullptr && OnFilter()) {
413             (*iter)->DrawBitmap(bitmap, px, py);
414         }
415     }
416 #else
417     if (canvas_ != nullptr && OnFilter()) {
418         canvas_->DrawBitmap(bitmap, px, py);
419     }
420 #endif
421 }
422 
DrawImageNine(const Drawing::Image * image,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filter,const Drawing::Brush * brush)423 void RSPaintFilterCanvasBase::DrawImageNine(const Drawing::Image* image, const Drawing::RectI& center,
424     const Drawing::Rect& dst, Drawing::FilterMode filter, const Drawing::Brush* brush)
425 {
426 #ifdef SKP_RECORDING_ENABLED
427     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
428         if ((*iter) != nullptr && OnFilter()) {
429             if (brush) {
430                 Drawing::Brush b(*brush);
431                 OnFilterWithBrush(b);
432                 (*iter)->DrawImageNine(image, center, dst, filter, &b);
433             } else {
434                 (*iter)->DrawImageNine(image, center, dst, filter, GetFilteredBrush());
435             }
436         }
437     }
438 #else
439     if (canvas_ != nullptr && OnFilter()) {
440         if (brush) {
441             Drawing::Brush b(*brush);
442             OnFilterWithBrush(b);
443             canvas_->DrawImageNine(image, center, dst, filter, &b);
444         } else {
445             canvas_->DrawImageNine(image, center, dst, filter, GetFilteredBrush());
446         }
447     }
448 #endif
449 }
450 
DrawImageLattice(const Drawing::Image * image,const Drawing::Lattice & lattice,const Drawing::Rect & dst,Drawing::FilterMode filter)451 void RSPaintFilterCanvasBase::DrawImageLattice(const Drawing::Image* image, const Drawing::Lattice& lattice,
452     const Drawing::Rect& dst, Drawing::FilterMode filter)
453 {
454 #ifdef SKP_RECORDING_ENABLED
455     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
456         if ((*iter) != nullptr && OnFilter()) {
457             (*iter)->DrawImageLattice(image, lattice, dst, filter);
458         }
459     }
460 #else
461     if (canvas_ != nullptr && OnFilter()) {
462         canvas_->DrawImageLattice(image, lattice, dst, filter);
463     }
464 #endif
465 }
466 
DrawImage(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling)467 void RSPaintFilterCanvasBase::DrawImage(
468     const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling)
469 {
470 #ifdef SKP_RECORDING_ENABLED
471     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
472         if ((*iter) != nullptr && OnFilter()) {
473             (*iter)->DrawImage(image, px, py, sampling);
474         }
475     }
476 #else
477     if (canvas_ != nullptr && OnFilter()) {
478         canvas_->DrawImage(image, px, py, sampling);
479     }
480 #endif
481 }
482 
DrawImageWithStencil(const Drawing::Image & image,const Drawing::scalar px,const Drawing::scalar py,const Drawing::SamplingOptions & sampling,uint32_t stencilVal)483 void RSPaintFilterCanvasBase::DrawImageWithStencil(const Drawing::Image& image, const Drawing::scalar px,
484     const Drawing::scalar py, const Drawing::SamplingOptions& sampling, uint32_t stencilVal)
485 {
486 #ifdef SKP_RECORDING_ENABLED
487     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
488         if ((*iter) != nullptr && OnFilter()) {
489             (*iter)->DrawImageWithStencil(image, px, py, sampling, stencilVal);
490         }
491     }
492 #else
493     if (canvas_ != nullptr && OnFilter()) {
494         canvas_->DrawImageWithStencil(image, px, py, sampling, stencilVal);
495     }
496 #endif
497 }
498 
DrawImageRect(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint)499 void RSPaintFilterCanvasBase::DrawImageRect(const Image& image, const Rect& src, const Rect& dst,
500     const SamplingOptions& sampling, SrcRectConstraint constraint)
501 {
502 #ifdef SKP_RECORDING_ENABLED
503     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
504         if ((*iter) != nullptr && OnFilter()) {
505             (*iter)->DrawImageRect(image, src, dst, sampling, constraint);
506         }
507     }
508 #else
509     if (canvas_ != nullptr && OnFilter()) {
510         canvas_->DrawImageRect(image, src, dst, sampling, constraint);
511     }
512 #endif
513 }
514 
DrawImageRect(const Image & image,const Rect & dst,const SamplingOptions & sampling)515 void RSPaintFilterCanvasBase::DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling)
516 {
517 #ifdef SKP_RECORDING_ENABLED
518     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
519         if ((*iter) != nullptr && OnFilter()) {
520             (*iter)->DrawImageRect(image, dst, sampling);
521         }
522     }
523 #else
524     if (canvas_ != nullptr && OnFilter()) {
525         canvas_->DrawImageRect(image, dst, sampling);
526     }
527 #endif
528 }
529 
DrawPicture(const Picture & picture)530 void RSPaintFilterCanvasBase::DrawPicture(const Picture& picture)
531 {
532 #ifdef SKP_RECORDING_ENABLED
533     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
534         if ((*iter) != nullptr && OnFilter()) {
535             (*iter)->DrawPicture(picture);
536         }
537     }
538 #else
539     if (canvas_ != nullptr && OnFilter()) {
540         canvas_->DrawPicture(picture);
541     }
542 #endif
543 }
544 
DrawTextBlob(const Drawing::TextBlob * blob,const Drawing::scalar x,const Drawing::scalar y)545 void RSPaintFilterCanvasBase::DrawTextBlob(
546     const Drawing::TextBlob* blob, const Drawing::scalar x, const Drawing::scalar y)
547 {
548 #ifdef SKP_RECORDING_ENABLED
549     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
550         if ((*iter) != nullptr && OnFilter()) {
551             (*iter)->DrawTextBlob(blob, x, y);
552         }
553     }
554 #else
555     if (canvas_ != nullptr && OnFilter()) {
556         canvas_->DrawTextBlob(blob, x, y);
557     }
558 #endif
559 }
560 
ClearStencil(const Drawing::RectI & rect,uint32_t stencilVal)561 void RSPaintFilterCanvasBase::ClearStencil(const Drawing::RectI& rect, uint32_t stencilVal)
562 {
563 #ifdef SKP_RECORDING_ENABLED
564     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
565         if ((*iter) != nullptr) {
566             (*iter)->ClearStencil(rect, stencilVal);
567         }
568     }
569 #else
570     if (canvas_ != nullptr) {
571         canvas_->ClearStencil(rect, stencilVal);
572     }
573 #endif
574 }
575 
ClipRect(const Drawing::Rect & rect,Drawing::ClipOp op,bool doAntiAlias)576 void RSPaintFilterCanvasBase::ClipRect(const Drawing::Rect& rect, Drawing::ClipOp op, bool doAntiAlias)
577 {
578 #ifdef SKP_RECORDING_ENABLED
579     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
580         if ((*iter) != nullptr) {
581             (*iter)->ClipRect(rect, op, doAntiAlias);
582         }
583     }
584 #else
585     if (canvas_ != nullptr) {
586         canvas_->ClipRect(rect, op, doAntiAlias);
587     }
588 #endif
589 }
590 
ClipIRect(const Drawing::RectI & rect,Drawing::ClipOp op)591 void RSPaintFilterCanvasBase::ClipIRect(const Drawing::RectI& rect, Drawing::ClipOp op)
592 {
593 #ifdef SKP_RECORDING_ENABLED
594     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
595         if ((*iter) != nullptr) {
596             (*iter)->ClipIRect(rect, op);
597         }
598     }
599 #else
600     if (canvas_ != nullptr) {
601         canvas_->ClipIRect(rect, op);
602     }
603 #endif
604 }
605 
ClipRoundRect(const RoundRect & roundRect,ClipOp op,bool doAntiAlias)606 void RSPaintFilterCanvasBase::ClipRoundRect(const RoundRect& roundRect, ClipOp op, bool doAntiAlias)
607 {
608 #ifdef SKP_RECORDING_ENABLED
609     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
610         if ((*iter) != nullptr) {
611             (*iter)->ClipRoundRect(roundRect, op, doAntiAlias);
612         }
613     }
614 #else
615     if (canvas_ != nullptr) {
616         canvas_->ClipRoundRect(roundRect, op, doAntiAlias);
617     }
618 #endif
619 }
620 
ClipRoundRect(const Drawing::Rect & rect,std::vector<Drawing::Point> & pts,bool doAntiAlias)621 void RSPaintFilterCanvasBase::ClipRoundRect(const Drawing::Rect& rect,
622     std::vector<Drawing::Point>& pts, bool doAntiAlias)
623 {
624 #ifdef SKP_RECORDING_ENABLED
625     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
626         if ((*iter) != nullptr) {
627             (*iter)->ClipRoundRect(rect, pts, doAntiAlias);
628         }
629     }
630 #else
631     if (canvas_ != nullptr) {
632         canvas_->ClipRoundRect(rect, pts, doAntiAlias);
633     }
634 #endif
635 }
636 
ClipPath(const Path & path,ClipOp op,bool doAntiAlias)637 void RSPaintFilterCanvasBase::ClipPath(const Path& path, ClipOp op, bool doAntiAlias)
638 {
639 #ifdef SKP_RECORDING_ENABLED
640     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
641         if ((*iter) != nullptr) {
642             (*iter)->ClipPath(path, op, doAntiAlias);
643         }
644     }
645 #else
646     if (canvas_ != nullptr) {
647         canvas_->ClipPath(path, op, doAntiAlias);
648     }
649 #endif
650 }
651 
ClipRegion(const Region & region,ClipOp op)652 void RSPaintFilterCanvasBase::ClipRegion(const Region& region, ClipOp op)
653 {
654 #ifdef SKP_RECORDING_ENABLED
655     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
656         if ((*iter) != nullptr) {
657             (*iter)->ClipRegion(region, op);
658         }
659     }
660 #else
661     if (canvas_ != nullptr) {
662         canvas_->ClipRegion(region, op);
663     }
664 #endif
665 }
666 
ResetClip()667 void RSPaintFilterCanvasBase::ResetClip()
668 {
669 #ifdef SKP_RECORDING_ENABLED
670     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
671         if ((*iter) != nullptr) {
672             (*iter)->ResetClip();
673         }
674     }
675 #else
676     if (canvas_ != nullptr) {
677         canvas_->ResetClip();
678     }
679 #endif
680 }
681 
SetMatrix(const Matrix & matrix)682 void RSPaintFilterCanvasBase::SetMatrix(const Matrix& matrix)
683 {
684 #ifdef SKP_RECORDING_ENABLED
685     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
686         if ((*iter) != nullptr) {
687             (*iter)->SetMatrix(matrix);
688         }
689     }
690 #else
691     if (canvas_ != nullptr) {
692         canvas_->SetMatrix(matrix);
693     }
694 #endif
695 }
696 
ResetMatrix()697 void RSPaintFilterCanvasBase::ResetMatrix()
698 {
699 #ifdef SKP_RECORDING_ENABLED
700     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
701         if ((*iter) != nullptr) {
702             (*iter)->ResetMatrix();
703         }
704     }
705 #else
706     if (canvas_ != nullptr) {
707         canvas_->ResetMatrix();
708     }
709 #endif
710 }
711 
ConcatMatrix(const Matrix & matrix)712 void RSPaintFilterCanvasBase::ConcatMatrix(const Matrix& matrix)
713 {
714 #ifdef SKP_RECORDING_ENABLED
715     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
716         if ((*iter) != nullptr) {
717             (*iter)->ConcatMatrix(matrix);
718         }
719     }
720 #else
721     if (canvas_ != nullptr) {
722         canvas_->ConcatMatrix(matrix);
723     }
724 #endif
725 }
726 
Translate(scalar dx,scalar dy)727 void RSPaintFilterCanvasBase::Translate(scalar dx, scalar dy)
728 {
729 #ifdef SKP_RECORDING_ENABLED
730     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
731         if ((*iter) != nullptr) {
732             (*iter)->Translate(dx, dy);
733         }
734     }
735 #else
736     if (canvas_ != nullptr) {
737         canvas_->Translate(dx, dy);
738     }
739 #endif
740 }
741 
Scale(scalar sx,scalar sy)742 void RSPaintFilterCanvasBase::Scale(scalar sx, scalar sy)
743 {
744 #ifdef SKP_RECORDING_ENABLED
745     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
746         if ((*iter) != nullptr) {
747             (*iter)->Scale(sx, sy);
748         }
749     }
750 #else
751     if (canvas_ != nullptr) {
752         canvas_->Scale(sx, sy);
753     }
754 #endif
755 }
756 
Rotate(scalar deg,scalar sx,scalar sy)757 void RSPaintFilterCanvasBase::Rotate(scalar deg, scalar sx, scalar sy)
758 {
759 #ifdef SKP_RECORDING_ENABLED
760     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
761         if ((*iter) != nullptr) {
762             (*iter)->Rotate(deg, sx, sy);
763         }
764     }
765 #else
766     if (canvas_ != nullptr) {
767         canvas_->Rotate(deg, sx, sy);
768     }
769 #endif
770 }
771 
Shear(scalar sx,scalar sy)772 void RSPaintFilterCanvasBase::Shear(scalar sx, scalar sy)
773 {
774 #ifdef SKP_RECORDING_ENABLED
775     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
776         if ((*iter) != nullptr) {
777             (*iter)->Shear(sx, sy);
778         }
779     }
780 #else
781     if (canvas_ != nullptr) {
782         canvas_->Shear(sx, sy);
783     }
784 #endif
785 }
786 
Flush()787 void RSPaintFilterCanvasBase::Flush()
788 {
789 #ifdef SKP_RECORDING_ENABLED
790     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
791         if ((*iter) != nullptr) {
792             (*iter)->Flush();
793         }
794     }
795 #else
796     if (canvas_ != nullptr) {
797         canvas_->Flush();
798     }
799 #endif
800 }
801 
Clear(ColorQuad color)802 void RSPaintFilterCanvasBase::Clear(ColorQuad color)
803 {
804 #ifdef SKP_RECORDING_ENABLED
805     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
806         if ((*iter) != nullptr) {
807             (*iter)->Clear(color);
808         }
809     }
810 #else
811     if (canvas_ != nullptr) {
812         canvas_->Clear(color);
813     }
814 #endif
815 }
816 
Save()817 uint32_t RSPaintFilterCanvasBase::Save()
818 {
819 #ifdef SKP_RECORDING_ENABLED
820     uint32_t count = 0U;
821     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
822         if ((*iter) != nullptr) {
823             auto c = (*iter)->Save();
824             if ((*iter) == canvas_) {
825                 count = c;
826             }
827         }
828     }
829     return count;
830 #else
831     if (canvas_ != nullptr) {
832         return canvas_->Save();
833     }
834     return 0;
835 #endif
836 }
837 
SaveLayer(const SaveLayerOps & saveLayerRec)838 void RSPaintFilterCanvasBase::SaveLayer(const SaveLayerOps& saveLayerRec)
839 {
840     if (canvas_ == nullptr) {
841         return;
842     }
843     Brush brush;
844     if (saveLayerRec.GetBrush() != nullptr) {
845         brush = *saveLayerRec.GetBrush();
846         OnFilterWithBrush(brush);
847     }
848     SaveLayerOps slo(saveLayerRec.GetBounds(), &brush, saveLayerRec.GetSaveLayerFlags());
849 #ifdef SKP_RECORDING_ENABLED
850     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
851         if ((*iter) != nullptr) {
852             (*iter)->SaveLayer(slo);
853         }
854     }
855 #else
856     canvas_->SaveLayer(slo);
857 #endif
858 }
859 
Restore()860 void RSPaintFilterCanvasBase::Restore()
861 {
862 #ifdef SKP_RECORDING_ENABLED
863     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
864         if ((*iter) != nullptr) {
865             (*iter)->Restore();
866         }
867     }
868 #else
869     if (canvas_ != nullptr) {
870         canvas_->Restore();
871     }
872 #endif
873 }
874 
Discard()875 void RSPaintFilterCanvasBase::Discard()
876 {
877 #ifdef SKP_RECORDING_ENABLED
878     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
879         if ((*iter) != nullptr) {
880             (*iter)->Discard();
881         }
882     }
883 #else
884     if (canvas_ != nullptr) {
885         canvas_->Discard();
886     }
887 #endif
888 }
889 
AttachPen(const Pen & pen)890 CoreCanvas& RSPaintFilterCanvasBase::AttachPen(const Pen& pen)
891 {
892 #ifdef SKP_RECORDING_ENABLED
893     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
894         if ((*iter) != nullptr) {
895             (*iter)->AttachPen(pen);
896         }
897     }
898 #else
899     if (canvas_ != nullptr) {
900         canvas_->AttachPen(pen);
901     }
902 #endif
903     return *this;
904 }
905 
AttachBrush(const Brush & brush)906 CoreCanvas& RSPaintFilterCanvasBase::AttachBrush(const Brush& brush)
907 {
908 #ifdef SKP_RECORDING_ENABLED
909     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
910         if ((*iter) != nullptr) {
911             (*iter)->AttachBrush(brush);
912         }
913     }
914 #else
915     if (canvas_ != nullptr) {
916         canvas_->AttachBrush(brush);
917     }
918 #endif
919     return *this;
920 }
921 
AttachPaint(const Drawing::Paint & paint)922 CoreCanvas& RSPaintFilterCanvasBase::AttachPaint(const Drawing::Paint& paint)
923 {
924 #ifdef SKP_RECORDING_ENABLED
925     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
926         if ((*iter) != nullptr) {
927             (*iter)->AttachPaint(paint);
928         }
929     }
930 #else
931     if (canvas_ != nullptr) {
932         canvas_->AttachPaint(paint);
933     }
934 #endif
935     return *this;
936 }
937 
DetachPen()938 CoreCanvas& RSPaintFilterCanvasBase::DetachPen()
939 {
940 #ifdef SKP_RECORDING_ENABLED
941     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
942         if ((*iter) != nullptr) {
943             (*iter)->DetachPen();
944         }
945     }
946 #else
947     if (canvas_ != nullptr) {
948         canvas_->DetachPen();
949     }
950 #endif
951     return *this;
952 }
953 
DetachBrush()954 CoreCanvas& RSPaintFilterCanvasBase::DetachBrush()
955 {
956 #ifdef SKP_RECORDING_ENABLED
957     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
958         if ((*iter) != nullptr) {
959             (*iter)->DetachBrush();
960         }
961     }
962 #else
963     if (canvas_ != nullptr) {
964         canvas_->DetachBrush();
965     }
966 #endif
967     return *this;
968 }
969 
DetachPaint()970 CoreCanvas& RSPaintFilterCanvasBase::DetachPaint()
971 {
972 #ifdef SKP_RECORDING_ENABLED
973     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
974         if ((*iter) != nullptr) {
975             (*iter)->DetachPaint();
976         }
977     }
978 #else
979     if (canvas_ != nullptr) {
980         canvas_->DetachPaint();
981     }
982 #endif
983     return *this;
984 }
985 
DrawBlurImage(const Drawing::Image & image,const Drawing::HpsBlurParameter & blurParams)986 bool RSPaintFilterCanvasBase::DrawBlurImage(const Drawing::Image& image, const Drawing::HpsBlurParameter& blurParams)
987 {
988     bool result = false;
989 #ifdef SKP_RECORDING_ENABLED
990     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
991         if ((*iter) != nullptr) {
992             result = ((*iter)->DrawBlurImage(image, blurParams) || result);
993         }
994     }
995 #else
996     if (canvas_ != nullptr) {
997         result = canvas_->DrawBlurImage(image, blurParams);
998     }
999 #endif
1000     return result;
1001 }
1002 
CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter & blurParams)1003 std::array<int, 2> RSPaintFilterCanvasBase::CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter& blurParams)
1004 {
1005     std::array<int, 2> result = {0, 0}; // There are 2 variables
1006 #ifdef SKP_RECORDING_ENABLED
1007     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
1008         if ((*iter) != nullptr) {
1009             result = (*iter)->CalcHpsBluredImageDimension(blurParams);
1010         }
1011     }
1012 #else
1013     if (canvas_ != nullptr) {
1014         result = canvas_->CalcHpsBluredImageDimension(blurParams);
1015     }
1016 #endif
1017     return result;
1018 }
1019 
IsClipRect()1020 bool RSPaintFilterCanvasBase::IsClipRect()
1021 {
1022     bool result = false;
1023 #ifdef SKP_RECORDING_ENABLED
1024     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
1025         if ((*iter) != nullptr) {
1026             result = result || (*iter)->IsClipRect();
1027         }
1028     }
1029 #else
1030     if (canvas_ != nullptr) {
1031         result = canvas_->IsClipRect();
1032     }
1033 #endif
1034     return result;
1035 }
1036 
RSPaintFilterCanvas(Drawing::Canvas * canvas,float alpha)1037 RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha)
1038     : RSPaintFilterCanvasBase(canvas), alphaStack_({ 1.0f }),
1039       envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } })
1040 {
1041     (void)alpha; // alpha is no longer used, but we keep it for backward compatibility
1042 }
1043 
RSPaintFilterCanvas(Drawing::Surface * surface,float alpha)1044 RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Surface* surface, float alpha)
1045     : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), alphaStack_({ 1.0f }),
1046       envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } })
1047 {
1048     (void)alpha; // alpha is no longer used, but we keep it for backward compatibility
1049 }
1050 
GetSurface() const1051 Drawing::Surface* RSPaintFilterCanvas::GetSurface() const
1052 {
1053     return surface_;
1054 }
1055 
AttachPen(const Pen & pen)1056 CoreCanvas& RSPaintFilterCanvas::AttachPen(const Pen& pen)
1057 {
1058     if (canvas_ == nullptr) {
1059         return *this;
1060     }
1061 
1062     Pen p(pen);
1063     if (p.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification
1064         p.SetColor(envStack_.top().envForegroundColor_.AsArgbInt());
1065     }
1066 
1067     // use alphaStack_.top() to multiply alpha
1068     if (alphaStack_.top() < 1 && alphaStack_.top() > 0) {
1069         p.SetAlpha(p.GetAlpha() * alphaStack_.top());
1070     }
1071 
1072     // use envStack_.top().blender_ to set blender
1073     if (auto& blender = envStack_.top().blender_) {
1074         if (p.GetBlenderEnabled()) {
1075             p.SetBlender(blender);
1076         }
1077     }
1078 
1079 #ifdef SKP_RECORDING_ENABLED
1080     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
1081         if ((*iter) != nullptr) {
1082             (*iter)->AttachPen(p);
1083         }
1084     }
1085 #else
1086     canvas_->AttachPen(p);
1087 #endif
1088     return *this;
1089 }
1090 
AttachBrush(const Brush & brush)1091 CoreCanvas& RSPaintFilterCanvas::AttachBrush(const Brush& brush)
1092 {
1093     if (canvas_ == nullptr) {
1094         return *this;
1095     }
1096 
1097     Brush b(brush);
1098     if (b.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification
1099         b.SetColor(envStack_.top().envForegroundColor_.AsArgbInt());
1100     }
1101 
1102     // use alphaStack_.top() to multiply alpha
1103     if (alphaStack_.top() < 1 && alphaStack_.top() > 0) {
1104         b.SetAlpha(b.GetAlpha() * alphaStack_.top());
1105     }
1106 
1107     // use envStack_.top().blender_ to set blender
1108     if (auto& blender = envStack_.top().blender_) {
1109         if (b.GetBlenderEnabled()) {
1110             b.SetBlender(blender);
1111         }
1112     }
1113 
1114 #ifdef SKP_RECORDING_ENABLED
1115     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
1116         if ((*iter) != nullptr) {
1117             (*iter)->AttachBrush(b);
1118         }
1119     }
1120 #else
1121     canvas_->AttachBrush(b);
1122 #endif
1123     return *this;
1124 }
1125 
AttachPaint(const Drawing::Paint & paint)1126 CoreCanvas& RSPaintFilterCanvas::AttachPaint(const Drawing::Paint& paint)
1127 {
1128     if (canvas_ == nullptr) {
1129         return *this;
1130     }
1131 
1132     Paint p(paint);
1133     if (p.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification
1134         p.SetColor(envStack_.top().envForegroundColor_.AsArgbInt());
1135     }
1136 
1137     // use alphaStack_.top() to multiply alpha
1138     if (alphaStack_.top() < 1 && alphaStack_.top() > 0) {
1139         p.SetAlpha(p.GetAlpha() * alphaStack_.top());
1140     }
1141 
1142     // use envStack_.top().blender_ to set blender
1143     if (auto& blender = envStack_.top().blender_) {
1144         if (p.GetBlenderEnabled()) {
1145             p.SetBlender(blender);
1146         }
1147     }
1148 
1149 #ifdef SKP_RECORDING_ENABLED
1150     for (auto iter = pCanvasList_.begin(); iter != pCanvasList_.end(); ++iter) {
1151         if ((*iter) != nullptr) {
1152             (*iter)->AttachPaint(p);
1153         }
1154     }
1155 #else
1156     canvas_->AttachPaint(p);
1157 #endif
1158     return *this;
1159 }
1160 
OnFilter() const1161 bool RSPaintFilterCanvas::OnFilter() const
1162 {
1163     return alphaStack_.top() > 0.f;
1164 }
1165 
GetRecordingCanvas() const1166 Drawing::Canvas* RSPaintFilterCanvas::GetRecordingCanvas() const
1167 {
1168     return recordingState_ ? canvas_ : nullptr;
1169 }
1170 
GetRecordingState() const1171 bool RSPaintFilterCanvas::GetRecordingState() const
1172 {
1173     return recordingState_;
1174 }
1175 
SetRecordingState(bool flag)1176 void RSPaintFilterCanvas::SetRecordingState(bool flag)
1177 {
1178     recordingState_ = flag;
1179 }
1180 
MultiplyAlpha(float alpha)1181 void RSPaintFilterCanvas::MultiplyAlpha(float alpha)
1182 {
1183     // multiply alpha to top of stack
1184     alphaStack_.top() *= std::clamp(alpha, 0.f, 1.f);
1185 }
1186 
SetAlpha(float alpha)1187 void RSPaintFilterCanvas::SetAlpha(float alpha)
1188 {
1189     alphaStack_.top() = std::clamp(alpha, 0.f, 1.f);
1190 }
1191 
SaveAlpha()1192 int RSPaintFilterCanvas::SaveAlpha()
1193 {
1194     // make a copy of top of stack
1195     alphaStack_.push(alphaStack_.top());
1196     // return prev stack height
1197     return alphaStack_.size() - 1;
1198 }
1199 
GetAlpha() const1200 float RSPaintFilterCanvas::GetAlpha() const
1201 {
1202     // return top of stack
1203     return alphaStack_.top();
1204 }
1205 
RestoreAlpha()1206 void RSPaintFilterCanvas::RestoreAlpha()
1207 {
1208     // sanity check, stack should not be empty
1209     if (alphaStack_.size() <= 1u) {
1210         return;
1211     }
1212     alphaStack_.pop();
1213 }
1214 
GetAlphaSaveCount() const1215 int RSPaintFilterCanvas::GetAlphaSaveCount() const
1216 {
1217     return alphaStack_.size();
1218 }
1219 
RestoreAlphaToCount(int count)1220 void RSPaintFilterCanvas::RestoreAlphaToCount(int count)
1221 {
1222     // sanity check, stack should not be empty
1223     if (count < 1) {
1224         count = 1;
1225     }
1226     // poo stack until stack height equals count
1227     int n = static_cast<int>(alphaStack_.size()) - count;
1228     for (int i = 0; i < n; ++i) {
1229         alphaStack_.pop();
1230     }
1231 }
1232 
SetBlendMode(std::optional<int> blendMode)1233 void RSPaintFilterCanvas::SetBlendMode(std::optional<int> blendMode)
1234 {
1235     std::shared_ptr<Drawing::Blender> blender = nullptr;
1236     if (blendMode) {
1237         // map blendMode to Drawing::BlendMode and convert to Blender
1238         blender = Drawing::Blender::CreateWithBlendMode(static_cast<Drawing::BlendMode>(*blendMode));
1239     }
1240     RSPaintFilterCanvas::SetBlender(blender);
1241 }
1242 
SetBlender(std::shared_ptr<Drawing::Blender> blender)1243 void RSPaintFilterCanvas::SetBlender(std::shared_ptr<Drawing::Blender> blender)
1244 {
1245     envStack_.top().blender_ = blender;
1246 }
1247 
SaveEnv()1248 int RSPaintFilterCanvas::SaveEnv()
1249 {
1250     // make a copy of top of stack
1251     envStack_.push(envStack_.top());
1252     // return prev stack height
1253     return envStack_.size() - 1;
1254 }
1255 
RestoreEnv()1256 void RSPaintFilterCanvas::RestoreEnv()
1257 {
1258     // sanity check, stack should not be empty
1259     if (envStack_.size() <= 1) {
1260         return;
1261     }
1262     envStack_.pop();
1263 }
1264 
RestoreEnvToCount(int count)1265 void RSPaintFilterCanvas::RestoreEnvToCount(int count)
1266 {
1267     // sanity check, stack should not be empty
1268     if (count < 1) {
1269         count = 1;
1270     }
1271     // poo stack until stack height equals count
1272     int n = static_cast<int>(envStack_.size()) - count;
1273     for (int i = 0; i < n; ++i) {
1274         envStack_.pop();
1275     }
1276 }
1277 
GetEnvSaveCount() const1278 int RSPaintFilterCanvas::GetEnvSaveCount() const
1279 {
1280     return envStack_.size();
1281 }
1282 
SetEnvForegroundColor(Rosen::RSColor color)1283 void RSPaintFilterCanvas::SetEnvForegroundColor(Rosen::RSColor color)
1284 {
1285     // sanity check, stack should not be empty
1286     if (envStack_.empty()) {
1287         return;
1288     }
1289     envStack_.top().envForegroundColor_ = color;
1290 }
1291 
GetEnvForegroundColor() const1292 Drawing::ColorQuad RSPaintFilterCanvas::GetEnvForegroundColor() const
1293 {
1294     // sanity check, stack should not be empty
1295     if (envStack_.empty()) {
1296         return Drawing::Color::COLOR_BLACK; // 0xFF000000 is default value -- black
1297     }
1298     return envStack_.top().envForegroundColor_.AsArgbInt();
1299 }
1300 
SaveAllStatus(SaveType type)1301 RSPaintFilterCanvas::SaveStatus RSPaintFilterCanvas::SaveAllStatus(SaveType type)
1302 {
1303     // save and return status on demand
1304     return { (RSPaintFilterCanvas::kCanvas & type) ? Save() : GetSaveCount(),
1305         (RSPaintFilterCanvas::kAlpha & type) ? SaveAlpha() : GetAlphaSaveCount(),
1306         (RSPaintFilterCanvas::kEnv & type) ? SaveEnv() : GetEnvSaveCount() };
1307 }
1308 
GetSaveStatus() const1309 RSPaintFilterCanvas::SaveStatus RSPaintFilterCanvas::GetSaveStatus() const
1310 {
1311     return { GetSaveCount(), GetAlphaSaveCount(), GetEnvSaveCount() };
1312 }
1313 
RestoreStatus(const SaveStatus & status)1314 void RSPaintFilterCanvas::RestoreStatus(const SaveStatus& status)
1315 {
1316     // simultaneously restore canvas and alpha
1317     RestoreToCount(status.canvasSaveCount);
1318     RestoreAlphaToCount(status.alphaSaveCount);
1319     RestoreEnvToCount(status.envSaveCount);
1320 }
1321 
PushDirtyRegion(Drawing::Region & resultRegion)1322 void RSPaintFilterCanvas::PushDirtyRegion(Drawing::Region& resultRegion)
1323 {
1324     dirtyRegionStack_.push(std::move(resultRegion));
1325 }
1326 
PopDirtyRegion()1327 void RSPaintFilterCanvas::PopDirtyRegion()
1328 {
1329     if (dirtyRegionStack_.empty()) {
1330         RS_LOGW("PopDirtyRegion dirtyRegionStack_ is empty");
1331         return;
1332     }
1333     dirtyRegionStack_.pop();
1334 }
1335 
GetCurDirtyRegion()1336 Drawing::Region& RSPaintFilterCanvas::GetCurDirtyRegion()
1337 {
1338     return dirtyRegionStack_.top();
1339 }
1340 
IsDirtyRegionStackEmpty()1341 bool RSPaintFilterCanvas::IsDirtyRegionStackEmpty()
1342 {
1343     return dirtyRegionStack_.empty();
1344 }
1345 
CopyHDRConfiguration(const RSPaintFilterCanvas & other)1346 void RSPaintFilterCanvas::CopyHDRConfiguration(const RSPaintFilterCanvas& other)
1347 {
1348     brightnessRatio_ = other.brightnessRatio_;
1349     screenId_ = other.screenId_;
1350     targetColorGamut_ = other.targetColorGamut_;
1351     isHdrOn_ = other.isHdrOn_;
1352 }
1353 
CopyConfigurationToOffscreenCanvas(const RSPaintFilterCanvas & other)1354 void RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas(const RSPaintFilterCanvas& other)
1355 {
1356     // Note:
1357     // 1. we don't need to copy alpha status, alpha will be applied when drawing cache.
1358     // 2. This function should only be called when creating offscreen canvas.
1359     // copy high contrast flag
1360     isHighContrastEnabled_.store(other.isHighContrastEnabled_.load());
1361     // copy env
1362     envStack_.top() = other.envStack_.top();
1363     // update effect matrix
1364     auto effectData = other.envStack_.top().effectData_;
1365     if (effectData != nullptr) {
1366         // make a deep copy of effect data, and calculate the mapping matrix from
1367         // local coordinate system to global coordinate system.
1368         auto copiedEffectData = std::make_shared<CachedEffectData>(*effectData);
1369         if (copiedEffectData == nullptr) {
1370             ROSEN_LOGE("RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas fail to create effectData");
1371             return;
1372         }
1373         Drawing::Matrix inverse;
1374         if (other.GetTotalMatrix().Invert(inverse)) {
1375             copiedEffectData->cachedMatrix_.PostConcat(inverse);
1376         } else {
1377             ROSEN_LOGE("RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas get invert matrix failed!");
1378         }
1379         envStack_.top().effectData_ = copiedEffectData;
1380     }
1381     // cache related
1382     if (other.isHighContrastEnabled()) {
1383         // explicit disable cache for high contrast mode
1384         SetCacheType(RSPaintFilterCanvas::CacheType::DISABLED);
1385     } else {
1386         // planning: maybe we should copy source cache status
1387         SetCacheType(other.GetCacheType());
1388     }
1389     isParallelCanvas_ = other.isParallelCanvas_;
1390     disableFilterCache_ = other.disableFilterCache_;
1391     threadIndex_ = other.threadIndex_;
1392 }
1393 
SetHighContrast(bool enabled)1394 void RSPaintFilterCanvas::SetHighContrast(bool enabled)
1395 {
1396     isHighContrastEnabled_ = enabled;
1397 }
isHighContrastEnabled() const1398 bool RSPaintFilterCanvas::isHighContrastEnabled() const
1399 {
1400     return isHighContrastEnabled_;
1401 }
1402 
SetCacheType(CacheType type)1403 void RSPaintFilterCanvas::SetCacheType(CacheType type)
1404 {
1405     cacheType_ = type;
1406 }
GetCacheType() const1407 Drawing::CacheType RSPaintFilterCanvas::GetCacheType() const
1408 {
1409     return cacheType_;
1410 }
1411 
SetVisibleRect(Drawing::Rect visibleRect)1412 void RSPaintFilterCanvas::SetVisibleRect(Drawing::Rect visibleRect)
1413 {
1414     visibleRect_ = visibleRect;
1415 }
1416 
GetVisibleRect() const1417 Drawing::Rect RSPaintFilterCanvas::GetVisibleRect() const
1418 {
1419     return visibleRect_;
1420 }
1421 
GetLocalClipBounds(const Drawing::Canvas & canvas,const Drawing::RectI * clipRect)1422 std::optional<Drawing::Rect> RSPaintFilterCanvas::GetLocalClipBounds(const Drawing::Canvas& canvas,
1423     const Drawing::RectI* clipRect)
1424 {
1425     // if clipRect is explicitly specified, use it as the device clip bounds
1426     Drawing::Rect bounds = Rect((clipRect != nullptr) ? *clipRect : canvas.GetDeviceClipBounds());
1427 
1428     if (!bounds.IsValid()) {
1429         return std::nullopt;
1430     }
1431 
1432     Drawing::Matrix inverse;
1433     // if we can't invert the CTM, we can't return local clip bounds
1434     if (!(canvas.GetTotalMatrix().Invert(inverse))) {
1435         return std::nullopt;
1436     }
1437     // return the inverse of the CTM applied to the device clip bounds as local clip bounds
1438     Drawing::Rect dst;
1439     inverse.MapRect(dst, bounds);
1440     return dst;
1441 }
1442 
1443 
SetEffectData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData> & effectData)1444 void RSPaintFilterCanvas::SetEffectData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& effectData)
1445 {
1446     envStack_.top().effectData_ = effectData;
1447 }
1448 
GetEffectData() const1449 const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& RSPaintFilterCanvas::GetEffectData() const
1450 {
1451     return envStack_.top().effectData_;
1452 }
1453 
SetBehindWindowData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData> & behindWindowData)1454 void RSPaintFilterCanvas::SetBehindWindowData(
1455     const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& behindWindowData)
1456 {
1457     envStack_.top().behindWindowData_ = behindWindowData;
1458 }
1459 
GetBehindWindowData() const1460 const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& RSPaintFilterCanvas::GetBehindWindowData() const
1461 {
1462     return envStack_.top().behindWindowData_;
1463 }
1464 
ReplaceMainScreenData(std::shared_ptr<Drawing::Surface> & offscreenSurface,std::shared_ptr<RSPaintFilterCanvas> & offscreenCanvas)1465 void RSPaintFilterCanvas::ReplaceMainScreenData(std::shared_ptr<Drawing::Surface>& offscreenSurface,
1466     std::shared_ptr<RSPaintFilterCanvas>& offscreenCanvas)
1467 {
1468     if (offscreenSurface != nullptr && offscreenCanvas != nullptr) {
1469         storeMainScreenSurface_.push(surface_);
1470         storeMainScreenCanvas_.push(canvas_);
1471         surface_ = offscreenSurface.get();
1472         canvas_ = offscreenCanvas.get();
1473         OffscreenData offscreenData = {offscreenSurface, offscreenCanvas};
1474         offscreenDataList_.push(offscreenData);
1475     }
1476 }
1477 
SwapBackMainScreenData()1478 void RSPaintFilterCanvas::SwapBackMainScreenData()
1479 {
1480     if (!storeMainScreenSurface_.empty() && !storeMainScreenCanvas_.empty() && !offscreenDataList_.empty()) {
1481         surface_ = storeMainScreenSurface_.top();
1482         canvas_ = storeMainScreenCanvas_.top();
1483         storeMainScreenSurface_.pop();
1484         storeMainScreenCanvas_.pop();
1485         offscreenDataList_.pop();
1486     }
1487 }
1488 
SavePCanvasList()1489 void RSPaintFilterCanvas::SavePCanvasList()
1490 {
1491     storedPCanvasList_.push_back(pCanvasList_);
1492 }
1493 
RestorePCanvasList()1494 void RSPaintFilterCanvas::RestorePCanvasList()
1495 {
1496     if (!storedPCanvasList_.empty()) {
1497         auto item = storedPCanvasList_.back();
1498         pCanvasList_.swap(item);
1499         storedPCanvasList_.pop_back();
1500     }
1501 }
1502 
SetCanvasStatus(const CanvasStatus & status)1503 void RSPaintFilterCanvas::SetCanvasStatus(const CanvasStatus& status)
1504 {
1505     SetAlpha(status.alpha_);
1506     SetMatrix(status.matrix_);
1507     SetEffectData(status.effectData_);
1508 }
1509 
GetCanvasStatus() const1510 RSPaintFilterCanvas::CanvasStatus RSPaintFilterCanvas::GetCanvasStatus() const
1511 {
1512     return { GetAlpha(), GetTotalMatrix(), GetEffectData() };
1513 }
1514 
CachedEffectData(std::shared_ptr<Drawing::Image> && image,const Drawing::RectI & rect)1515 RSPaintFilterCanvas::CachedEffectData::CachedEffectData(std::shared_ptr<Drawing::Image>&& image,
1516     const Drawing::RectI& rect)
1517     : cachedImage_(image), cachedRect_(rect), cachedMatrix_(Drawing::Matrix())
1518 {}
1519 
SetIsParallelCanvas(bool isParallel)1520 void RSPaintFilterCanvas::SetIsParallelCanvas(bool isParallel)
1521 {
1522     isParallelCanvas_ = isParallel;
1523 }
1524 
GetIsParallelCanvas() const1525 bool RSPaintFilterCanvas::GetIsParallelCanvas() const
1526 {
1527     return isParallelCanvas_;
1528 }
1529 
1530 // UNI_MAIN_THREAD_INDEX, UNI_RENDER_THREAD_INDEX, subthread 0 1 2.
SetParallelThreadIdx(uint32_t idx)1531 void RSPaintFilterCanvas::SetParallelThreadIdx(uint32_t idx)
1532 {
1533     threadIndex_ = idx;
1534 }
1535 
GetParallelThreadIdx() const1536 uint32_t RSPaintFilterCanvas::GetParallelThreadIdx() const
1537 {
1538     return threadIndex_;
1539 }
1540 
SetDisableFilterCache(bool disable)1541 void RSPaintFilterCanvas::SetDisableFilterCache(bool disable)
1542 {
1543     disableFilterCache_ = disable;
1544 }
1545 
GetDisableFilterCache() const1546 bool RSPaintFilterCanvas::GetDisableFilterCache() const
1547 {
1548     return disableFilterCache_;
1549 }
1550 
SetRecordDrawable(bool enable)1551 void RSPaintFilterCanvas::SetRecordDrawable(bool enable)
1552 {
1553     recordDrawable_ = enable;
1554 }
1555 
GetRecordDrawable() const1556 bool RSPaintFilterCanvas::GetRecordDrawable() const
1557 {
1558     return recordDrawable_;
1559 }
HasOffscreenLayer() const1560 bool RSPaintFilterCanvas::HasOffscreenLayer() const
1561 {
1562     return envStack_.top().hasOffscreenLayer_;
1563 }
SaveLayer(const Drawing::SaveLayerOps & saveLayerOps)1564 void RSPaintFilterCanvas::SaveLayer(const Drawing::SaveLayerOps& saveLayerOps)
1565 {
1566     envStack_.top().hasOffscreenLayer_ = true;
1567     RSPaintFilterCanvasBase::SaveLayer(saveLayerOps);
1568 }
1569 
IsOnMultipleScreen() const1570 bool RSPaintFilterCanvas::IsOnMultipleScreen() const
1571 {
1572     return multipleScreen_;
1573 }
SetOnMultipleScreen(bool multipleScreen)1574 void RSPaintFilterCanvas::SetOnMultipleScreen(bool multipleScreen)
1575 {
1576     multipleScreen_ = multipleScreen;
1577 }
1578 
GetScreenId() const1579 ScreenId RSPaintFilterCanvas::GetScreenId() const
1580 {
1581     return screenId_;
1582 }
1583 
SetScreenId(ScreenId screenId)1584 void RSPaintFilterCanvas::SetScreenId(ScreenId screenId)
1585 {
1586     screenId_ = screenId;
1587 }
1588 
GetHdrOn() const1589 bool RSPaintFilterCanvas::GetHdrOn() const
1590 {
1591     return isHdrOn_;
1592 }
1593 
SetHdrOn(bool isHdrOn)1594 void RSPaintFilterCanvas::SetHdrOn(bool isHdrOn)
1595 {
1596     isHdrOn_ = isHdrOn;
1597 }
1598 
GetTargetColorGamut() const1599 GraphicColorGamut RSPaintFilterCanvas::GetTargetColorGamut() const
1600 {
1601     return targetColorGamut_;
1602 }
1603 
SetTargetColorGamut(GraphicColorGamut colorGamut)1604 void RSPaintFilterCanvas::SetTargetColorGamut(GraphicColorGamut colorGamut)
1605 {
1606     targetColorGamut_ = colorGamut;
1607 }
1608 
GetBrightnessRatio() const1609 float RSPaintFilterCanvas::GetBrightnessRatio() const
1610 {
1611     return brightnessRatio_;
1612 }
1613 
SetBrightnessRatio(float brightnessRatio)1614 void RSPaintFilterCanvas::SetBrightnessRatio(float brightnessRatio)
1615 {
1616     brightnessRatio_ = brightnessRatio;
1617 }
1618 
GetIsWindowFreezeCapture() const1619 bool RSPaintFilterCanvas::GetIsWindowFreezeCapture() const
1620 {
1621     return isWindowFreezeCapture_;
1622 }
1623 
SetIsWindowFreezeCapture(bool isWindowFreezeCapture)1624 void RSPaintFilterCanvas::SetIsWindowFreezeCapture(bool isWindowFreezeCapture)
1625 {
1626     isWindowFreezeCapture_ = isWindowFreezeCapture;
1627 }
1628 } // namespace Rosen
1629 } // namespace OHOS
1630