• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_PROPERTY_RS_FILTER_CACHE_MANAGER_H
17 #define RENDER_SERVICE_CLIENT_CORE_PROPERTY_RS_FILTER_CACHE_MANAGER_H
18 
19 #ifndef USE_ROSEN_DRAWING
20 #include "include/core/SkRect.h"
21 
22 #include "common/rs_macros.h"
23 #include "common/rs_rect.h"
24 #include "pipeline/rs_paint_filter_canvas.h"
25 #include "render/rs_filter.h"
26 
27 namespace OHOS {
28 namespace Rosen {
29 class RSSkiaFilter;
30 
31 // Note: we don't care about if the filter will be applied to background or foreground, the caller should take care of
32 // this. This means if both background and foreground need to apply filter, the caller should create two
33 // RSFilterCacheManager, pass the correct dirty region, and call the DrawFilter() in correct order.
34 class RSFilterCacheManager final {
35 public:
36     RSFilterCacheManager() = default;
37     ~RSFilterCacheManager() = default;
38     RSFilterCacheManager(const RSFilterCacheManager&) = delete;
39     RSFilterCacheManager(const RSFilterCacheManager&&) = delete;
40     RSFilterCacheManager& operator=(const RSFilterCacheManager&) = delete;
41     RSFilterCacheManager& operator=(const RSFilterCacheManager&&) = delete;
42 
43     // Call these functions during the prepare phase to validate the cache state with the filter hash, filter region,
44     // and dirty region.
45     void UpdateCacheStateWithFilterHash(uint32_t filterHash);
46     void UpdateCacheStateWithFilterRegion(const RectI& filterRegion);
47     void UpdateCacheStateWithDirtyRegion(const RectI& dirtyRegion);
48 
49     // Similar to UpdateCacheStateWithFilterRegion and UpdateCacheStateWithDirtyRegion, but instead of passing a filter
50     // region or dirty region, we directly pass the test result of if the cached region cannot fully cover the filter
51     // region or if the cached region is intersected with dirty region.
52     void UpdateCacheStateWithFilterRegion(bool isCachedRegionCannotCoverFilterRegion);
53     void UpdateCacheStateWithDirtyRegion(bool isCachedRegionIntersectedWithDirtyRegion);
54     const SkIRect& GetCachedImageRegion() const;
55 
56     // Call this function during the process phase to apply the filter. Depending on the cache state, it may either
57     // regenerate the cache or reuse the existing cache.
58     // Note: The caller should clip the canvas before calling this method, we'll use the DeviceClipRect as the filtered
59     // and cached region.
60     void DrawFilter(RSPaintFilterCanvas& canvas, const std::shared_ptr<RSSkiaFilter>& filter);
61 
62     // This function is similar to DrawFilter(), but instead of drawing anything on the canvas, it simply returns the
63     // cache data. This is used with effect component in RSPropertiesPainter::DrawBackgroundEffect.
64     CachedEffectData GeneratedCachedEffectData(
65         RSPaintFilterCanvas& canvas, const std::shared_ptr<RSSkiaFilter>& filter);
66 
67     // Call this function to manually invalidate the cache. The next time DrawFilter() is called, it will regenerate the
68     // cache.
69     void InvalidateCache();
70 
IsCacheValid()71     bool IsCacheValid() const
72     {
73         return cacheType_ != CacheType::CACHE_TYPE_NONE;
74     }
75 
76 private:
77     // TakeSnapshot won't apply the filter, but we need to call filter::PreProcess()
78     void TakeSnapshot(RSPaintFilterCanvas& canvas, const std::shared_ptr<RSSkiaFilter>& filter);
79     // GenerateFilteredSnapshot will call DrawCachedSnapshot to generate filtered snapshot and cache it.
80     void GenerateFilteredSnapshot(RSPaintFilterCanvas& canvas, const std::shared_ptr<RSSkiaFilter>& filter);
81     void DrawCachedSnapshot(RSPaintFilterCanvas& canvas, const std::shared_ptr<RSSkiaFilter>& filter) const;
82     void DrawCachedFilteredSnapshot(RSPaintFilterCanvas& canvas) const;
83     void ClipVisibleRect(RSPaintFilterCanvas& canvas) const;
84     // Attempt to reattach cached image to recording context if needed, if failed, we'll invalidate the cache.
85     void ReattachCachedImage(RSPaintFilterCanvas& canvas);
86 
87     enum class CacheType : uint8_t {
88         CACHE_TYPE_NONE,
89         CACHE_TYPE_SNAPSHOT,
90         CACHE_TYPE_FILTERED_SNAPSHOT,
91     };
92 
93     CacheType cacheType_ = CacheType::CACHE_TYPE_NONE;
94     sk_sp<SkImage> cachedImage_ = nullptr;
95 
96     // for automatically converting cached snapshot to filtered snapshot if the filter is persistent
97     uint32_t cachedFilterHash_ = 0;
98     int frameSinceLastFilterChange_ = 0;
99 
100     // for delaying cached snapshot update even if the cached area is intersected with dirty region.
101     int cacheUpdateInterval_ = 0;
102 
103     // Note: all rects should be in device coordinate space
104     SkIRect cachedImageRegion_; // region of cached image
105     SkIRect filterRegion_;      // region of previous filter region
106 };
107 
108 } // namespace Rosen
109 } // namespace OHOS
110 #endif
111 
112 #endif // RENDER_SERVICE_CLIENT_CORE_PROPERTY_RS_FILTER_CACHE_MANAGER_H
113