10#include <android/bitmap.h>
15#include "third_party/skia/include/codec/SkCodecAnimation.h"
24AndroidImageGenerator::AndroidImageGenerator(sk_sp<SkData>
data)
25 : data_(
std::move(
data)), image_info_(SkImageInfo::MakeUnknown(-1, -1)) {}
27const SkImageInfo& AndroidImageGenerator::GetInfo() {
28 header_decoded_latch_.Wait();
32unsigned int AndroidImageGenerator::GetFrameCount()
const {
36unsigned int AndroidImageGenerator::GetPlayCount()
const {
41 unsigned int frame_index) {
44 .disposal_method = SkCodecAnimation::DisposalMethod::kKeep};
47SkISize AndroidImageGenerator::GetScaledDimensions(
float desired_scale) {
48 return GetInfo().dimensions();
51bool AndroidImageGenerator::GetPixels(
const SkImageInfo& info,
54 unsigned int frame_index,
55 std::optional<unsigned int> prior_frame) {
56 fully_decoded_latch_.Wait();
58 if (!software_decoded_data_) {
62 if (kRGBA_8888_SkColorType != info.colorType()) {
66 switch (info.alphaType()) {
67 case kOpaque_SkAlphaType:
68 if (kOpaque_SkAlphaType != GetInfo().alphaType()) {
72 case kPremul_SkAlphaType:
82 size_t pixels_size = info.computeByteSize(row_bytes);
83 if (pixels_size ==
SIZE_MAX || pixels_size < software_decoded_data_->
size()) {
86 memcpy(pixels, software_decoded_data_->data(),
87 software_decoded_data_->size());
91void AndroidImageGenerator::DecodeImage() {
94 header_decoded_latch_.Signal();
95 fully_decoded_latch_.Signal();
98void AndroidImageGenerator::DoDecodeImage() {
110 jobject direct_buffer =
111 env->NewDirectByteBuffer(
const_cast<void*
>(data_->data()), data_->size());
113 auto bitmap = std::make_unique<fml::jni::ScopedJavaGlobalRef<jobject>>(
115 g_decode_image_method, direct_buffer,
116 reinterpret_cast<jlong
>(
this)));
123 AndroidBitmapInfo info;
124 [[maybe_unused]]
int status;
125 if ((status = AndroidBitmap_getInfo(env,
bitmap->obj(), &info)) < 0) {
126 FML_DLOG(ERROR) <<
"Failed to get bitmap info, status=" << status;
129 FML_DCHECK(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888);
134 if ((status = AndroidBitmap_lockPixels(env,
bitmap->obj(), &pixel_lock)) <
136 FML_DLOG(ERROR) <<
"Failed to lock pixels, error=" << status;
140 SkData::ReleaseProc on_release = [](
const void* ptr,
void*
context) ->
void {
144 AndroidBitmap_unlockPixels(env,
bitmap->obj());
148 software_decoded_data_ = SkData::MakeWithProc(
149 pixel_lock, info.width * info.height *
sizeof(uint32_t), on_release,
153bool AndroidImageGenerator::Register(JNIEnv* env) {
155 env, env->FindClass(
"io/flutter/embedding/engine/FlutterJNI"));
160 "(Ljava/nio/ByteBuffer;J)Landroid/graphics/Bitmap;");
163 static const JNINativeMethod header_decoded_method = {
164 .name =
"nativeImageHeaderCallback",
165 .signature =
"(JII)V",
166 .fnPtr =
reinterpret_cast<void*
>(
167 &AndroidImageGenerator::NativeImageHeaderCallback),
172 <<
"Failed to register FlutterJNI.nativeImageHeaderCallback method";
179std::shared_ptr<ImageGenerator> AndroidImageGenerator::MakeFromData(
182 std::shared_ptr<AndroidImageGenerator> generator(
186 task_runner, [generator]() { generator->DecodeImage(); });
188 if (generator->IsValidImageData()) {
195std::shared_ptr<AndroidImageGenerator> AndroidImageGenerator::MakeForTesting(
196 const SkImageInfo& header_info,
197 sk_sp<SkData> decoded_data) {
198 std::shared_ptr<AndroidImageGenerator> generator(
200 generator->image_info_ = header_info;
201 generator->software_decoded_data_ = std::move(decoded_data);
202 generator->header_decoded_latch_.Signal();
203 generator->fully_decoded_latch_.Signal();
207void AndroidImageGenerator::NativeImageHeaderCallback(JNIEnv* env,
209 jlong generator_address,
215 generator->image_info_ = SkImageInfo::Make(
216 width,
height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
217 generator->header_decoded_latch_.
Signal();
220bool AndroidImageGenerator::IsValidImageData() {
226 return GetInfo().height() != -1;
static void RunNowOrPostTask(const fml::RefPtr< fml::TaskRunner > &runner, const fml::closure &task)
#define FML_DLOG(severity)
#define FML_LOG(severity)
#define FML_CHECK(condition)
#define FML_DCHECK(condition)
std::shared_ptr< SkBitmap > bitmap
static jmethodID g_decode_image_method
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
static fml::jni::ScopedJavaGlobalRef< jclass > * g_flutter_jni_class
JNIEnv * AttachCurrentThread()
bool CheckException(JNIEnv *env)
std::shared_ptr< ContextGLES > context
Info about a single frame in the context of a multi-frame image, useful for animation and blending.
std::optional< unsigned int > required_frame