• 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 #ifndef USE_ROSEN_DRAWING
20 #include <include/utils/SkPaintFilterCanvas.h>
21 #endif
22 #include <optional>
23 #include <stack>
24 #include <vector>
25 
26 #ifndef USE_ROSEN_DRAWING
27 #include "include/core/SkColorFilter.h"
28 #include "include/core/SkPath.h"
29 #include "include/core/SkSurface.h"
30 #else
31 #include "draw/canvas.h"
32 #include "draw/surface.h"
33 #endif
34 
35 #include "common/rs_color.h"
36 #include "common/rs_macros.h"
37 
38 namespace OHOS {
39 namespace Rosen {
40 
41 #ifndef USE_ROSEN_DRAWING
42 struct CachedEffectData {
43     sk_sp<SkImage> cachedImage_ = nullptr;
44     SkIRect cachedRect_ = SkIRect::MakeEmpty();
45     SkPath childrenPath_;
46 };
47 #endif
48 
49 #ifdef USE_ROSEN_DRAWING
50 class RSB_EXPORT RSPaintFilterCanvasBase : public Drawing::Canvas {
51 public:
52     RSPaintFilterCanvasBase(Drawing::Canvas* canvas);
53     ~RSPaintFilterCanvasBase() override = default;
54 
55 #ifdef ACE_ENABLE_GPU
56     std::shared_ptr<Drawing::GPUContext> GetGPUContext() const override;
57 #endif
58 
59     void DrawPoint(const Drawing::Point& point) override;
60     void DrawLine(const Drawing::Point& startPt, const Drawing::Point& endPt) override;
61     void DrawRect(const Drawing::Rect& rect) override;
62     void DrawRoundRect(const Drawing::RoundRect& roundRect) override;
63     void DrawNestedRoundRect(const Drawing::RoundRect& outer, const Drawing::RoundRect& inner) override;
64     void DrawArc(const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle) override;
65     void DrawPie(const Drawing::Rect& oval, Drawing::scalar startAngle, Drawing::scalar sweepAngle) override;
66     void DrawOval(const Drawing::Rect& oval) override;
67     void DrawCircle(const Drawing::Point& centerPt, Drawing::scalar radius) override;
68     void DrawPath(const Drawing::Path& path) override;
69     void DrawBackground(const Drawing::Brush& brush) override;
70     void DrawShadow(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) override;
73     void DrawRegion(const Drawing::Region& region) override;
74 
75     void DrawBitmap(const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py) override;
76     void DrawBitmap(Media::PixelMap& pixelMap, const Drawing::scalar px, const Drawing::scalar py) override;
77     void DrawImage(const Drawing::Image& image,
78         const Drawing::scalar px, const Drawing::scalar py, const Drawing::SamplingOptions& sampling) override;
79     void DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src, const Drawing::Rect& dst,
80         const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint) override;
81     void DrawImageRect(const Drawing::Image& image,
82         const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling) override;
83     void DrawPicture(const Drawing::Picture& picture) override;
84 
85     void ClipRect(const Drawing::Rect& rect, Drawing::ClipOp op, bool doAntiAlias) override;
86     void ClipRoundRect(const Drawing::RoundRect& roundRect, Drawing::ClipOp op, bool doAntiAlias) override;
87     void ClipPath(const Drawing::Path& path, Drawing::ClipOp op, bool doAntiAlias) override;
88 
89     void SetMatrix(const Drawing::Matrix& matrix) override;
90     void ResetMatrix() override;
91     void ConcatMatrix(const Drawing::Matrix& matrix) override;
92     void Translate(Drawing::scalar dx, Drawing::scalar dy) override;
93     void Scale(Drawing::scalar sx, Drawing::scalar sy) override;
94     void Rotate(Drawing::scalar deg, Drawing::scalar sx, Drawing::scalar sy) override;
95     void Shear(Drawing::scalar sx, Drawing::scalar sy) override;
96 
97     void Flush() override;
98     void Clear(Drawing::ColorQuad color) override;
99     void Save() override;
100     void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override;
101     void Restore() override;
102 
103     CoreCanvas& AttachPen(const Drawing::Pen& pen) override;
104     CoreCanvas& AttachBrush(const Drawing::Brush& brush) override;
105     CoreCanvas& DetachPen() override;
106     CoreCanvas& DetachBrush() override;
107 
108 protected:
109     virtual bool OnFilter() const = 0;
110     Drawing::Canvas* canvas_ = nullptr;
111 };
112 #endif // USE_ROSEN_DRAWING
113 
114 // This class is used to filter the paint before drawing. currently, it is used to filter the alpha and foreground
115 // color.
116 #ifndef USE_ROSEN_DRAWING
117 class RSB_EXPORT RSPaintFilterCanvas : public SkPaintFilterCanvas {
118 public:
119     RSPaintFilterCanvas(SkCanvas* canvas, float alpha = 1.0f);
120     RSPaintFilterCanvas(SkSurface* skSurface, float alpha = 1.0f);
121 #else
122 class RSB_EXPORT RSPaintFilterCanvas : public RSPaintFilterCanvasBase {
123 public:
124     RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha = 1.0f);
125     RSPaintFilterCanvas(Drawing::Surface* surface, float alpha = 1.0f);
126 #endif
~RSPaintFilterCanvas()127     ~RSPaintFilterCanvas() override {};
128 
129     void CopyConfiguration(const RSPaintFilterCanvas& other);
130 
131     // alpha related
132     void MultiplyAlpha(float alpha);
133     void SetAlpha(float alpha);
134     float GetAlpha() const;
135     int SaveAlpha();
136     void RestoreAlpha();
137     int GetAlphaSaveCount() const;
138     void RestoreAlphaToCount(int count);
139 
140     // env related
141     void SetEnvForegroundColor(Color color);
142     Color GetEnvForegroundColor() const;
143     int SaveEnv();
144     void RestoreEnv();
145     int GetEnvSaveCount() const;
146     void RestoreEnvToCount(int count);
147 
148     // save/restore utils
149     struct SaveStatus {
150         int canvasSaveCount = -1;
151         int alphaSaveCount = -1;
152         int envSaveCount = -1;
153     };
154 #ifndef USE_ROSEN_DRAWING
155     SaveStatus Save();
156 #else
157     SaveStatus SaveAllStatus();
158 #endif
159     SaveStatus GetSaveStatus() const;
160     void RestoreStatus(const SaveStatus& status);
161 
162 #ifndef USE_ROSEN_DRAWING
163     SkSurface* GetSurface() const;
164 #else
165     Drawing::Surface* GetSurface() const;
166 #endif
167 
168     // high contrast
169     void SetHighContrast(bool enabled);
170     bool isHighContrastEnabled() const;
171 
172     enum CacheType : uint8_t {
173         UNDEFINED, // do not change current cache status
174         ENABLED,   // explicitly enable cache
175         DISABLED,  // explicitly disable cache
176         OFFSCREEN, // offscreen rendering
177     };
178     // cache
179     void SetCacheType(CacheType type);
180     CacheType GetCacheType() const;
181 
182     // visible rect
183 #ifndef USE_ROSEN_DRAWING
184     void SetVisibleRect(SkRect visibleRect);
185     SkRect GetVisibleRect() const;
186 
187     static std::optional<SkRect> GetLocalClipBounds(const SkCanvas& canvas, const SkIRect* clipBounds = nullptr);
188 #else
189     void SetVisibleRect(Drawing::Rect visibleRect);
190     Drawing::Rect GetVisibleRect() const;
191 
192     static std::optional<Drawing::Rect> GetLocalClipBounds(const Drawing::Canvas& canvas,
193         const Drawing::RectI* clipBounds = nullptr);
194 
195     CoreCanvas& AttachPen(const Drawing::Pen& pen) override;
196     CoreCanvas& AttachBrush(const Drawing::Brush& brush) override;
197 #endif
SetIsParallelCanvas(bool isParallel)198     void SetIsParallelCanvas(bool isParallel) {
199         isParallelCanvas_ = isParallel;
200     }
201 
GetIsParallelCanvas()202     bool GetIsParallelCanvas() const
203     {
204         return isParallelCanvas_;
205     }
206 
207 #ifndef USE_ROSEN_DRAWING
208     // effect cache data related
209     void SetEffectData(const CachedEffectData& effectData);
210     void SetChildrenPath(const SkPath& childrenPath);
211     const CachedEffectData& GetEffectData() const;
212 
213     void SaveEffectData();
214     void RestoreEffectData();
215 #endif
216 
217 protected:
218 #ifndef USE_ROSEN_DRAWING
219     bool onFilter(SkPaint& paint) const override;
220     void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) override;
221     SkCanvas::SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
222 #else
223     using Env = struct {
224         Color envForegroundColor;
225     };
226     std::stack<float> GetAlphaStack();
227     std::stack<Env> GetEnvStack();
228     bool OnFilter() const override;
229 #endif
230 
231 private:
232 #ifndef USE_ROSEN_DRAWING
233     SkSurface* skSurface_ = nullptr;
234 #else
235     Drawing::Surface* surface_ = nullptr;
236 #endif
237     std::stack<float> alphaStack_;
238 #ifndef USE_ROSEN_DRAWING
239     using Env = struct {
240         Color envForegroundColor;
241     };
242 #endif
243     std::stack<Env> envStack_;
244 
245     std::atomic_bool isHighContrastEnabled_ { false };
246     CacheType cacheType_ { UNDEFINED };
247 #ifndef USE_ROSEN_DRAWING
248     SkRect visibleRect_ = SkRect::MakeEmpty();
249 #else
250     Drawing::Rect visibleRect_ = Drawing::Rect();
251 #endif
252 
253     bool isParallelCanvas_ = false;
254 #ifndef USE_ROSEN_DRAWING
255     std::stack<CachedEffectData> effectStack_;
256 #endif
257 };
258 
259 // This class extends RSPaintFilterCanvas to also create a color filter for the paint.
260 class RSB_EXPORT RSColorFilterCanvas : public RSPaintFilterCanvas {
261 public:
262     explicit RSColorFilterCanvas(RSPaintFilterCanvas* canvas);
~RSColorFilterCanvas()263     ~RSColorFilterCanvas() override {};
264 
265 #ifdef USE_ROSEN_DRAWING
266     CoreCanvas& AttachPen(const Drawing::Pen& pen) override;
267     CoreCanvas& AttachBrush(const Drawing::Brush& brush) override;
268 #endif
269 
270 protected:
271 #ifndef USE_ROSEN_DRAWING
272     bool onFilter(SkPaint& paint) const override;
273 #else
274     bool onFilter() const;
275 #endif
276 };
277 
278 // Helper class similar to SkAutoCanvasRestore, but also restores alpha and/or env
279 class RSB_EXPORT RSAutoCanvasRestore {
280 public:
281     enum SaveType : uint8_t {
282         kNone   = 0x0,
283         kCanvas = 0x1,
284         kAlpha  = 0x2,
285         kEnv    = 0x4,
286         kALL    = kCanvas | kAlpha | kEnv,
287     };
288 
289     /** Preserves canvas save count. Optionally call SkCanvas::save() and/or RSPaintFilterCanvas::SaveAlpha() and/or
290        RSPaintFilterCanvas::SaveEnv().
291         @param canvas     RSPaintFilterCanvas to guard
292         @param saveCanvas call SkCanvas::save()
293         @param saveAlpha  call RSPaintFilterCanvas::SaveAlpha()
294         @return           utility to restore RSPaintFilterCanvas state on destructor
295     */
296     RSAutoCanvasRestore(RSPaintFilterCanvas* canvas, SaveType type = SaveType::kALL);
297 
298     /** Allow RSAutoCanvasRestore to be used with std::unique_ptr and std::shared_ptr */
299     RSAutoCanvasRestore(const std::unique_ptr<RSPaintFilterCanvas>& canvas, SaveType type = SaveType::kALL)
300         : RSAutoCanvasRestore(canvas.get(), type)
301     {}
302     RSAutoCanvasRestore(const std::shared_ptr<RSPaintFilterCanvas>& canvas, SaveType type = SaveType::kALL)
303         : RSAutoCanvasRestore(canvas.get(), type)
304     {}
305 
306     /** Restores RSPaintFilterCanvas to saved state. Destructor is called when container goes out of
307         scope.
308     */
~RSAutoCanvasRestore()309     ~RSAutoCanvasRestore()
310     {
311         if (canvas_ && saveCount_.has_value()) {
312             canvas_->RestoreStatus(saveCount_.value());
313         }
314     }
315 
316     /** Restores RSPaintFilterCanvas to saved state immediately. Subsequent calls and
317         ~RSAutoCanvasRestore() have no effect.
318     */
restore()319     void restore()
320     {
321         if (canvas_ && saveCount_.has_value()) {
322             canvas_->RestoreStatus(saveCount_.value());
323             canvas_ = nullptr;
324             saveCount_.reset();
325         }
326     }
327 
328 private:
329     RSPaintFilterCanvas* canvas_ = nullptr;
330     std::optional<RSPaintFilterCanvas::SaveStatus> saveCount_;
331 
332     RSAutoCanvasRestore(RSAutoCanvasRestore&&) = delete;
333     RSAutoCanvasRestore(const RSAutoCanvasRestore&) = delete;
334     RSAutoCanvasRestore& operator=(RSAutoCanvasRestore&&) = delete;
335     RSAutoCanvasRestore& operator=(const RSAutoCanvasRestore&) = delete;
336 };
337 } // namespace Rosen
338 } // namespace OHOS
339 #endif // RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_PAINT_FILTER_CANVAS_H
340