1 /* 2 * Copyright (c) 2021-2023 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 #ifndef RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_PAINT_FILTER_CANVAS_H 17 #define RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_PAINT_FILTER_CANVAS_H 18 19 #include <optional> 20 #include <stack> 21 #include <vector> 22 23 #include "draw/canvas.h" 24 #include "draw/surface.h" 25 26 #include "common/rs_color.h" 27 #include "common/rs_macros.h" 28 #include "screen_manager/screen_types.h" 29 #include "surface_type.h" 30 #include "utils/region.h" 31 32 namespace OHOS { 33 namespace Rosen { 34 35 class RSB_EXPORT RSPaintFilterCanvasBase : public Drawing::Canvas { 36 public: 37 RSPaintFilterCanvasBase(Drawing::Canvas* canvas); 38 ~RSPaintFilterCanvasBase() override = default; 39 40 Drawing::Matrix GetTotalMatrix() const override; 41 42 Drawing::Rect GetLocalClipBounds() const override; 43 44 Drawing::RectI GetDeviceClipBounds() const override; 45 46 Drawing::RectI GetRoundInDeviceClipBounds() const override; 47 48 uint32_t GetSaveCount() const override; 49 50 #ifdef RS_ENABLE_GPU 51 std::shared_ptr<Drawing::GPUContext> GetGPUContext() override; 52 #endif 53 54 void DrawSdf(const Drawing::SDFShapeBase& shape) override; 55 void DrawPoint(const Drawing::Point& point) override; 56 void DrawPoints(Drawing::PointMode mode, size_t count, const Drawing::Point pts[]) override; 57 void DrawLine(const Drawing::Point& startPt, const Drawing::Point& endPt) override; 58 void DrawRect(const Drawing::Rect& rect) override; 59 void DrawRoundRect(const Drawing::RoundRect& roundRect) override; 60 void DrawNestedRoundRect(const Drawing::RoundRect& outer, const Drawing::RoundRect& inner) override; 61 void DrawArc(const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle) override; 62 void DrawPie(const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle) override; 63 void DrawOval(const Drawing::Rect& oval) override; 64 void DrawCircle(const Drawing::Point& centerPt, Drawing::scalar radius) override; 65 void DrawPath(const Drawing::Path& path) override; 66 void DrawPathWithStencil(const Drawing::Path& path, uint32_t stencilVal) override; 67 void DrawBackground(const Drawing::Brush& brush) override; 68 void DrawShadow(const Drawing::Path& path, const Drawing::Point3& planeParams, 69 const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, 70 Drawing::Color ambientColor, Drawing::Color spotColor, Drawing::ShadowFlags flag) override; 71 void DrawShadowStyle(const Drawing::Path& path, const Drawing::Point3& planeParams, 72 const Drawing::Point3& devLightPos, Drawing::scalar lightRadius, 73 Drawing::Color ambientColor, Drawing::Color spotColor, Drawing::ShadowFlags flag, 74 bool isLimitElevation) override; 75 void DrawColor(Drawing::ColorQuad color, Drawing::BlendMode mode = Drawing::BlendMode::SRC_OVER) override; 76 void DrawRegion(const Drawing::Region& region) override; 77 void DrawPatch(const Drawing::Point cubics[12], const Drawing::ColorQuad colors[4], 78 const Drawing::Point texCoords[4], Drawing::BlendMode mode) override; 79 void DrawVertices(const Drawing::Vertices& vertices, Drawing::BlendMode mode) override; 80 81 void DrawImageNine(const Drawing::Image* image, const Drawing::RectI& center, const Drawing::Rect& dst, 82 Drawing::FilterMode filter, const Drawing::Brush* brush = nullptr) override; 83 void DrawImageLattice(const Drawing::Image* image, const Drawing::Lattice& lattice, const Drawing::Rect& dst, 84 Drawing::FilterMode filter) override; 85 86 bool OpCalculateBefore(const Drawing::Matrix& matrix) override; 87 std::shared_ptr<Drawing::OpListHandle> OpCalculateAfter(const Drawing::Rect& bound) override; 88 89 void DrawAtlas(const Drawing::Image* atlas, const Drawing::RSXform xform[], const Drawing::Rect tex[], 90 const Drawing::ColorQuad colors[], int count, Drawing::BlendMode mode, 91 const Drawing::SamplingOptions& sampling, const Drawing::Rect* cullRect) override; 92 void DrawBitmap(const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py) override; 93 void DrawImage(const Drawing::Image& image, 94 const Drawing::scalar px, const Drawing::scalar py, const Drawing::SamplingOptions& sampling) override; 95 void DrawImageWithStencil(const Drawing::Image& image, const Drawing::scalar px, const Drawing::scalar py, 96 const Drawing::SamplingOptions& sampling, uint32_t stencilVal) override; 97 void DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src, const Drawing::Rect& dst, 98 const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint) override; 99 void DrawImageRect(const Drawing::Image& image, 100 const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling) override; 101 void DrawPicture(const Drawing::Picture& picture) override; 102 void DrawTextBlob(const Drawing::TextBlob* blob, const Drawing::scalar x, const Drawing::scalar y) override; 103 104 void ClearStencil(const Drawing::RectI& rect, uint32_t stencilVal) override; 105 void ClipRect(const Drawing::Rect& rect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT, 106 bool doAntiAlias = false) override; 107 void ClipIRect(const Drawing::RectI& rect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT) override; 108 void ClipRoundRect(const Drawing::RoundRect& roundRect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT, 109 bool doAntiAlias = false) override; 110 void ClipRoundRect(const Drawing::Rect& rect, std::vector<Drawing::Point>& pts, bool doAntiAlias = false) override; 111 void ClipPath(const Drawing::Path& path, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT, 112 bool doAntiAlias = false) override; 113 void ClipRegion(const Drawing::Region& region, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT) override; 114 void ResetClip() override; 115 116 void SetMatrix(const Drawing::Matrix& matrix) override; 117 void ResetMatrix() override; 118 void ConcatMatrix(const Drawing::Matrix& matrix) override; 119 void Translate(Drawing::scalar dx, Drawing::scalar dy) override; 120 void Scale(Drawing::scalar sx, Drawing::scalar sy) override; 121 void Rotate(Drawing::scalar deg, Drawing::scalar sx, Drawing::scalar sy) override; 122 void Shear(Drawing::scalar sx, Drawing::scalar sy) override; 123 124 void Flush() override; 125 void Clear(Drawing::ColorQuad color) override; 126 uint32_t Save() override; 127 void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override; 128 void Restore() override; 129 void Discard() override; 130 131 CoreCanvas& AttachPen(const Drawing::Pen& pen) override; 132 CoreCanvas& AttachBrush(const Drawing::Brush& brush) override; 133 CoreCanvas& AttachPaint(const Drawing::Paint& paint) override; 134 CoreCanvas& DetachPen() override; 135 CoreCanvas& DetachBrush() override; 136 CoreCanvas& DetachPaint() override; 137 138 bool DrawBlurImage(const Drawing::Image& image, const Drawing::HpsBlurParameter& blurParams) override; 139 std::array<int, 2> CalcHpsBluredImageDimension(const Drawing::HpsBlurParameter& blurParams) override; 140 141 bool IsClipRect() override; 142 143 protected: 144 virtual bool OnFilter() const = 0; 145 virtual bool OnFilterWithBrush(Drawing::Brush& brush) const = 0; 146 virtual Drawing::Brush* GetFilteredBrush() const = 0; 147 Drawing::Canvas* canvas_ = nullptr; 148 }; 149 150 // This class is used to filter the paint before drawing. currently, it is used to filter the alpha and foreground 151 // color. 152 class RSB_EXPORT RSPaintFilterCanvas : public RSPaintFilterCanvasBase { 153 public: 154 RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha = 1.0f); 155 RSPaintFilterCanvas(Drawing::Surface* surface, float alpha = 1.0f); 156 ~RSPaintFilterCanvas() override = default;; 157 158 void CopyConfigurationToOffscreenCanvas(const RSPaintFilterCanvas& other); 159 void PushDirtyRegion(Drawing::Region& resultRegion); 160 void PopDirtyRegion(); 161 bool IsDirtyRegionStackEmpty(); 162 Drawing::Region& GetCurDirtyRegion(); 163 164 // alpha related 165 void MultiplyAlpha(float alpha); 166 void SetAlpha(float alpha); 167 float GetAlpha() const override; 168 int SaveAlpha(); 169 void RestoreAlpha(); 170 int GetAlphaSaveCount() const override; 171 void RestoreAlphaToCount(int count); 172 173 // env related 174 void SetEnvForegroundColor(Color color); 175 Drawing::ColorQuad GetEnvForegroundColor() const override; 176 int SaveEnv(); 177 void RestoreEnv(); 178 int GetEnvSaveCount() const; 179 void RestoreEnvToCount(int count); 180 181 // blendmode and blender related 182 void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override; 183 void SetBlendMode(std::optional<int> blendMode); 184 void SetBlender(std::shared_ptr<Drawing::Blender>); 185 bool HasOffscreenLayer() const; 186 187 // save/restore utils 188 struct SaveStatus { 189 int canvasSaveCount = -1; 190 int alphaSaveCount = -1; 191 int envSaveCount = -1; 192 }; 193 enum SaveType : uint8_t { 194 kNone = 0x0, 195 kCanvas = 0x1, 196 kAlpha = 0x2, 197 kEnv = 0x4, 198 kCanvasAndAlpha = kCanvas | kAlpha, 199 kAll = kCanvas | kAlpha | kEnv, 200 }; 201 202 SaveStatus SaveAllStatus(SaveType type = kAll); 203 SaveStatus GetSaveStatus() const; 204 void RestoreStatus(const SaveStatus& status); 205 206 Drawing::Surface* GetSurface() const override; 207 208 // high contrast 209 void SetHighContrast(bool enabled); 210 bool isHighContrastEnabled() const override; 211 212 using CacheType = Drawing::CacheType; 213 // cache 214 void SetCacheType(CacheType type); 215 Drawing::CacheType GetCacheType() const override; 216 217 // visible rect 218 void SetVisibleRect(Drawing::Rect visibleRect); 219 Drawing::Rect GetVisibleRect() const; 220 221 static std::optional<Drawing::Rect> GetLocalClipBounds(const Drawing::Canvas& canvas, 222 const Drawing::RectI* clipBounds = nullptr); 223 224 CoreCanvas& AttachPen(const Drawing::Pen& pen) override; 225 CoreCanvas& AttachBrush(const Drawing::Brush& brush) override; 226 CoreCanvas& AttachPaint(const Drawing::Paint& paint) override; 227 228 void SetParallelThreadIdx(uint32_t idx); 229 uint32_t GetParallelThreadIdx() const; 230 void SetIsParallelCanvas(bool isParallel); 231 bool GetIsParallelCanvas() const; 232 233 void SetDisableFilterCache(bool disable); 234 bool GetDisableFilterCache() const; 235 236 void SetRecordDrawable(bool enable); 237 bool GetRecordDrawable() const; 238 239 // effect cache data relate 240 struct CachedEffectData { 241 CachedEffectData() = default; 242 CachedEffectData(std::shared_ptr<Drawing::Image>&& image, const Drawing::RectI& rect); 243 ~CachedEffectData() = default; 244 std::shared_ptr<Drawing::Image> cachedImage_ = nullptr; 245 Drawing::RectI cachedRect_ = {}; 246 Drawing::Matrix cachedMatrix_ = Drawing::Matrix(); 247 }; 248 void SetEffectData(const std::shared_ptr<CachedEffectData>& effectData); 249 const std::shared_ptr<CachedEffectData>& GetEffectData() const; 250 // behind window cache relate 251 void SetBehindWindowData(const std::shared_ptr<CachedEffectData>& behindWindowData); 252 const std::shared_ptr<CachedEffectData>& GetBehindWindowData() const; 253 254 // for foregroundFilter to store offscreen canvas & surface 255 struct OffscreenData { 256 std::shared_ptr<Drawing::Surface> offscreenSurface_ = nullptr; 257 std::shared_ptr<RSPaintFilterCanvas> offscreenCanvas_ = nullptr; 258 }; 259 // for foregroundFilter to store and restore offscreen canvas & surface 260 void ReplaceMainScreenData(std::shared_ptr<Drawing::Surface>& offscreenSurface, 261 std::shared_ptr<RSPaintFilterCanvas>& offscreenCanvas); 262 void SwapBackMainScreenData(); 263 void SavePCanvasList(); 264 void RestorePCanvasList(); 265 266 // canvas status relate 267 struct CanvasStatus { 268 float alpha_; 269 Drawing::Matrix matrix_; 270 std::shared_ptr<CachedEffectData> effectData_; 271 }; 272 CanvasStatus GetCanvasStatus() const; 273 void SetCanvasStatus(const CanvasStatus& status); 274 Drawing::Canvas* GetRecordingCanvas() const override; 275 bool GetRecordingState() const override; 276 void SetRecordingState(bool flag) override; 277 GetOffscreenDataList()278 const std::stack<OffscreenData>& GetOffscreenDataList() const 279 { 280 return offscreenDataList_; 281 } 282 StoreCanvas()283 void StoreCanvas() 284 { 285 if (storeMainCanvas_ == nullptr) { 286 storeMainCanvas_ = canvas_; 287 } 288 } 289 GetOriginalCanvas()290 Drawing::Canvas* GetOriginalCanvas() 291 { 292 return storeMainCanvas_; 293 } 294 GetDrawingType()295 Drawing::DrawingType GetDrawingType() const override 296 { 297 return Drawing::DrawingType::PAINT_FILTER; 298 } 299 bool IsOnMultipleScreen() const; 300 void SetOnMultipleScreen(bool multipleScreen); 301 ScreenId GetScreenId() const; 302 void SetScreenId(ScreenId screenId); 303 GraphicColorGamut GetTargetColorGamut() const; 304 void SetTargetColorGamut(GraphicColorGamut colorGamut); 305 float GetBrightnessRatio() const; 306 void SetBrightnessRatio(float brightnessRatio); 307 void CopyHDRConfiguration(const RSPaintFilterCanvas& other); 308 bool GetHdrOn() const; 309 void SetHdrOn(bool isHdrOn); 310 bool GetIsWindowFreezeCapture() const; 311 void SetIsWindowFreezeCapture(bool isWindowFreezeCapture); 312 313 protected: 314 using Env = struct { 315 Color envForegroundColor_; 316 std::shared_ptr<CachedEffectData> effectData_; 317 std::shared_ptr<CachedEffectData> behindWindowData_; 318 std::shared_ptr<Drawing::Blender> blender_; 319 bool hasOffscreenLayer_; 320 }; 321 322 bool OnFilter() const override; OnFilterWithBrush(Drawing::Brush & brush)323 inline bool OnFilterWithBrush(Drawing::Brush& brush) const override 324 { 325 float alpha = alphaStack_.top(); 326 // foreground color and foreground color strategy identification 327 if (brush.GetColor().CastToColorQuad() == 0x00000001) { 328 brush.SetColor(envStack_.top().envForegroundColor_.AsArgbInt()); 329 } 330 331 // use alphaStack_.top() to multiply alpha 332 if (alpha < 1 && alpha > 0) { 333 brush.SetAlpha(brush.GetAlpha() * alpha); 334 } 335 return alpha > 0.f; 336 } GetFilteredBrush()337 inline Drawing::Brush* GetFilteredBrush() const override 338 { 339 static Drawing::Brush brush; 340 float alpha = alphaStack_.top(); 341 if (alpha >= 1) { 342 return nullptr; 343 } 344 brush.SetAlphaF(alpha); 345 return &brush; 346 } 347 348 private: 349 bool isParallelCanvas_ = false; 350 bool disableFilterCache_ = false; 351 bool recordingState_ = false; 352 bool recordDrawable_ = false; 353 bool multipleScreen_ = false; 354 bool isHdrOn_ = false; 355 bool isWindowFreezeCapture_ = false; 356 CacheType cacheType_ { RSPaintFilterCanvas::CacheType::UNDEFINED }; 357 std::atomic_bool isHighContrastEnabled_ { false }; 358 GraphicColorGamut targetColorGamut_ = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB; 359 float brightnessRatio_ = 1.0f; // Default 1.0f means no discount 360 ScreenId screenId_ = INVALID_SCREEN_ID; 361 uint32_t threadIndex_ = UNI_RENDER_THREAD_INDEX; // default 362 Drawing::Surface* surface_ = nullptr; 363 Drawing::Canvas* storeMainCanvas_ = nullptr; // store main canvas 364 Drawing::Rect visibleRect_ = Drawing::Rect(); 365 366 std::stack<float> alphaStack_; 367 std::stack<Env> envStack_; 368 369 // save every dirty region of the current surface for quick reject 370 std::stack<Drawing::Region> dirtyRegionStack_; 371 372 // greater than 0 indicates canvas currently is drawing on a new layer created offscreen blendmode 373 // std::stack<bool> blendOffscreenStack_; 374 375 // foregroundFilter related 376 std::vector<std::vector<Canvas*>> storedPCanvasList_; // store pCanvasList_ 377 std::stack<OffscreenData> offscreenDataList_; // store offscreen canvas & surface 378 std::stack<Drawing::Surface*> storeMainScreenSurface_; // store surface_ 379 std::stack<Drawing::Canvas*> storeMainScreenCanvas_; // store canvas_ 380 }; 381 382 // Helper class similar to SkAutoCanvasRestore, but also restores alpha and/or env 383 class RSB_EXPORT RSAutoCanvasRestore { 384 public: 385 /** Preserves canvas save count. Optionally call SkCanvas::save() and/or RSPaintFilterCanvas::SaveAlpha() and/or 386 RSPaintFilterCanvas::SaveEnv(). 387 @param canvas RSPaintFilterCanvas to guard 388 @param saveCanvas call SkCanvas::save() 389 @param saveAlpha call RSPaintFilterCanvas::SaveAlpha() 390 @return utility to restore RSPaintFilterCanvas state on destructor 391 */ 392 RSAutoCanvasRestore( 393 RSPaintFilterCanvas* canvas, RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll) canvas_(canvas)394 : canvas_(canvas), saveCount_(canvas ? canvas->SaveAllStatus(type) : RSPaintFilterCanvas::SaveStatus()) 395 {} 396 397 /** Allow RSAutoCanvasRestore to be used with std::unique_ptr and std::shared_ptr */ 398 RSAutoCanvasRestore(const std::unique_ptr<RSPaintFilterCanvas>& canvas, 399 RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll) 400 : RSAutoCanvasRestore(canvas.get(), type) 401 {} 402 RSAutoCanvasRestore(const std::shared_ptr<RSPaintFilterCanvas>& canvas, 403 RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll) 404 : RSAutoCanvasRestore(canvas.get(), type) 405 {} 406 407 RSAutoCanvasRestore(RSAutoCanvasRestore&&) = delete; 408 RSAutoCanvasRestore(const RSAutoCanvasRestore&) = delete; 409 RSAutoCanvasRestore& operator=(RSAutoCanvasRestore&&) = delete; 410 RSAutoCanvasRestore& operator=(const RSAutoCanvasRestore&) = delete; 411 412 /** Restores RSPaintFilterCanvas to saved state. Destructor is called when container goes out of 413 scope. 414 */ ~RSAutoCanvasRestore()415 ~RSAutoCanvasRestore() 416 { 417 if (canvas_) { 418 canvas_->RestoreStatus(saveCount_); 419 } 420 } 421 422 /** Restores RSPaintFilterCanvas to saved state immediately. Subsequent calls and 423 ~RSAutoCanvasRestore() have no effect. 424 */ restore()425 void restore() 426 { 427 if (canvas_) { 428 canvas_->RestoreStatus(saveCount_); 429 canvas_ = nullptr; 430 } 431 } 432 433 private: 434 RSPaintFilterCanvas* canvas_ = nullptr; 435 RSPaintFilterCanvas::SaveStatus saveCount_; 436 }; 437 } // namespace Rosen 438 } // namespace OHOS 439 #endif // RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_PAINT_FILTER_CANVAS_H 440