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