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