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