Files

145 lines
4.0 KiB
C++
Raw Permalink Normal View History

2018-11-07 12:24:35 -08:00
// Copyright 2013 The Flutter Authors. All rights reserved.
2016-01-08 01:53:36 -08:00
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
2016-08-09 12:48:29 -07:00
#ifndef FLUTTER_FLOW_RASTER_CACHE_H_
#define FLUTTER_FLOW_RASTER_CACHE_H_
2016-01-08 01:53:36 -08:00
#include <memory>
#include <unordered_map>
2016-08-09 12:48:29 -07:00
#include "flutter/flow/instrumentation.h"
#include "flutter/flow/raster_cache_key.h"
2018-07-26 12:49:34 -07:00
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/weak_ptr.h"
2016-08-01 15:11:56 -07:00
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSize.h"
2016-01-08 01:53:36 -08:00
2019-04-17 14:38:45 -07:00
namespace flutter {
2016-01-08 01:53:36 -08:00
class RasterCacheResult {
public:
RasterCacheResult();
RasterCacheResult(const RasterCacheResult& other);
~RasterCacheResult();
RasterCacheResult(sk_sp<SkImage> image, const SkRect& logical_rect);
operator bool() const { return static_cast<bool>(image_); }
bool is_valid() const { return static_cast<bool>(image_); };
void draw(SkCanvas& canvas, const SkPaint* paint = nullptr) const;
SkISize image_dimensions() const {
return image_ ? image_->dimensions() : SkISize::Make(0, 0);
};
private:
sk_sp<SkImage> image_;
SkRect logical_rect_;
};
struct PrerollContext;
2016-01-08 01:53:36 -08:00
class RasterCache {
public:
2019-02-08 17:40:38 -08:00
// The default max number of picture raster caches to be generated per frame.
// Generating too many caches in one frame may cause jank on that frame. This
// limit allows us to throttle the cache and distribute the work across
// multiple frames.
static constexpr int kDefaultPictureCacheLimitPerFrame = 3;
explicit RasterCache(
size_t access_threshold = 3,
2019-02-08 17:40:38 -08:00
size_t picture_cache_limit_per_frame = kDefaultPictureCacheLimitPerFrame);
2016-01-08 01:53:36 -08:00
~RasterCache();
static SkIRect GetDeviceBounds(const SkRect& rect, const SkMatrix& ctm) {
SkRect device_rect;
ctm.mapRect(&device_rect, rect);
SkIRect bounds;
device_rect.roundOut(&bounds);
return bounds;
}
static SkMatrix GetIntegralTransCTM(const SkMatrix& ctm) {
SkMatrix result = ctm;
result[SkMatrix::kMTransX] = SkScalarRoundToScalar(ctm.getTranslateX());
result[SkMatrix::kMTransY] = SkScalarRoundToScalar(ctm.getTranslateY());
return result;
}
// Return true if the cache is generated.
//
// We may return false and not generate the cache if
// 1. The picture is not worth rasterizing
// 2. The matrix is singular
// 3. The picture is accessed too few times
2019-02-08 17:40:38 -08:00
// 4. There are too many pictures to be cached in the current frame.
// (See also kDefaultPictureCacheLimitPerFrame.)
bool Prepare(GrContext* context,
SkPicture* picture,
const SkMatrix& transformation_matrix,
SkColorSpace* dst_color_space,
bool is_complex,
bool will_change);
void Prepare(PrerollContext* context, Layer* layer, const SkMatrix& ctm);
RasterCacheResult Get(const SkPicture& picture, const SkMatrix& ctm) const;
RasterCacheResult Get(Layer* layer, const SkMatrix& ctm) const;
2016-01-08 01:53:36 -08:00
void SweepAfterFrame();
void Clear();
void SetCheckboardCacheImages(bool checkerboard);
size_t GetCachedEntriesCount() const;
2016-01-08 01:53:36 -08:00
private:
struct Entry {
bool used_this_frame = false;
size_t access_count = 0;
RasterCacheResult image;
2016-01-08 01:53:36 -08:00
};
template <class Cache, class Iterator>
static void SweepOneCacheAfterFrame(Cache& cache) {
std::vector<Iterator> dead;
for (auto it = cache.begin(); it != cache.end(); ++it) {
Entry& entry = it->second;
if (!entry.used_this_frame) {
dead.push_back(it);
}
entry.used_this_frame = false;
}
for (auto it : dead) {
cache.erase(it);
}
}
const size_t access_threshold_;
2019-02-08 17:40:38 -08:00
const size_t picture_cache_limit_per_frame_;
size_t picture_cached_this_frame_ = 0;
PictureRasterCacheKey::Map<Entry> picture_cache_;
LayerRasterCacheKey::Map<Entry> layer_cache_;
bool checkerboard_images_;
2018-07-26 12:49:34 -07:00
fml::WeakPtrFactory<RasterCache> weak_factory_;
2016-01-08 01:53:36 -08:00
void TraceStatsToTimeline() const;
2018-07-26 12:49:34 -07:00
FML_DISALLOW_COPY_AND_ASSIGN(RasterCache);
2016-01-08 01:53:36 -08:00
};
2019-04-17 14:38:45 -07:00
} // namespace flutter
2016-01-08 01:53:36 -08:00
2016-08-09 12:48:29 -07:00
#endif // FLUTTER_FLOW_RASTER_CACHE_H_