This repository has been archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add image generator registry and lookup with priority
- Loading branch information
Showing
18 changed files
with
472 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// 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. | ||
|
||
#include "flutter/lib/ui/painting/image_generator.h" | ||
|
||
namespace flutter { | ||
|
||
BuiltinSkiaImageGenerator::BuiltinSkiaImageGenerator( | ||
std::unique_ptr<SkImageGenerator> generator) | ||
: generator_(std::move(generator)) {} | ||
|
||
const SkImageInfo& BuiltinSkiaImageGenerator::getInfo() const { | ||
return generator_->getInfo(); | ||
} | ||
|
||
bool BuiltinSkiaImageGenerator::getPixels(const SkImageInfo& info, | ||
void* pixels, | ||
size_t rowBytes) const { | ||
return generator_->getPixels(info, pixels, rowBytes); | ||
} | ||
|
||
SkISize BuiltinSkiaImageGenerator::getScaledDimensions(float desiredScale) { | ||
return generator_->getInfo().dimensions(); | ||
} | ||
|
||
std::unique_ptr<ImageGenerator> BuiltinSkiaImageGenerator::makeFromGenerator( | ||
std::unique_ptr<SkImageGenerator> generator) { | ||
if (!generator) { | ||
return nullptr; | ||
} | ||
return std::make_unique<BuiltinSkiaImageGenerator>(std::move(generator)); | ||
} | ||
|
||
BuiltinSkiaCodecImageGenerator::BuiltinSkiaCodecImageGenerator( | ||
std::unique_ptr<SkCodec> codec) | ||
: codec_generator_(static_cast<SkCodecImageGenerator*>( | ||
SkCodecImageGenerator::MakeFromCodec(std::move(codec)).release())) {} | ||
|
||
BuiltinSkiaCodecImageGenerator::BuiltinSkiaCodecImageGenerator( | ||
sk_sp<SkData> buffer) | ||
: codec_generator_(static_cast<SkCodecImageGenerator*>( | ||
SkCodecImageGenerator::MakeFromEncodedCodec(buffer).release())) {} | ||
|
||
const SkImageInfo& BuiltinSkiaCodecImageGenerator::getInfo() const { | ||
return codec_generator_->getInfo(); | ||
} | ||
|
||
bool BuiltinSkiaCodecImageGenerator::getPixels(const SkImageInfo& info, | ||
void* pixels, | ||
size_t rowBytes) const { | ||
return codec_generator_->getPixels(info, pixels, rowBytes); | ||
} | ||
|
||
SkISize BuiltinSkiaCodecImageGenerator::getScaledDimensions( | ||
float desiredScale) { | ||
return codec_generator_->getScaledDimensions(desiredScale); | ||
} | ||
|
||
std::unique_ptr<ImageGenerator> BuiltinSkiaCodecImageGenerator::makeFromData( | ||
sk_sp<SkData> data) { | ||
auto codec = SkCodec::MakeFromData(data); | ||
if (!codec) { | ||
return nullptr; | ||
} | ||
return std::make_unique<BuiltinSkiaCodecImageGenerator>(std::move(codec)); | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// 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_H_ | ||
#define FLUTTER_LIB_UI_PAINTING_IMAGE_GENERATOR_H_ | ||
|
||
#include "flutter/lib/ui/painting/codec.h" | ||
#include "third_party/skia/include/core/SkImageInfo.h" | ||
|
||
namespace flutter { | ||
|
||
/// The minimal interface necessary for creating decoders that can be used for | ||
/// single-frame image decoding with optional support for decoding into a | ||
/// subscaled buffer. | ||
/// | ||
/// See `getScaledDimensions` for details about how subpixel image decoding can | ||
/// be supported. | ||
class ImageGenerator { | ||
public: | ||
virtual ~ImageGenerator(){}; | ||
|
||
virtual const SkImageInfo& getInfo() const = 0; | ||
|
||
virtual bool getPixels(const SkImageInfo& info, | ||
void* pixels, | ||
size_t rowBytes) const = 0; | ||
|
||
/// Given a scale value, returns the closest image size that can be used for | ||
/// efficiently decoding the image. If subpixel image decoding is not | ||
/// supported by the codec, this method just returns the original image size. | ||
virtual SkISize getScaledDimensions(float scale) = 0; | ||
}; | ||
|
||
class BuiltinSkiaImageGenerator : public ImageGenerator { | ||
public: | ||
BuiltinSkiaImageGenerator(std::unique_ptr<SkImageGenerator> generator); | ||
|
||
~BuiltinSkiaImageGenerator() = default; | ||
|
||
const SkImageInfo& getInfo() const override; | ||
|
||
bool getPixels(const SkImageInfo& info, | ||
void* pixels, | ||
size_t rowBytes) const override; | ||
|
||
SkISize getScaledDimensions(float desiredScale) override; | ||
|
||
static std::unique_ptr<ImageGenerator> makeFromGenerator( | ||
std::unique_ptr<SkImageGenerator> generator); | ||
|
||
private: | ||
BuiltinSkiaImageGenerator() = delete; | ||
std::unique_ptr<SkImageGenerator> generator_; | ||
}; | ||
|
||
class BuiltinSkiaCodecImageGenerator : public ImageGenerator { | ||
public: | ||
BuiltinSkiaCodecImageGenerator(std::unique_ptr<SkCodec> codec); | ||
|
||
BuiltinSkiaCodecImageGenerator(sk_sp<SkData> buffer); | ||
|
||
~BuiltinSkiaCodecImageGenerator() = default; | ||
|
||
const SkImageInfo& getInfo() const override; | ||
|
||
bool getPixels(const SkImageInfo& info, | ||
void* pixels, | ||
size_t rowBytes) const override; | ||
|
||
SkISize getScaledDimensions(float desiredScale) override; | ||
|
||
static std::unique_ptr<ImageGenerator> makeFromData(sk_sp<SkData> data); | ||
|
||
private: | ||
BuiltinSkiaCodecImageGenerator() = delete; | ||
std::unique_ptr<SkCodecImageGenerator> codec_generator_; | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // FLUTTER_LIB_UI_PAINTING_IMAGE_GENERATOR_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// 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. | ||
|
||
#include <algorithm> | ||
|
||
#include "flutter/lib/ui/painting/image_generator_registry.h" | ||
#include "third_party/skia/include/codec/SkCodec.h" | ||
#include "third_party/skia/include/core/SkImageGenerator.h" | ||
#include "third_party/skia/src/codec/SkCodecImageGenerator.h" | ||
#ifdef OS_MACOSX | ||
#include "third_party/skia/include/ports/SkImageGeneratorCG.h" | ||
#elif OS_WIN | ||
#include "third_party/skia/include/ports/SkImageGeneratorWIC.h" | ||
#endif | ||
|
||
namespace flutter { | ||
|
||
ImageGeneratorRegistry::ImageGeneratorRegistry() : weak_factory_(this) { | ||
add( | ||
[](sk_sp<SkData> buffer) { | ||
return BuiltinSkiaCodecImageGenerator::makeFromData(buffer); | ||
}, | ||
0); | ||
|
||
#ifdef OS_MACOSX | ||
add( | ||
[](sk_sp<SkData> buffer) { | ||
auto generator = SkImageGeneratorCG::MakeFromEncodedCG(buffer); | ||
return BuiltinSkiaImageGenerator::makeFromGenerator( | ||
std::move(generator)); | ||
}, | ||
0); | ||
#elif OS_WIN | ||
add( | ||
[](sk_sp<SkData> buffer) { | ||
auto generator = SkImageGeneratorWIC::MakeFromEncodedWIC(buffer); | ||
return BuiltinSkiaImageGenerator::makeFromGenerator( | ||
std::move(generator)); | ||
}, | ||
0); | ||
#endif | ||
} | ||
|
||
void ImageGeneratorRegistry::add(ImageGeneratorFactory factory, | ||
int32_t priority) { | ||
image_generator_factories_.push_back({factory, priority}); | ||
std::stable_sort(image_generator_factories_.begin(), | ||
image_generator_factories_.end()); | ||
} | ||
|
||
std::unique_ptr<ImageGenerator> ImageGeneratorRegistry::createCompatible( | ||
sk_sp<SkData> buffer) { | ||
for (auto& factory : image_generator_factories_) { | ||
std::unique_ptr<ImageGenerator> result = factory.callback(buffer); | ||
if (result) { | ||
return result; | ||
} | ||
} | ||
return nullptr; | ||
} | ||
|
||
fml::WeakPtr<ImageGeneratorRegistry> ImageGeneratorRegistry::GetWeakPtr() | ||
const { | ||
return weak_factory_.GetWeakPtr(); | ||
} | ||
|
||
} // namespace flutter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// 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 <vector> | ||
|
||
#include "flutter/fml/mapping.h" | ||
#include "flutter/fml/memory/weak_ptr.h" | ||
#include "flutter/lib/ui/painting/image_generator.h" | ||
|
||
namespace flutter { | ||
|
||
/// 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: | ||
using ImageGeneratorFactory = | ||
std::function<std::unique_ptr<ImageGenerator>(sk_sp<SkData> buffer)>; | ||
|
||
ImageGeneratorRegistry(); | ||
|
||
~ImageGeneratorRegistry() = default; | ||
|
||
void add(ImageGeneratorFactory factory, int32_t priority); | ||
|
||
/// Walks the list of image generator builders in descending priority order | ||
/// until a compatible SkImageGenerator is able to be built. If no compatible | ||
/// image generator could be produced, `std::unique_ptr(nullptr)` is returned. | ||
std::unique_ptr<ImageGenerator> createCompatible(sk_sp<SkData> buffer); | ||
|
||
fml::WeakPtr<ImageGeneratorRegistry> GetWeakPtr() const; | ||
|
||
private: | ||
struct PrioritizedFactory_ { | ||
ImageGeneratorFactory callback; | ||
|
||
int32_t priority; | ||
|
||
// Order by descending priority. | ||
inline bool operator<(const PrioritizedFactory_& other) const { | ||
return priority > other.priority; | ||
} | ||
}; | ||
std::vector<PrioritizedFactory_> image_generator_factories_; | ||
fml::WeakPtrFactory<ImageGeneratorRegistry> weak_factory_; | ||
}; | ||
|
||
} // namespace flutter | ||
|
||
#endif // FLUTTER_LIB_UI_PAINTING_IMAGE_DECODER_H_ |
Oops, something went wrong.