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