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 } 33 GetTotalMatrix() const34 Drawing::Matrix RSPaintFilterCanvasBase::GetTotalMatrix() const 35 { 36 return canvas_->GetTotalMatrix(); 37 } 38 GetLocalClipBounds() const39 Drawing::Rect RSPaintFilterCanvasBase::GetLocalClipBounds() const 40 { 41 return canvas_->GetLocalClipBounds(); 42 } 43 GetDeviceClipBounds() const44 Drawing::RectI RSPaintFilterCanvasBase::GetDeviceClipBounds() const 45 { 46 return canvas_->GetDeviceClipBounds(); 47 } 48 GetRoundInDeviceClipBounds() const49 Drawing::RectI RSPaintFilterCanvasBase::GetRoundInDeviceClipBounds() const 50 { 51 return canvas_->GetRoundInDeviceClipBounds(); 52 } 53 GetSaveCount() const54 uint32_t RSPaintFilterCanvasBase::GetSaveCount() const 55 { 56 return canvas_->GetSaveCount(); 57 } 58 59 #ifdef RS_ENABLE_GPU GetGPUContext()60 std::shared_ptr<Drawing::GPUContext> RSPaintFilterCanvasBase::GetGPUContext() 61 { 62 return canvas_ != nullptr ? canvas_->GetGPUContext() : nullptr; 63 } 64 #endif 65 DrawPoint(const Point & point)66 void RSPaintFilterCanvasBase::DrawPoint(const Point& point) 67 { 68 if (canvas_ != nullptr && OnFilter()) { 69 canvas_->DrawPoint(point); 70 } 71 } 72 DrawSdf(const SDFShapeBase & shape)73 void RSPaintFilterCanvasBase::DrawSdf(const SDFShapeBase& shape) 74 { 75 if (canvas_ != nullptr && OnFilter()) { 76 canvas_->DrawSdf(shape); 77 } 78 } 79 DrawPoints(PointMode mode,size_t count,const Point pts[])80 void RSPaintFilterCanvasBase::DrawPoints(PointMode mode, size_t count, const Point pts[]) 81 { 82 if (canvas_ != nullptr && OnFilter()) { 83 canvas_->DrawPoints(mode, count, pts); 84 } 85 } 86 DrawLine(const Point & startPt,const Point & endPt)87 void RSPaintFilterCanvasBase::DrawLine(const Point& startPt, const Point& endPt) 88 { 89 if (canvas_ != nullptr && OnFilter()) { 90 canvas_->DrawLine(startPt, endPt); 91 } 92 } 93 DrawRect(const Rect & rect)94 void RSPaintFilterCanvasBase::DrawRect(const Rect& rect) 95 { 96 if (canvas_ != nullptr && OnFilter()) { 97 canvas_->DrawRect(rect); 98 } 99 } 100 DrawRoundRect(const RoundRect & roundRect)101 void RSPaintFilterCanvasBase::DrawRoundRect(const RoundRect& roundRect) 102 { 103 if (canvas_ != nullptr && OnFilter()) { 104 canvas_->DrawRoundRect(roundRect); 105 } 106 } 107 DrawNestedRoundRect(const RoundRect & outer,const RoundRect & inner)108 void RSPaintFilterCanvasBase::DrawNestedRoundRect(const RoundRect& outer, const RoundRect& inner) 109 { 110 if (canvas_ != nullptr && OnFilter()) { 111 canvas_->DrawNestedRoundRect(outer, inner); 112 } 113 } 114 DrawArc(const Rect & oval,scalar startAngle,scalar sweepAngle)115 void RSPaintFilterCanvasBase::DrawArc(const Rect& oval, scalar startAngle, scalar sweepAngle) 116 { 117 if (canvas_ != nullptr && OnFilter()) { 118 canvas_->DrawArc(oval, startAngle, sweepAngle); 119 } 120 } 121 DrawPie(const Rect & oval,scalar startAngle,scalar sweepAngle)122 void RSPaintFilterCanvasBase::DrawPie(const Rect& oval, scalar startAngle, scalar sweepAngle) 123 { 124 if (canvas_ != nullptr && OnFilter()) { 125 canvas_->DrawPie(oval, startAngle, sweepAngle); 126 } 127 } 128 DrawOval(const Rect & oval)129 void RSPaintFilterCanvasBase::DrawOval(const Rect& oval) 130 { 131 if (canvas_ != nullptr && OnFilter()) { 132 canvas_->DrawOval(oval); 133 } 134 } 135 DrawCircle(const Point & centerPt,scalar radius)136 void RSPaintFilterCanvasBase::DrawCircle(const Point& centerPt, scalar radius) 137 { 138 if (canvas_ != nullptr && OnFilter()) { 139 canvas_->DrawCircle(centerPt, radius); 140 } 141 } 142 DrawPath(const Path & path)143 void RSPaintFilterCanvasBase::DrawPath(const Path& path) 144 { 145 if (canvas_ != nullptr && OnFilter()) { 146 canvas_->DrawPath(path); 147 } 148 } 149 DrawBackground(const Brush & brush)150 void RSPaintFilterCanvasBase::DrawBackground(const Brush& brush) 151 { 152 Brush b(brush); 153 if (canvas_ != nullptr && OnFilterWithBrush(b)) { 154 canvas_->DrawBackground(b); 155 } 156 } 157 DrawShadow(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag)158 void RSPaintFilterCanvasBase::DrawShadow(const Path& path, const Point3& planeParams, const Point3& devLightPos, 159 scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag) 160 { 161 if (canvas_ != nullptr && OnFilter()) { 162 canvas_->DrawShadow(path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag); 163 } 164 } 165 DrawShadowStyle(const Path & path,const Point3 & planeParams,const Point3 & devLightPos,scalar lightRadius,Color ambientColor,Color spotColor,ShadowFlags flag,bool isLimitElevation)166 void RSPaintFilterCanvasBase::DrawShadowStyle(const Path& path, const Point3& planeParams, const Point3& devLightPos, 167 scalar lightRadius, Color ambientColor, Color spotColor, ShadowFlags flag, bool isLimitElevation) 168 { 169 if (canvas_ != nullptr && OnFilter()) { 170 canvas_->DrawShadowStyle( 171 path, planeParams, devLightPos, lightRadius, ambientColor, spotColor, flag, isLimitElevation); 172 } 173 } 174 DrawColor(Drawing::ColorQuad color,Drawing::BlendMode mode)175 void RSPaintFilterCanvasBase::DrawColor(Drawing::ColorQuad color, Drawing::BlendMode mode) 176 { 177 if (canvas_ != nullptr && OnFilter()) { 178 canvas_->DrawColor(color, mode); 179 } 180 } 181 DrawRegion(const Drawing::Region & region)182 void RSPaintFilterCanvasBase::DrawRegion(const Drawing::Region& region) 183 { 184 if (canvas_ != nullptr && OnFilter()) { 185 canvas_->DrawRegion(region); 186 } 187 } 188 DrawPatch(const Drawing::Point cubics[12],const Drawing::ColorQuad colors[4],const Drawing::Point texCoords[4],Drawing::BlendMode mode)189 void RSPaintFilterCanvasBase::DrawPatch(const Drawing::Point cubics[12], const Drawing::ColorQuad colors[4], 190 const Drawing::Point texCoords[4], Drawing::BlendMode mode) 191 { 192 if (canvas_ != nullptr && OnFilter()) { 193 canvas_->DrawPatch(cubics, colors, texCoords, mode); 194 } 195 } 196 DrawVertices(const Drawing::Vertices & vertices,Drawing::BlendMode mode)197 void RSPaintFilterCanvasBase::DrawVertices(const Drawing::Vertices& vertices, Drawing::BlendMode mode) 198 { 199 if (canvas_ != nullptr && OnFilter()) { 200 canvas_->DrawVertices(vertices, mode); 201 } 202 } 203 OpCalculateBefore(const Matrix & matrix)204 bool RSPaintFilterCanvasBase::OpCalculateBefore(const Matrix& matrix) 205 { 206 if (canvas_ != nullptr && OnFilter()) { 207 return canvas_->OpCalculateBefore(matrix); 208 } 209 return false; 210 } 211 OpCalculateAfter(const Drawing::Rect & bound)212 std::shared_ptr<Drawing::OpListHandle> RSPaintFilterCanvasBase::OpCalculateAfter(const Drawing::Rect& bound) 213 { 214 if (canvas_ != nullptr && OnFilter()) { 215 return canvas_->OpCalculateAfter(bound); 216 } 217 return nullptr; 218 } 219 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)220 void RSPaintFilterCanvasBase::DrawAtlas(const Drawing::Image* atlas, const Drawing::RSXform xform[], 221 const Drawing::Rect tex[], const Drawing::ColorQuad colors[], int count, Drawing::BlendMode mode, 222 const Drawing::SamplingOptions& sampling, const Drawing::Rect* cullRect) 223 { 224 if (canvas_ != nullptr && OnFilter()) { 225 canvas_->DrawAtlas(atlas, xform, tex, colors, count, mode, sampling, cullRect); 226 } 227 } 228 DrawBitmap(const Bitmap & bitmap,const scalar px,const scalar py)229 void RSPaintFilterCanvasBase::DrawBitmap(const Bitmap& bitmap, const scalar px, const scalar py) 230 { 231 if (canvas_ != nullptr && OnFilter()) { 232 canvas_->DrawBitmap(bitmap, px, py); 233 } 234 } 235 DrawImageNine(const Drawing::Image * image,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filter,const Drawing::Brush * brush)236 void RSPaintFilterCanvasBase::DrawImageNine(const Drawing::Image* image, const Drawing::RectI& center, 237 const Drawing::Rect& dst, Drawing::FilterMode filter, const Drawing::Brush* brush) 238 { 239 if (canvas_ != nullptr && OnFilter()) { 240 if (brush) { 241 Drawing::Brush b(*brush); 242 OnFilterWithBrush(b); 243 canvas_->DrawImageNine(image, center, dst, filter, &b); 244 } else { 245 canvas_->DrawImageNine(image, center, dst, filter, GetFilteredBrush()); 246 } 247 } 248 } 249 DrawImageLattice(const Drawing::Image * image,const Drawing::Lattice & lattice,const Drawing::Rect & dst,Drawing::FilterMode filter)250 void RSPaintFilterCanvasBase::DrawImageLattice(const Drawing::Image* image, const Drawing::Lattice& lattice, 251 const Drawing::Rect& dst, Drawing::FilterMode filter) 252 { 253 if (canvas_ != nullptr && OnFilter()) { 254 canvas_->DrawImageLattice(image, lattice, dst, filter); 255 } 256 } 257 DrawImage(const Image & image,const scalar px,const scalar py,const SamplingOptions & sampling)258 void RSPaintFilterCanvasBase::DrawImage( 259 const Image& image, const scalar px, const scalar py, const SamplingOptions& sampling) 260 { 261 if (canvas_ != nullptr && OnFilter()) { 262 canvas_->DrawImage(image, px, py, sampling); 263 } 264 } 265 DrawImageRect(const Image & image,const Rect & src,const Rect & dst,const SamplingOptions & sampling,SrcRectConstraint constraint)266 void RSPaintFilterCanvasBase::DrawImageRect(const Image& image, const Rect& src, const Rect& dst, 267 const SamplingOptions& sampling, SrcRectConstraint constraint) 268 { 269 if (canvas_ != nullptr && OnFilter()) { 270 canvas_->DrawImageRect(image, src, dst, sampling, constraint); 271 } 272 } 273 DrawImageRect(const Image & image,const Rect & dst,const SamplingOptions & sampling)274 void RSPaintFilterCanvasBase::DrawImageRect(const Image& image, const Rect& dst, const SamplingOptions& sampling) 275 { 276 if (canvas_ != nullptr && OnFilter()) { 277 canvas_->DrawImageRect(image, dst, sampling); 278 } 279 } 280 DrawPicture(const Picture & picture)281 void RSPaintFilterCanvasBase::DrawPicture(const Picture& picture) 282 { 283 if (canvas_ != nullptr && OnFilter()) { 284 canvas_->DrawPicture(picture); 285 } 286 } 287 DrawTextBlob(const Drawing::TextBlob * blob,const Drawing::scalar x,const Drawing::scalar y)288 void RSPaintFilterCanvasBase::DrawTextBlob( 289 const Drawing::TextBlob* blob, const Drawing::scalar x, const Drawing::scalar y) 290 { 291 if (canvas_ != nullptr && OnFilter()) { 292 canvas_->DrawTextBlob(blob, x, y); 293 } 294 } 295 ClipRect(const Drawing::Rect & rect,Drawing::ClipOp op,bool doAntiAlias)296 void RSPaintFilterCanvasBase::ClipRect(const Drawing::Rect& rect, Drawing::ClipOp op, bool doAntiAlias) 297 { 298 if (canvas_ != nullptr) { 299 canvas_->ClipRect(rect, op, doAntiAlias); 300 } 301 } 302 ClipIRect(const Drawing::RectI & rect,Drawing::ClipOp op)303 void RSPaintFilterCanvasBase::ClipIRect(const Drawing::RectI& rect, Drawing::ClipOp op) 304 { 305 if (canvas_ != nullptr) { 306 canvas_->ClipIRect(rect, op); 307 } 308 } 309 ClipRoundRect(const RoundRect & roundRect,ClipOp op,bool doAntiAlias)310 void RSPaintFilterCanvasBase::ClipRoundRect(const RoundRect& roundRect, ClipOp op, bool doAntiAlias) 311 { 312 if (canvas_ != nullptr) { 313 canvas_->ClipRoundRect(roundRect, op, doAntiAlias); 314 } 315 } 316 ClipRoundRect(const Drawing::Rect & rect,std::vector<Drawing::Point> & pts,bool doAntiAlias)317 void RSPaintFilterCanvasBase::ClipRoundRect(const Drawing::Rect& rect, 318 std::vector<Drawing::Point>& pts, bool doAntiAlias) 319 { 320 if (canvas_ != nullptr) { 321 canvas_->ClipRoundRect(rect, pts, doAntiAlias); 322 } 323 } 324 ClipPath(const Path & path,ClipOp op,bool doAntiAlias)325 void RSPaintFilterCanvasBase::ClipPath(const Path& path, ClipOp op, bool doAntiAlias) 326 { 327 if (canvas_ != nullptr) { 328 canvas_->ClipPath(path, op, doAntiAlias); 329 } 330 } 331 ClipRegion(const Region & region,ClipOp op)332 void RSPaintFilterCanvasBase::ClipRegion(const Region& region, ClipOp op) 333 { 334 if (canvas_ != nullptr) { 335 canvas_->ClipRegion(region, op); 336 } 337 } 338 SetMatrix(const Matrix & matrix)339 void RSPaintFilterCanvasBase::SetMatrix(const Matrix& matrix) 340 { 341 if (canvas_ != nullptr) { 342 canvas_->SetMatrix(matrix); 343 } 344 } 345 ResetMatrix()346 void RSPaintFilterCanvasBase::ResetMatrix() 347 { 348 if (canvas_ != nullptr) { 349 canvas_->ResetMatrix(); 350 } 351 } 352 ConcatMatrix(const Matrix & matrix)353 void RSPaintFilterCanvasBase::ConcatMatrix(const Matrix& matrix) 354 { 355 if (canvas_ != nullptr) { 356 canvas_->ConcatMatrix(matrix); 357 } 358 } 359 Translate(scalar dx,scalar dy)360 void RSPaintFilterCanvasBase::Translate(scalar dx, scalar dy) 361 { 362 if (canvas_ != nullptr) { 363 canvas_->Translate(dx, dy); 364 } 365 } 366 Scale(scalar sx,scalar sy)367 void RSPaintFilterCanvasBase::Scale(scalar sx, scalar sy) 368 { 369 if (canvas_ != nullptr) { 370 canvas_->Scale(sx, sy); 371 } 372 } 373 Rotate(scalar deg,scalar sx,scalar sy)374 void RSPaintFilterCanvasBase::Rotate(scalar deg, scalar sx, scalar sy) 375 { 376 if (canvas_ != nullptr) { 377 canvas_->Rotate(deg, sx, sy); 378 } 379 } 380 Shear(scalar sx,scalar sy)381 void RSPaintFilterCanvasBase::Shear(scalar sx, scalar sy) 382 { 383 if (canvas_ != nullptr) { 384 canvas_->Shear(sx, sy); 385 } 386 } 387 Flush()388 void RSPaintFilterCanvasBase::Flush() 389 { 390 if (canvas_ != nullptr) { 391 canvas_->Flush(); 392 } 393 } 394 Clear(ColorQuad color)395 void RSPaintFilterCanvasBase::Clear(ColorQuad color) 396 { 397 if (canvas_ != nullptr) { 398 canvas_->Clear(color); 399 } 400 } 401 Save()402 uint32_t RSPaintFilterCanvasBase::Save() 403 { 404 if (canvas_ != nullptr) { 405 return canvas_->Save(); 406 } 407 return 0; 408 } 409 SaveLayer(const SaveLayerOps & saveLayerRec)410 void RSPaintFilterCanvasBase::SaveLayer(const SaveLayerOps& saveLayerRec) 411 { 412 if (canvas_ == nullptr) { 413 return; 414 } 415 Brush brush; 416 if (saveLayerRec.GetBrush() != nullptr) { 417 brush = *saveLayerRec.GetBrush(); 418 OnFilterWithBrush(brush); 419 } 420 SaveLayerOps slo(saveLayerRec.GetBounds(), &brush, saveLayerRec.GetSaveLayerFlags()); 421 canvas_->SaveLayer(slo); 422 } 423 Restore()424 void RSPaintFilterCanvasBase::Restore() 425 { 426 if (canvas_ != nullptr) { 427 canvas_->Restore(); 428 } 429 } 430 Discard()431 void RSPaintFilterCanvasBase::Discard() 432 { 433 if (canvas_ != nullptr) { 434 canvas_->Discard(); 435 } 436 } 437 AttachPen(const Pen & pen)438 CoreCanvas& RSPaintFilterCanvasBase::AttachPen(const Pen& pen) 439 { 440 if (canvas_ != nullptr) { 441 canvas_->AttachPen(pen); 442 } 443 return *this; 444 } 445 AttachBrush(const Brush & brush)446 CoreCanvas& RSPaintFilterCanvasBase::AttachBrush(const Brush& brush) 447 { 448 if (canvas_ != nullptr) { 449 canvas_->AttachBrush(brush); 450 } 451 return *this; 452 } 453 AttachPaint(const Drawing::Paint & paint)454 CoreCanvas& RSPaintFilterCanvasBase::AttachPaint(const Drawing::Paint& paint) 455 { 456 if (canvas_ != nullptr) { 457 canvas_->AttachPaint(paint); 458 } 459 return *this; 460 } 461 DetachPen()462 CoreCanvas& RSPaintFilterCanvasBase::DetachPen() 463 { 464 if (canvas_ != nullptr) { 465 canvas_->DetachPen(); 466 } 467 return *this; 468 } 469 DetachBrush()470 CoreCanvas& RSPaintFilterCanvasBase::DetachBrush() 471 { 472 if (canvas_ != nullptr) { 473 canvas_->DetachBrush(); 474 } 475 return *this; 476 } 477 DetachPaint()478 CoreCanvas& RSPaintFilterCanvasBase::DetachPaint() 479 { 480 if (canvas_ != nullptr) { 481 canvas_->DetachPaint(); 482 } 483 return *this; 484 } 485 DrawBlurImage(const Drawing::Image & image,const Drawing::HpsBlurParameter & blurParams)486 bool RSPaintFilterCanvasBase::DrawBlurImage(const Drawing::Image& image, const Drawing::HpsBlurParameter& blurParams) 487 { 488 bool result = false; 489 if (canvas_ != nullptr) { 490 result = canvas_->DrawBlurImage(image, blurParams); 491 } 492 return result; 493 } 494 CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter & blurParams)495 std::array<int, 2> RSPaintFilterCanvasBase::CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter& blurParams) 496 { 497 std::array<int, 2> result = {0, 0}; // There are 2 variables 498 if (canvas_ != nullptr) { 499 result = canvas_->CalcHpsBluredImageDimension(blurParams); 500 } 501 return result; 502 } 503 RSPaintFilterCanvas(Drawing::Canvas * canvas,float alpha)504 RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha) 505 : RSPaintFilterCanvasBase(canvas), alphaStack_({ 1.0f }), 506 envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) 507 { 508 (void)alpha; // alpha is no longer used, but we keep it for backward compatibility 509 } 510 RSPaintFilterCanvas(Drawing::Surface * surface,float alpha)511 RSPaintFilterCanvas::RSPaintFilterCanvas(Drawing::Surface* surface, float alpha) 512 : RSPaintFilterCanvasBase(surface ? surface->GetCanvas().get() : nullptr), surface_(surface), alphaStack_({ 1.0f }), 513 envStack_({ Env { .envForegroundColor_ = RSColor(0xFF000000), .hasOffscreenLayer_ = false } }) 514 { 515 (void)alpha; // alpha is no longer used, but we keep it for backward compatibility 516 } 517 GetSurface() const518 Drawing::Surface* RSPaintFilterCanvas::GetSurface() const 519 { 520 return surface_; 521 } 522 AttachPen(const Pen & pen)523 CoreCanvas& RSPaintFilterCanvas::AttachPen(const Pen& pen) 524 { 525 if (canvas_ == nullptr) { 526 return *this; 527 } 528 529 Pen p(pen); 530 if (p.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification 531 p.SetColor(envStack_.top().envForegroundColor_.AsArgbInt()); 532 } 533 534 // use alphaStack_.top() to multiply alpha 535 if (alphaStack_.top() < 1 && alphaStack_.top() > 0) { 536 p.SetAlpha(p.GetAlpha() * alphaStack_.top()); 537 } 538 539 // use envStack_.top().blender_ to set blender 540 if (auto& blender = envStack_.top().blender_) { 541 if (p.GetBlenderEnabled()) { 542 p.SetBlender(blender); 543 } 544 } 545 546 canvas_->AttachPen(p); 547 return *this; 548 } 549 AttachBrush(const Brush & brush)550 CoreCanvas& RSPaintFilterCanvas::AttachBrush(const Brush& brush) 551 { 552 if (canvas_ == nullptr) { 553 return *this; 554 } 555 556 Brush b(brush); 557 if (b.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification 558 b.SetColor(envStack_.top().envForegroundColor_.AsArgbInt()); 559 } 560 561 // use alphaStack_.top() to multiply alpha 562 if (alphaStack_.top() < 1 && alphaStack_.top() > 0) { 563 b.SetAlpha(b.GetAlpha() * alphaStack_.top()); 564 } 565 566 // use envStack_.top().blender_ to set blender 567 if (auto& blender = envStack_.top().blender_) { 568 if (b.GetBlenderEnabled()) { 569 b.SetBlender(blender); 570 } 571 } 572 573 canvas_->AttachBrush(b); 574 return *this; 575 } 576 AttachPaint(const Drawing::Paint & paint)577 CoreCanvas& RSPaintFilterCanvas::AttachPaint(const Drawing::Paint& paint) 578 { 579 if (canvas_ == nullptr) { 580 return *this; 581 } 582 583 Paint p(paint); 584 if (p.GetColor() == 0x00000001) { // foreground color and foreground color strategy identification 585 p.SetColor(envStack_.top().envForegroundColor_.AsArgbInt()); 586 } 587 588 // use alphaStack_.top() to multiply alpha 589 if (alphaStack_.top() < 1 && alphaStack_.top() > 0) { 590 p.SetAlpha(p.GetAlpha() * alphaStack_.top()); 591 } 592 593 // use envStack_.top().blender_ to set blender 594 if (auto& blender = envStack_.top().blender_) { 595 if (p.GetBlenderEnabled()) { 596 p.SetBlender(blender); 597 } 598 } 599 600 canvas_->AttachPaint(p); 601 return *this; 602 } 603 OnFilter() const604 bool RSPaintFilterCanvas::OnFilter() const 605 { 606 return alphaStack_.top() > 0.f; 607 } 608 GetRecordingCanvas() const609 Drawing::Canvas* RSPaintFilterCanvas::GetRecordingCanvas() const 610 { 611 return recordingState_ ? canvas_ : nullptr; 612 } 613 GetRecordingState() const614 bool RSPaintFilterCanvas::GetRecordingState() const 615 { 616 return recordingState_; 617 } 618 SetRecordingState(bool flag)619 void RSPaintFilterCanvas::SetRecordingState(bool flag) 620 { 621 recordingState_ = flag; 622 } 623 MultiplyAlpha(float alpha)624 void RSPaintFilterCanvas::MultiplyAlpha(float alpha) 625 { 626 // multiply alpha to top of stack 627 alphaStack_.top() *= std::clamp(alpha, 0.f, 1.f); 628 } 629 SetAlpha(float alpha)630 void RSPaintFilterCanvas::SetAlpha(float alpha) 631 { 632 alphaStack_.top() = std::clamp(alpha, 0.f, 1.f); 633 } 634 SaveAlpha()635 int RSPaintFilterCanvas::SaveAlpha() 636 { 637 // make a copy of top of stack 638 alphaStack_.push(alphaStack_.top()); 639 // return prev stack height 640 return alphaStack_.size() - 1; 641 } 642 GetAlpha() const643 float RSPaintFilterCanvas::GetAlpha() const 644 { 645 // return top of stack 646 return alphaStack_.top(); 647 } 648 RestoreAlpha()649 void RSPaintFilterCanvas::RestoreAlpha() 650 { 651 // sanity check, stack should not be empty 652 if (alphaStack_.size() <= 1u) { 653 return; 654 } 655 alphaStack_.pop(); 656 } 657 GetAlphaSaveCount() const658 int RSPaintFilterCanvas::GetAlphaSaveCount() const 659 { 660 return alphaStack_.size(); 661 } 662 RestoreAlphaToCount(int count)663 void RSPaintFilterCanvas::RestoreAlphaToCount(int count) 664 { 665 // sanity check, stack should not be empty 666 if (count < 1) { 667 count = 1; 668 } 669 // poo stack until stack height equals count 670 int n = static_cast<int>(alphaStack_.size()) - count; 671 for (int i = 0; i < n; ++i) { 672 alphaStack_.pop(); 673 } 674 } 675 SetBlendMode(std::optional<int> blendMode)676 void RSPaintFilterCanvas::SetBlendMode(std::optional<int> blendMode) 677 { 678 std::shared_ptr<Drawing::Blender> blender = nullptr; 679 if (blendMode) { 680 // map blendMode to Drawing::BlendMode and convert to Blender 681 blender = Drawing::Blender::CreateWithBlendMode(static_cast<Drawing::BlendMode>(*blendMode)); 682 } 683 RSPaintFilterCanvas::SetBlender(blender); 684 } 685 SetBlender(std::shared_ptr<Drawing::Blender> blender)686 void RSPaintFilterCanvas::SetBlender(std::shared_ptr<Drawing::Blender> blender) 687 { 688 envStack_.top().blender_ = blender; 689 } 690 SaveEnv()691 int RSPaintFilterCanvas::SaveEnv() 692 { 693 // make a copy of top of stack 694 envStack_.push(envStack_.top()); 695 // return prev stack height 696 return envStack_.size() - 1; 697 } 698 RestoreEnv()699 void RSPaintFilterCanvas::RestoreEnv() 700 { 701 // sanity check, stack should not be empty 702 if (envStack_.size() <= 1) { 703 return; 704 } 705 envStack_.pop(); 706 } 707 RestoreEnvToCount(int count)708 void RSPaintFilterCanvas::RestoreEnvToCount(int count) 709 { 710 // sanity check, stack should not be empty 711 if (count < 1) { 712 count = 1; 713 } 714 // poo stack until stack height equals count 715 int n = static_cast<int>(envStack_.size()) - count; 716 for (int i = 0; i < n; ++i) { 717 envStack_.pop(); 718 } 719 } 720 GetEnvSaveCount() const721 int RSPaintFilterCanvas::GetEnvSaveCount() const 722 { 723 return envStack_.size(); 724 } 725 SetEnvForegroundColor(Rosen::RSColor color)726 void RSPaintFilterCanvas::SetEnvForegroundColor(Rosen::RSColor color) 727 { 728 // sanity check, stack should not be empty 729 if (envStack_.empty()) { 730 return; 731 } 732 envStack_.top().envForegroundColor_ = color; 733 } 734 GetEnvForegroundColor() const735 Drawing::ColorQuad RSPaintFilterCanvas::GetEnvForegroundColor() const 736 { 737 // sanity check, stack should not be empty 738 if (envStack_.empty()) { 739 return Drawing::Color::COLOR_BLACK; // 0xFF000000 is default value -- black 740 } 741 return envStack_.top().envForegroundColor_.AsArgbInt(); 742 } 743 SaveAllStatus(SaveType type)744 RSPaintFilterCanvas::SaveStatus RSPaintFilterCanvas::SaveAllStatus(SaveType type) 745 { 746 // save and return status on demand 747 return { (RSPaintFilterCanvas::kCanvas & type) ? Save() : GetSaveCount(), 748 (RSPaintFilterCanvas::kAlpha & type) ? SaveAlpha() : GetAlphaSaveCount(), 749 (RSPaintFilterCanvas::kEnv & type) ? SaveEnv() : GetEnvSaveCount() }; 750 } 751 GetSaveStatus() const752 RSPaintFilterCanvas::SaveStatus RSPaintFilterCanvas::GetSaveStatus() const 753 { 754 return { GetSaveCount(), GetAlphaSaveCount(), GetEnvSaveCount() }; 755 } 756 RestoreStatus(const SaveStatus & status)757 void RSPaintFilterCanvas::RestoreStatus(const SaveStatus& status) 758 { 759 // simultaneously restore canvas and alpha 760 RestoreToCount(status.canvasSaveCount); 761 RestoreAlphaToCount(status.alphaSaveCount); 762 RestoreEnvToCount(status.envSaveCount); 763 } 764 PushDirtyRegion(Drawing::Region & resultRegion)765 void RSPaintFilterCanvas::PushDirtyRegion(Drawing::Region& resultRegion) 766 { 767 dirtyRegionStack_.push(std::move(resultRegion)); 768 } 769 PopDirtyRegion()770 void RSPaintFilterCanvas::PopDirtyRegion() 771 { 772 if (dirtyRegionStack_.empty()) { 773 RS_LOGW("PopDirtyRegion dirtyRegionStack_ is empty"); 774 return; 775 } 776 dirtyRegionStack_.pop(); 777 } 778 GetCurDirtyRegion()779 Drawing::Region& RSPaintFilterCanvas::GetCurDirtyRegion() 780 { 781 return dirtyRegionStack_.top(); 782 } 783 IsDirtyRegionStackEmpty()784 bool RSPaintFilterCanvas::IsDirtyRegionStackEmpty() 785 { 786 return dirtyRegionStack_.empty(); 787 } 788 CopyHDRConfiguration(const RSPaintFilterCanvas & other)789 void RSPaintFilterCanvas::CopyHDRConfiguration(const RSPaintFilterCanvas& other) 790 { 791 brightnessRatio_ = other.brightnessRatio_; 792 screenId_ = other.screenId_; 793 targetColorGamut_ = other.targetColorGamut_; 794 } 795 CopyConfigurationToOffscreenCanvas(const RSPaintFilterCanvas & other)796 void RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas(const RSPaintFilterCanvas& other) 797 { 798 // Note: 799 // 1. we don't need to copy alpha status, alpha will be applied when drawing cache. 800 // 2. This function should only be called when creating offscreen canvas. 801 // copy high contrast flag 802 isHighContrastEnabled_.store(other.isHighContrastEnabled_.load()); 803 // copy env 804 envStack_.top() = other.envStack_.top(); 805 // update effect matrix 806 auto effectData = other.envStack_.top().effectData_; 807 if (effectData != nullptr) { 808 // make a deep copy of effect data, and calculate the mapping matrix from 809 // local coordinate system to global coordinate system. 810 auto copiedEffectData = std::make_shared<CachedEffectData>(*effectData); 811 if (copiedEffectData == nullptr) { 812 ROSEN_LOGE("RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas fail to create effectData"); 813 return; 814 } 815 Drawing::Matrix inverse; 816 if (other.GetTotalMatrix().Invert(inverse)) { 817 copiedEffectData->cachedMatrix_.PostConcat(inverse); 818 } else { 819 ROSEN_LOGE("RSPaintFilterCanvas::CopyConfigurationToOffscreenCanvas get invert matrix failed!"); 820 } 821 envStack_.top().effectData_ = copiedEffectData; 822 } 823 // cache related 824 if (other.isHighContrastEnabled()) { 825 // explicit disable cache for high contrast mode 826 SetCacheType(RSPaintFilterCanvas::CacheType::DISABLED); 827 } else { 828 // planning: maybe we should copy source cache status 829 SetCacheType(other.GetCacheType()); 830 } 831 isParallelCanvas_ = other.isParallelCanvas_; 832 disableFilterCache_ = other.disableFilterCache_; 833 threadIndex_ = other.threadIndex_; 834 } 835 SetHighContrast(bool enabled)836 void RSPaintFilterCanvas::SetHighContrast(bool enabled) 837 { 838 isHighContrastEnabled_ = enabled; 839 } isHighContrastEnabled() const840 bool RSPaintFilterCanvas::isHighContrastEnabled() const 841 { 842 return isHighContrastEnabled_; 843 } 844 SetCacheType(CacheType type)845 void RSPaintFilterCanvas::SetCacheType(CacheType type) 846 { 847 cacheType_ = type; 848 } GetCacheType() const849 Drawing::CacheType RSPaintFilterCanvas::GetCacheType() const 850 { 851 return cacheType_; 852 } 853 SetVisibleRect(Drawing::Rect visibleRect)854 void RSPaintFilterCanvas::SetVisibleRect(Drawing::Rect visibleRect) 855 { 856 visibleRect_ = visibleRect; 857 } 858 GetVisibleRect() const859 Drawing::Rect RSPaintFilterCanvas::GetVisibleRect() const 860 { 861 return visibleRect_; 862 } 863 GetLocalClipBounds(const Drawing::Canvas & canvas,const Drawing::RectI * clipRect)864 std::optional<Drawing::Rect> RSPaintFilterCanvas::GetLocalClipBounds(const Drawing::Canvas& canvas, 865 const Drawing::RectI* clipRect) 866 { 867 // if clipRect is explicitly specified, use it as the device clip bounds 868 Drawing::Rect bounds = Rect((clipRect != nullptr) ? *clipRect : canvas.GetDeviceClipBounds()); 869 870 if (!bounds.IsValid()) { 871 return std::nullopt; 872 } 873 874 Drawing::Matrix inverse; 875 // if we can't invert the CTM, we can't return local clip bounds 876 if (!(canvas.GetTotalMatrix().Invert(inverse))) { 877 return std::nullopt; 878 } 879 // return the inverse of the CTM applied to the device clip bounds as local clip bounds 880 Drawing::Rect dst; 881 inverse.MapRect(dst, bounds); 882 return dst; 883 } 884 885 SetEffectData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData> & effectData)886 void RSPaintFilterCanvas::SetEffectData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& effectData) 887 { 888 envStack_.top().effectData_ = effectData; 889 } 890 GetEffectData() const891 const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& RSPaintFilterCanvas::GetEffectData() const 892 { 893 return envStack_.top().effectData_; 894 } 895 SetBehindWindowData(const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData> & behindWindowData)896 void RSPaintFilterCanvas::SetBehindWindowData( 897 const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& behindWindowData) 898 { 899 envStack_.top().behindWindowData_ = behindWindowData; 900 } 901 GetBehindWindowData() const902 const std::shared_ptr<RSPaintFilterCanvas::CachedEffectData>& RSPaintFilterCanvas::GetBehindWindowData() const 903 { 904 return envStack_.top().behindWindowData_; 905 } 906 ReplaceMainScreenData(std::shared_ptr<Drawing::Surface> & offscreenSurface,std::shared_ptr<RSPaintFilterCanvas> & offscreenCanvas)907 void RSPaintFilterCanvas::ReplaceMainScreenData(std::shared_ptr<Drawing::Surface>& offscreenSurface, 908 std::shared_ptr<RSPaintFilterCanvas>& offscreenCanvas) 909 { 910 if (offscreenSurface != nullptr && offscreenCanvas != nullptr) { 911 storeMainScreenSurface_.push(surface_); 912 storeMainScreenCanvas_.push(canvas_); 913 surface_ = offscreenSurface.get(); 914 canvas_ = offscreenCanvas.get(); 915 OffscreenData offscreenData = {offscreenSurface, offscreenCanvas}; 916 offscreenDataList_.push(offscreenData); 917 } 918 } 919 SwapBackMainScreenData()920 void RSPaintFilterCanvas::SwapBackMainScreenData() 921 { 922 if (!storeMainScreenSurface_.empty() && !storeMainScreenCanvas_.empty() && !offscreenDataList_.empty()) { 923 surface_ = storeMainScreenSurface_.top(); 924 canvas_ = storeMainScreenCanvas_.top(); 925 storeMainScreenSurface_.pop(); 926 storeMainScreenCanvas_.pop(); 927 offscreenDataList_.pop(); 928 } 929 } 930 SavePCanvasList()931 void RSPaintFilterCanvas::SavePCanvasList() 932 { 933 storedPCanvasList_.push_back(pCanvasList_); 934 } 935 RestorePCanvasList()936 void RSPaintFilterCanvas::RestorePCanvasList() 937 { 938 if (!storedPCanvasList_.empty()) { 939 auto item = storedPCanvasList_.back(); 940 pCanvasList_.swap(item); 941 storedPCanvasList_.pop_back(); 942 } 943 } 944 SetCanvasStatus(const CanvasStatus & status)945 void RSPaintFilterCanvas::SetCanvasStatus(const CanvasStatus& status) 946 { 947 SetAlpha(status.alpha_); 948 SetMatrix(status.matrix_); 949 SetEffectData(status.effectData_); 950 } 951 GetCanvasStatus() const952 RSPaintFilterCanvas::CanvasStatus RSPaintFilterCanvas::GetCanvasStatus() const 953 { 954 return { GetAlpha(), GetTotalMatrix(), GetEffectData() }; 955 } 956 CachedEffectData(std::shared_ptr<Drawing::Image> && image,const Drawing::RectI & rect)957 RSPaintFilterCanvas::CachedEffectData::CachedEffectData(std::shared_ptr<Drawing::Image>&& image, 958 const Drawing::RectI& rect) 959 : cachedImage_(image), cachedRect_(rect), cachedMatrix_(Drawing::Matrix()) 960 {} 961 SetIsParallelCanvas(bool isParallel)962 void RSPaintFilterCanvas::SetIsParallelCanvas(bool isParallel) 963 { 964 isParallelCanvas_ = isParallel; 965 } 966 GetIsParallelCanvas() const967 bool RSPaintFilterCanvas::GetIsParallelCanvas() const 968 { 969 return isParallelCanvas_; 970 } 971 972 // UNI_MAIN_THREAD_INDEX, UNI_RENDER_THREAD_INDEX, subthread 0 1 2. SetParallelThreadIdx(uint32_t idx)973 void RSPaintFilterCanvas::SetParallelThreadIdx(uint32_t idx) 974 { 975 threadIndex_ = idx; 976 } 977 GetParallelThreadIdx() const978 uint32_t RSPaintFilterCanvas::GetParallelThreadIdx() const 979 { 980 return threadIndex_; 981 } 982 SetDisableFilterCache(bool disable)983 void RSPaintFilterCanvas::SetDisableFilterCache(bool disable) 984 { 985 disableFilterCache_ = disable; 986 } 987 GetDisableFilterCache() const988 bool RSPaintFilterCanvas::GetDisableFilterCache() const 989 { 990 return disableFilterCache_; 991 } 992 SetRecordDrawable(bool enable)993 void RSPaintFilterCanvas::SetRecordDrawable(bool enable) 994 { 995 recordDrawable_ = enable; 996 } 997 GetRecordDrawable() const998 bool RSPaintFilterCanvas::GetRecordDrawable() const 999 { 1000 return recordDrawable_; 1001 } HasOffscreenLayer() const1002 bool RSPaintFilterCanvas::HasOffscreenLayer() const 1003 { 1004 return envStack_.top().hasOffscreenLayer_; 1005 } SaveLayer(const Drawing::SaveLayerOps & saveLayerOps)1006 void RSPaintFilterCanvas::SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) 1007 { 1008 envStack_.top().hasOffscreenLayer_ = true; 1009 RSPaintFilterCanvasBase::SaveLayer(saveLayerOps); 1010 } 1011 IsCapture() const1012 bool RSPaintFilterCanvas::IsCapture() const 1013 { 1014 return isCapture_; 1015 } SetCapture(bool isCapture)1016 void RSPaintFilterCanvas::SetCapture(bool isCapture) 1017 { 1018 isCapture_ = isCapture; 1019 } 1020 GetScreenId() const1021 ScreenId RSPaintFilterCanvas::GetScreenId() const 1022 { 1023 return screenId_; 1024 } 1025 SetScreenId(ScreenId screenId)1026 void RSPaintFilterCanvas::SetScreenId(ScreenId screenId) 1027 { 1028 screenId_ = screenId; 1029 } 1030 GetTargetColorGamut() const1031 GraphicColorGamut RSPaintFilterCanvas::GetTargetColorGamut() const 1032 { 1033 return targetColorGamut_; 1034 } 1035 SetTargetColorGamut(GraphicColorGamut colorGamut)1036 void RSPaintFilterCanvas::SetTargetColorGamut(GraphicColorGamut colorGamut) 1037 { 1038 targetColorGamut_ = colorGamut; 1039 } 1040 GetBrightnessRatio() const1041 float RSPaintFilterCanvas::GetBrightnessRatio() const 1042 { 1043 return brightnessRatio_; 1044 } 1045 SetBrightnessRatio(float brightnessRatio)1046 void RSPaintFilterCanvas::SetBrightnessRatio(float brightnessRatio) 1047 { 1048 brightnessRatio_ = brightnessRatio; 1049 } 1050 } // namespace Rosen 1051 } // namespace OHOS 1052