7#include "flutter/lib/ui/painting/image_decoder_skia.h"
11#include "flutter/fml/logging.h"
12#include "flutter/fml/make_copyable.h"
13#include "flutter/lib/ui/painting/display_list_image_gpu.h"
22 std::shared_ptr<fml::ConcurrentTaskRunner> concurrent_task_runner,
25 std::move(concurrent_task_runner),
26 std::move(io_manager)) {}
31 const SkISize& resized_dimensions,
36 flow.
Step(__FUNCTION__);
38 if (resized_dimensions.
isEmpty()) {
39 FML_LOG(
ERROR) <<
"Could not resize to empty dimensions.";
47 const auto scaled_image_info =
52 FML_LOG(
ERROR) <<
"Failed to allocate memory for bitmap of size "
53 << scaled_image_info.computeMinByteSize() <<
"B";
71 FML_LOG(
ERROR) <<
"Could not create a scaled image from a scaled bitmap.";
80 uint32_t target_width,
81 uint32_t target_height,
84 flow.
Step(__FUNCTION__);
89 FML_LOG(
ERROR) <<
"Could not create image from decompressed bytes.";
93 if (!target_width && !target_height) {
104 uint32_t target_width,
105 uint32_t target_height,
108 flow.
Step(__FUNCTION__);
110 if (!descriptor->
should_resize(target_width, target_height)) {
117 const SkISize resized_dimensions = {
static_cast<int32_t
>(target_width),
118 static_cast<int32_t
>(target_height)};
122 source_dimensions.
width(),
123 static_cast<float>(resized_dimensions.
height()) /
124 source_dimensions.
height()));
128 if (decode_dimensions != source_dimensions) {
129 auto scaled_image_info =
134 FML_LOG(
ERROR) <<
"Failed to allocate memory for bitmap of size "
135 << scaled_image_info.computeMinByteSize() <<
"B";
139 const auto& pixmap = scaled_bitmap.
pixmap();
147 if (!decoded_image) {
149 <<
"Could not create a scaled image from a scaled bitmap.";
169 flow.
Step(__FUNCTION__);
175 if (!io_manager->GetResourceContext() || !io_manager->GetSkiaUnrefQueue()) {
177 <<
"Could not acquire context of release queue for texture upload.";
183 FML_LOG(
ERROR) <<
"Could not peek pixels of image for texture upload.";
188 io_manager->GetIsGpuDisabledSyncSwitch()->Execute(
198 result = {std::move(texture_image),
nullptr};
200 .SetIfFalse([&
result, context = io_manager->GetResourceContext(),
201 &pixmap,
queue = io_manager->GetSkiaUnrefQueue()] {
202 TRACE_EVENT0(
"flutter",
"MakeCrossContextImageFromPixmap");
210 if (!texture_image) {
223 uint32_t target_width,
224 uint32_t target_height,
242 auto raw_descriptor = descriptor_ref_ptr.
get();
243 raw_descriptor->AddRef();
254 flow = std::move(flow)]()
mutable {
260 raw_descriptor->Release();
264 if (!raw_descriptor->data() || raw_descriptor->data()->size() == 0) {
265 result({}, std::move(flow));
274 target_width = target_width,
275 target_height = target_height,
276 flow = std::move(flow)
281 auto decompressed = raw_descriptor->is_compressed()
282 ? ImageFromCompressedData(raw_descriptor,
286 : ImageFromDecompressedData(raw_descriptor,
292 FML_DLOG(ERROR) <<
"Could not decompress image.";
293 result({}, std::move(flow));
302 std::move(flow)]()
mutable {
304 FML_DLOG(ERROR) <<
"Could not acquire IO manager.";
305 result({}, std::move(flow));
312 if (!io_manager->GetResourceContext()) {
313 result({std::move(decompressed), io_manager->GetSkiaUnrefQueue()},
321 if (!uploaded.skia_object()) {
323 result({}, std::move(flow));
328 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)
static float max(float r, float g, float b)
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)
sk_sp< const SkImage > image
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 |SyncSwitch::Execute|.
#define TRACE_EVENT0(category_group, name)