• 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/SkSurface.h"
29 #else
30 #include "draw/canvas.h"
31 #include "draw/surface.h"
32 #endif
33 
34 #include "common/rs_color.h"
35 #include "common/rs_macros.h"
36 
37 namespace OHOS {
38 namespace Rosen {
39 
40 #ifdef USE_ROSEN_DRAWING
41 class RSB_EXPORT RSPaintFilterCanvasBase : public Drawing::Canvas {
42 public:
43     RSPaintFilterCanvasBase(Drawing::Canvas* canvas);
44     ~RSPaintFilterCanvasBase() override = default;
45 
46     Drawing::Matrix GetTotalMatrix() const override;
47 
48     Drawing::Rect GetLocalClipBounds() const override;
49 
50     Drawing::RectI GetDeviceClipBounds() const override;
51 
52     uint32_t GetSaveCount() const override;
53 
54 #ifdef ACE_ENABLE_GPU
55     std::shared_ptr<Drawing::GPUContext> GetGPUContext() override;
56 #endif
57 
58     void DrawPoint(const Drawing::Point& point) override;
59     void DrawPoints(Drawing::PointMode mode, size_t count, const Drawing::Point pts[]) 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 DrawColor(Drawing::ColorQuad color, Drawing::BlendMode mode = Drawing::BlendMode::SRC_OVER) override;
74     void DrawRegion(const Drawing::Region& region) override;
75     void DrawPatch(const Drawing::Point cubics[12], const Drawing::ColorQuad colors[4],
76         const Drawing::Point texCoords[4], Drawing::BlendMode mode) override;
77     void DrawVertices(const Drawing::Vertices& vertices, Drawing::BlendMode mode) override;
78 
79     void DrawImageNine(const Drawing::Image* image, const Drawing::RectI& center, const Drawing::Rect& dst,
80         Drawing::FilterMode filter, const Drawing::Brush* brush = nullptr) override;
81     void DrawImageLattice(const Drawing::Image* image, const Drawing::Lattice& lattice, const Drawing::Rect& dst,
82         Drawing::FilterMode filter, const Drawing::Brush* brush = nullptr) override;
83 
84     void DrawBitmap(const Drawing::Bitmap& bitmap, const Drawing::scalar px, const Drawing::scalar py) override;
85     void DrawBitmap(Media::PixelMap& pixelMap, const Drawing::scalar px, const Drawing::scalar py) override;
86     void DrawImage(const Drawing::Image& image,
87         const Drawing::scalar px, const Drawing::scalar py, const Drawing::SamplingOptions& sampling) override;
88     void DrawImageRect(const Drawing::Image& image, const Drawing::Rect& src, const Drawing::Rect& dst,
89         const Drawing::SamplingOptions& sampling, Drawing::SrcRectConstraint constraint) override;
90     void DrawImageRect(const Drawing::Image& image,
91         const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling) override;
92     void DrawPicture(const Drawing::Picture& picture) override;
93     void DrawTextBlob(const Drawing::TextBlob* blob, const Drawing::scalar x, const Drawing::scalar y) override;
94 
95     void ClipRect(const Drawing::Rect& rect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT,
96         bool doAntiAlias = false) override;
97     void ClipIRect(const Drawing::RectI& rect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT) override;
98     void ClipRoundRect(const Drawing::RoundRect& roundRect, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT,
99         bool doAntiAlias = false) override;
100     void ClipRoundRect(const Drawing::Rect& rect, std::vector<Drawing::Point>& pts, bool doAntiAlias = false) override;
101     void ClipPath(const Drawing::Path& path, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT,
102         bool doAntiAlias = false) override;
103     void ClipRegion(const Drawing::Region& region, Drawing::ClipOp op = Drawing::ClipOp::INTERSECT) override;
104 
105     void SetMatrix(const Drawing::Matrix& matrix) override;
106     void ResetMatrix() override;
107     void ConcatMatrix(const Drawing::Matrix& matrix) override;
108     void Translate(Drawing::scalar dx, Drawing::scalar dy) override;
109     void Scale(Drawing::scalar sx, Drawing::scalar sy) override;
110     void Rotate(Drawing::scalar deg, Drawing::scalar sx, Drawing::scalar sy) override;
111     void Shear(Drawing::scalar sx, Drawing::scalar sy) override;
112 
113     void Flush() override;
114     void Clear(Drawing::ColorQuad color) override;
115     uint32_t Save() override;
116     void SaveLayer(const Drawing::SaveLayerOps& saveLayerOps) override;
117     void Restore() override;
118     void Discard() override;
119 
120     CoreCanvas& AttachPen(const Drawing::Pen& pen) override;
121     CoreCanvas& AttachBrush(const Drawing::Brush& brush) override;
122     CoreCanvas& AttachPaint(const Drawing::Paint& paint) override;
123     CoreCanvas& DetachPen() override;
124     CoreCanvas& DetachBrush() override;
125     CoreCanvas& DetachPaint() override;
126 
127 protected:
128     virtual bool OnFilter() const = 0;
129     virtual bool OnFilterWithBrush(Drawing::Brush& brush) const = 0;
130     Drawing::Canvas* canvas_ = nullptr;
131 };
132 #endif // USE_ROSEN_DRAWING
133 
134 // This class is used to filter the paint before drawing. currently, it is used to filter the alpha and foreground
135 // color.
136 #ifndef USE_ROSEN_DRAWING
137 class RSB_EXPORT RSPaintFilterCanvas : public SkPaintFilterCanvas {
138 public:
139     RSPaintFilterCanvas(SkCanvas* canvas, float alpha = 1.0f);
140     RSPaintFilterCanvas(SkSurface* skSurface, float alpha = 1.0f);
141 #else
142 class RSB_EXPORT RSPaintFilterCanvas : public RSPaintFilterCanvasBase {
143 public:
144     RSPaintFilterCanvas(Drawing::Canvas* canvas, float alpha = 1.0f);
145     RSPaintFilterCanvas(Drawing::Surface* surface, float alpha = 1.0f);
146 #endif
~RSPaintFilterCanvas()147     ~RSPaintFilterCanvas() override {};
148 
149     void CopyConfiguration(const RSPaintFilterCanvas& other);
150 
151     // alpha related
152     void MultiplyAlpha(float alpha);
153     void SetAlpha(float alpha);
154 #ifndef USE_ROSEN_DRAWING
155     float GetAlpha() const;
156 #else
157     float GetAlpha() const override;
158 #endif
159     int SaveAlpha();
160     void RestoreAlpha();
161 #ifndef USE_ROSEN_DRAWING
162     int GetAlphaSaveCount() const;
163 #else
164     int GetAlphaSaveCount() const override;
165 #endif
166     void RestoreAlphaToCount(int count);
167 
168     // env related
169     void SetEnvForegroundColor(Color color);
170 #ifndef USE_ROSEN_DRAWING
171     Color GetEnvForegroundColor() const;
172 #else
173     Drawing::ColorQuad GetEnvForegroundColor() const override;
174 #endif
175     int SaveEnv();
176     void RestoreEnv();
177     int GetEnvSaveCount() const;
178     void RestoreEnvToCount(int count);
179 
180     // blendmode related
181     int SaveBlendMode();
182     void SetBlendMode(std::optional<int> blendMode);
183     void RestoreBlendMode();
184 
185     // save/restore utils
186     struct SaveStatus {
187         int canvasSaveCount = -1;
188         int alphaSaveCount = -1;
189         int envSaveCount = -1;
190     };
191     enum SaveType : uint8_t {
192         kNone   = 0x0,
193         kCanvas = 0x1,
194         kAlpha  = 0x2,
195         kEnv    = 0x4,
196         kAll    = kCanvas | kAlpha | kEnv,
197     };
198 
199 #ifndef USE_ROSEN_DRAWING
200     SaveStatus Save(SaveType type = kAll);
201 #else
202     SaveStatus SaveAllStatus(SaveType type = kAll);
203 #endif
204     SaveStatus GetSaveStatus() const;
205     void RestoreStatus(const SaveStatus& status);
206 
207 #ifndef USE_ROSEN_DRAWING
208     SkSurface* GetSurface() const;
209 #else
210     Drawing::Surface* GetSurface() const override;
211 #endif
212 
213     // high contrast
214     void SetHighContrast(bool enabled);
215 #ifndef USE_ROSEN_DRAWING
216     bool isHighContrastEnabled() const;
217 #else
218     bool isHighContrastEnabled() const override;
219 #endif
220 
221 #ifndef USE_ROSEN_DRAWING
222     enum CacheType : uint8_t {
223         UNDEFINED, // do not change current cache status
224         ENABLED,   // explicitly enable cache
225         DISABLED,  // explicitly disable cache
226         OFFSCREEN, // offscreen rendering
227     };
228 #else
229     using CacheType = Drawing::CacheType;
230 #endif
231     // cache
232     void SetCacheType(CacheType type);
233 #ifndef USE_ROSEN_DRAWING
234     CacheType GetCacheType() const;
235 #else
236     Drawing::CacheType GetCacheType() const override;
237 #endif
238 
239     // visible rect
240 #ifndef USE_ROSEN_DRAWING
241     void SetVisibleRect(SkRect visibleRect);
242     SkRect GetVisibleRect() const;
243 
244     static std::optional<SkRect> GetLocalClipBounds(const SkCanvas& canvas, const SkIRect* clipBounds = nullptr);
245 #else
246     void SetVisibleRect(Drawing::Rect visibleRect);
247     Drawing::Rect GetVisibleRect() const;
248 
249     static std::optional<Drawing::Rect> GetLocalClipBounds(const Drawing::Canvas& canvas,
250         const Drawing::RectI* clipBounds = nullptr);
251 
252     CoreCanvas& AttachPen(const Drawing::Pen& pen) override;
253     CoreCanvas& AttachBrush(const Drawing::Brush& brush) override;
254     CoreCanvas& AttachPaint(const Drawing::Paint& paint) override;
255 #endif
256     void SetIsParallelCanvas(bool isParallel);
257     bool GetIsParallelCanvas() const;
258 
259     void SetDisableFilterCache(bool disable);
260     bool GetDisableFilterCache() const;
261 
262     void SetRecordDrawable(bool enable);
263     bool GetRecordDrawable() const;
264 
265 #ifndef USE_ROSEN_DRAWING
266     // effect cache data relate
267     struct CachedEffectData {
268         CachedEffectData() = default;
269         CachedEffectData(sk_sp<SkImage>&& image, const SkIRect& rect);
270         ~CachedEffectData() = default;
271         sk_sp<SkImage> cachedImage_ = nullptr;
272         SkIRect cachedRect_ = SkIRect::MakeEmpty();
273     };
274     void SetEffectData(const std::shared_ptr<CachedEffectData>& effectData);
275     const std::shared_ptr<CachedEffectData>& GetEffectData() const;
276 
277     // canvas status relate
278     struct CanvasStatus {
279         float alpha_;
280         SkMatrix matrix_;
281         std::shared_ptr<CachedEffectData> effectData_;
282     };
283     CanvasStatus GetCanvasStatus() const;
284     void SetCanvasStatus(const CanvasStatus& status);
285     SkCanvas* GetRecordingCanvas() const;
286 #else
287     // effect cache data relate
288     struct CachedEffectData {
289         CachedEffectData() = default;
290         CachedEffectData(std::shared_ptr<Drawing::Image>&& image, const Drawing::RectI& rect);
291         ~CachedEffectData() = default;
292         std::shared_ptr<Drawing::Image> cachedImage_ = nullptr;
293         Drawing::RectI cachedRect_ = {};
294     };
295     void SetEffectData(const std::shared_ptr<CachedEffectData>& effectData);
296     const std::shared_ptr<CachedEffectData>& GetEffectData() const;
297 
298     // canvas status relate
299     struct CanvasStatus {
300         float alpha_;
301         Drawing::Matrix matrix_;
302         std::shared_ptr<CachedEffectData> effectData_;
303     };
304     CanvasStatus GetCanvasStatus() const;
305     void SetCanvasStatus(const CanvasStatus& status);
306     Drawing::Canvas* GetRecordingCanvas() const override;
307     bool GetRecordingState() const override;
308     void SetRecordingState(bool flag) override;
309 #endif
310 
311 protected:
312     using Env = struct {
313         Color envForegroundColor_;
314         std::shared_ptr<CachedEffectData> effectData_;
315     };
316 #ifndef USE_ROSEN_DRAWING
317     bool onFilter(SkPaint& paint) const override;
318     void onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint) override;
319     SkCanvas::SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override;
320 #else
321     const std::stack<float>& GetAlphaStack();
322     const std::stack<Env>& GetEnvStack();
323 
324     bool OnFilter() const override;
OnFilterWithBrush(Drawing::Brush & brush)325     inline bool OnFilterWithBrush(Drawing::Brush& brush) const override
326     {
327         float alpha = alphaStack_.top();
328         // foreground color and foreground color strategy identification
329         if (brush.GetColor().CastToColorQuad() == 0x00000001) {
330             brush.SetColor(envStack_.top().envForegroundColor_.AsArgbInt());
331         }
332 
333         // use alphaStack_.top() to multiply alpha
334         if (alpha < 1 && alpha > 0) {
335             brush.SetAlpha(brush.GetAlpha() * alpha);
336         }
337         return alpha > 0.f;
338     }
339 #endif
340 
341 private:
342 #ifndef USE_ROSEN_DRAWING
343     SkSurface* skSurface_ = nullptr;
344 #else
345     Drawing::Surface* surface_ = nullptr;
346 #endif
347     std::stack<float> alphaStack_;
348     std::stack<Env> envStack_;
349     std::stack<std::optional<int>> blendModeStack_;
350 
351     std::atomic_bool isHighContrastEnabled_ { false };
352     CacheType cacheType_ { RSPaintFilterCanvas::CacheType::UNDEFINED };
353 #ifndef USE_ROSEN_DRAWING
354     SkRect visibleRect_ = SkRect::MakeEmpty();
355 #else
356     Drawing::Rect visibleRect_ = Drawing::Rect();
357 #endif
358 
359     bool isParallelCanvas_ = false;
360     bool disableFilterCache_ = false;
361     bool recordingState_ = false;
362     bool recordDrawable_ = false;
363 };
364 
365 // Helper class similar to SkAutoCanvasRestore, but also restores alpha and/or env
366 class RSB_EXPORT RSAutoCanvasRestore {
367 public:
368     /** Preserves canvas save count. Optionally call SkCanvas::save() and/or RSPaintFilterCanvas::SaveAlpha() and/or
369        RSPaintFilterCanvas::SaveEnv().
370         @param canvas     RSPaintFilterCanvas to guard
371         @param saveCanvas call SkCanvas::save()
372         @param saveAlpha  call RSPaintFilterCanvas::SaveAlpha()
373         @return           utility to restore RSPaintFilterCanvas state on destructor
374     */
375 #ifndef USE_ROSEN_DRAWING
376     RSAutoCanvasRestore(
377         RSPaintFilterCanvas* canvas, RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll)
canvas_(canvas)378         : canvas_(canvas), saveCount_(canvas ? canvas->Save(type) : RSPaintFilterCanvas::SaveStatus())
379     {}
380 #else
381     RSAutoCanvasRestore(
382         RSPaintFilterCanvas* canvas, RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll)
383         : canvas_(canvas), saveCount_(canvas ? canvas->SaveAllStatus(type) : RSPaintFilterCanvas::SaveStatus())
384     {}
385 #endif
386 
387     /** Allow RSAutoCanvasRestore to be used with std::unique_ptr and std::shared_ptr */
388     RSAutoCanvasRestore(const std::unique_ptr<RSPaintFilterCanvas>& canvas,
389         RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll)
390         : RSAutoCanvasRestore(canvas.get(), type)
391     {}
392     RSAutoCanvasRestore(const std::shared_ptr<RSPaintFilterCanvas>& canvas,
393         RSPaintFilterCanvas::SaveType type = RSPaintFilterCanvas::SaveType::kAll)
394         : RSAutoCanvasRestore(canvas.get(), type)
395     {}
396 
397     RSAutoCanvasRestore(RSAutoCanvasRestore&&) = delete;
398     RSAutoCanvasRestore(const RSAutoCanvasRestore&) = delete;
399     RSAutoCanvasRestore& operator=(RSAutoCanvasRestore&&) = delete;
400     RSAutoCanvasRestore& operator=(const RSAutoCanvasRestore&) = delete;
401 
402     /** Restores RSPaintFilterCanvas to saved state. Destructor is called when container goes out of
403         scope.
404     */
~RSAutoCanvasRestore()405     ~RSAutoCanvasRestore()
406     {
407         if (canvas_) {
408             canvas_->RestoreStatus(saveCount_);
409         }
410     }
411 
412     /** Restores RSPaintFilterCanvas to saved state immediately. Subsequent calls and
413         ~RSAutoCanvasRestore() have no effect.
414     */
restore()415     void restore()
416     {
417         if (canvas_) {
418             canvas_->RestoreStatus(saveCount_);
419             canvas_ = nullptr;
420         }
421     }
422 
423 private:
424     RSPaintFilterCanvas* canvas_ = nullptr;
425     RSPaintFilterCanvas::SaveStatus saveCount_;
426 };
427 } // namespace Rosen
428 } // namespace OHOS
429 #endif // RENDER_SERVICE_CLIENT_CORE_PIPELINE_RS_PAINT_FILTER_CANVAS_H
430