blob: b04dc1cc24eba1ae6e97ccc13024fb0ef9031219 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_LIB_UI_PAINTING_IMAGE_GENERATOR_REGISTRY_H_
#define FLUTTER_LIB_UI_PAINTING_IMAGE_GENERATOR_REGISTRY_H_
#include <functional>
#include <set>
#include "flutter/fml/mapping.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/lib/ui/painting/image_generator.h"
namespace flutter {
/// @brief `ImageGeneratorFactory` is the top level primitive for specifying an
/// image decoder in Flutter. When called, it should return an
/// `ImageGenerator` that typically compatible with the given input
/// data.
using ImageGeneratorFactory =
std::function<std::shared_ptr<ImageGenerator>(sk_sp<SkData> buffer)>;
/// @brief Keeps a priority-ordered registry of image generator builders to be
/// used when decoding images. This object must be created, accessed, and
/// collected on the UI thread (typically the engine or its runtime
/// controller).
class ImageGeneratorRegistry {
public:
ImageGeneratorRegistry();
~ImageGeneratorRegistry();
/// @brief Install a new factory for image generators
/// @param[in] factory Callback that produces `ImageGenerator`s for
/// compatible input data.
/// @param[in] priority The priority used to determine the order in which
/// factories are tried. Higher values mean higher
/// priority. The built-in Skia decoders are installed
/// at priority 0, and so a priority > 0 takes precedent
/// over the builtin decoders. When multiple decoders
/// are added with the same priority, those which are
/// added earlier take precedent.
/// @see `CreateCompatibleGenerator`
void AddFactory(ImageGeneratorFactory factory, int32_t priority);
/// @brief Walks the list of image generator builders in descending
/// priority order until a compatible `ImageGenerator` is able to
/// be built. This method is safe to perform on the UI thread, as
/// checking for `ImageGenerator` compatibility is expected to be
/// a lightweight operation. The returned `ImageGenerator` can
/// then be used to fully decode the image on e.g. the IO thread.
/// @param[in] buffer The raw encoded image data.
/// @return An `ImageGenerator` that is compatible with the input buffer.
/// If no compatible `ImageGenerator` type was found, then
/// `std::shared_ptr<ImageGenerator>(nullptr)` is returned.
/// @see `ImageGenerator`
std::shared_ptr<ImageGenerator> CreateCompatibleGenerator(
sk_sp<SkData> buffer);
fml::WeakPtr<ImageGeneratorRegistry> GetWeakPtr() const;
private:
struct PrioritizedFactory {
ImageGeneratorFactory callback;
int32_t priority = 0;
// Used as a fallback priority comparison when equal.
size_t ascending_nonce = 0;
};
struct Compare {
constexpr bool operator()(const PrioritizedFactory& lhs,
const PrioritizedFactory& rhs) const {
// When priorities are equal, factories registered earlier take
// precedent.
if (lhs.priority == rhs.priority) {
return lhs.ascending_nonce < rhs.ascending_nonce;
}
// Order by descending priority.
return lhs.priority > rhs.priority;
}
};
using FactorySet = std::set<PrioritizedFactory, Compare>;
FactorySet image_generator_factories_;
size_t nonce_;
fml::WeakPtrFactory<ImageGeneratorRegistry> weak_factory_;
};
} // namespace flutter
#endif // FLUTTER_LIB_UI_PAINTING_IMAGE_DECODER_H_