5#include "flutter/lib/ui/painting/image_decoder_skia.h"
9#include "flutter/fml/logging.h"
10#include "flutter/fml/make_copyable.h"
11#include "flutter/lib/ui/painting/display_list_image_gpu.h"
20 std::shared_ptr<fml::ConcurrentTaskRunner> concurrent_task_runner,
23 std::move(concurrent_task_runner),
24 std::move(io_manager)) {}
29 const SkISize& resized_dimensions,
34 flow.
Step(__FUNCTION__);
36 if (resized_dimensions.
isEmpty()) {
37 FML_LOG(
ERROR) <<
"Could not resize to empty dimensions.";
45 const auto scaled_image_info =
50 FML_LOG(
ERROR) <<
"Failed to allocate memory for bitmap of size "
51 << scaled_image_info.computeMinByteSize() <<
"B";
69 FML_LOG(
ERROR) <<
"Could not create a scaled image from a scaled bitmap.";
78 uint32_t target_width,
79 uint32_t target_height,
82 flow.
Step(__FUNCTION__);
87 FML_LOG(
ERROR) <<
"Could not create image from decompressed bytes.";
91 if (!target_width && !target_height) {
102 uint32_t target_width,
103 uint32_t target_height,
106 flow.
Step(__FUNCTION__);
108 if (!descriptor->
should_resize(target_width, target_height)) {
115 const SkISize resized_dimensions = {
static_cast<int32_t
>(target_width),
116 static_cast<int32_t
>(target_height)};
119 std::max(
static_cast<float>(resized_dimensions.
width()) /
120 source_dimensions.
width(),
121 static_cast<float>(resized_dimensions.
height()) /
122 source_dimensions.
height()));
126 if (decode_dimensions != source_dimensions) {
127 auto scaled_image_info =
132 FML_LOG(
ERROR) <<
"Failed to allocate memory for bitmap of size "
133 << scaled_image_info.computeMinByteSize() <<
"B";
137 const auto& pixmap = scaled_bitmap.
pixmap();
145 if (!decoded_image) {
147 <<
"Could not create a scaled image from a scaled bitmap.";
167 flow.
Step(__FUNCTION__);
173 if (!io_manager->GetResourceContext() || !io_manager->GetSkiaUnrefQueue()) {
175 <<
"Could not acquire context of release queue for texture upload.";
181 FML_LOG(
ERROR) <<
"Could not peek pixels of image for texture upload.";
186 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
196 result = {std::move(texture_image),
nullptr};
198 .SetIfFalse([&
result, context = io_manager->GetResourceContext(),
199 &pixmap,
queue = io_manager->GetSkiaUnrefQueue()] {
200 TRACE_EVENT0(
"flutter",
"MakeCrossContextImageFromPixmap");
208 if (!texture_image) {
221 uint32_t target_width,
222 uint32_t target_height,
240 auto raw_descriptor = descriptor_ref_ptr.
get();
241 raw_descriptor->AddRef();
252 flow = std::move(flow)]()
mutable {
258 raw_descriptor->Release();
262 if (!raw_descriptor->data() || raw_descriptor->data()->size() == 0) {
263 result({}, std::move(flow));
272 target_width = target_width,
273 target_height = target_height,
274 flow = std::move(flow)
279 auto decompressed = raw_descriptor->is_compressed()
280 ? ImageFromCompressedData(raw_descriptor,
284 : ImageFromDecompressedData(raw_descriptor,
290 FML_DLOG(ERROR) <<
"Could not decompress image.";
291 result({}, std::move(flow));
300 std::move(flow)]()
mutable {
302 FML_DLOG(ERROR) <<
"Could not acquire IO manager.";
303 result({}, std::move(flow));
310 if (!io_manager->GetResourceContext()) {
311 result({std::move(decompressed), io_manager->GetSkiaUnrefQueue()},
319 if (!uploaded.skia_object()) {
321 result({}, std::move(flow));
326 result(std::move(uploaded), std::move(flow));
static void SkSafeUnref(T *obj)
static T * SkSafeRef(T *obj)
const SkPixmap & pixmap() const
bool tryAllocPixels(const SkImageInfo &info, size_t rowBytes)
sk_sp< SkImage > makeRasterImage(GrDirectContext *, CachingHint cachingHint=kDisallow_CachingHint) const
const SkImageInfo & imageInfo() const
SkISize dimensions() const
bool peekPixels(SkPixmap *pixmap) const
virtual bool isTextureBacked() const =0
@ kDisallow_CachingHint
disallows internally caching decoded and copied pixels
bool scalePixels(const SkPixmap &dst, const SkSamplingOptions &, CachingHint cachingHint=kAllow_CachingHint) const
static sk_sp< DlImageGPU > Make(SkiaGPUObject< SkImage > image)
ImageDecoderSkia(const TaskRunners &runners, std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner, fml::WeakPtr< IOManager > io_manager)
void Decode(fml::RefPtr< ImageDescriptor > descriptor, uint32_t target_width, uint32_t target_height, const ImageResult &result) override
~ImageDecoderSkia() override
static sk_sp< SkImage > ImageFromCompressedData(ImageDescriptor *descriptor, uint32_t target_width, uint32_t target_height, const fml::tracing::TraceFlow &flow)
std::function< void(sk_sp< DlImage >, std::string)> ImageResult
std::shared_ptr< fml::ConcurrentTaskRunner > concurrent_task_runner_
fml::WeakPtr< IOManager > io_manager_
Creates an image descriptor for encoded or decoded image data, describing the width,...
sk_sp< SkImage > image() const
const SkImageInfo & image_info() const
The orientation corrected image info for this image.
SkISize get_scaled_dimensions(float scale)
Gets the scaled dimensions of this image, if backed by an ImageGenerator that can perform efficient s...
int row_bytes() const
The byte length of the first row of the image. Defaults to width() * 4.
bool should_resize(int target_width, int target_height) const
Whether the given target_width or target_height differ from width() and height() respectively.
bool get_pixels(const SkPixmap &pixmap) const
Gets pixels for this image transformed based on the EXIF orientation tag, if applicable.
sk_sp< SkData > data() const
The underlying buffer for this image.
fml::RefPtr< fml::TaskRunner > GetUITaskRunner() const
fml::RefPtr< fml::TaskRunner > GetIOTaskRunner() const
virtual bool RunsTasksOnCurrentThread()
void End(const char *label=nullptr)
void Step(const char *label=nullptr) const
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_DCHECK(condition)
SK_API sk_sp< SkImage > RasterFromData(const SkImageInfo &info, sk_sp< SkData > pixels, size_t rowBytes)
SK_API sk_sp< SkImage > RasterFromPixmap(const SkPixmap &pixmap, RasterReleaseProc rasterReleaseProc, ReleaseContext releaseContext)
SK_API sk_sp< SkImage > CrossContextTextureFromPixmap(GrDirectContext *context, const SkPixmap &pixmap, bool buildMips, bool limitToMaxTextureSize=false)
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
static SkiaGPUObject< SkImage > UploadRasterImage(sk_sp< SkImage > image, const fml::WeakPtr< IOManager > &io_manager, const fml::tracing::TraceFlow &flow)
static sk_sp< SkImage > ResizeRasterImage(const sk_sp< SkImage > &image, const SkISize &resized_dimensions, const fml::tracing::TraceFlow &flow)
static sk_sp< SkImage > ImageFromDecompressedData(ImageDescriptor *descriptor, uint32_t target_width, uint32_t target_height, const fml::tracing::TraceFlow &flow)
internal::CopyableLambda< T > MakeCopyable(T lambda)
static constexpr SkISize Make(int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
SkImageInfo makeDimensions(SkISize newSize) const
SkISize dimensions() const
Represents the 2 code paths available when calling |SyncSwitchExecute|.
#define TRACE_EVENT0(category_group, name)