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