• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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