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