• 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 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