blob: ef288f27bf4395258705ccf6693ec1ea7463ed58 [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_MUTLI_FRAME_CODEC_H_
#define FLUTTER_LIB_UI_PAINTING_MUTLI_FRAME_CODEC_H_
#include "flutter/fml/macros.h"
#include "flutter/lib/ui/painting/codec.h"
#include "flutter/lib/ui/painting/image_generator.h"
#include <utility>
using tonic::DartPersistentValue;
namespace flutter {
class MultiFrameCodec : public Codec {
public:
explicit MultiFrameCodec(std::shared_ptr<ImageGenerator> generator);
~MultiFrameCodec() override;
// |Codec|
int frameCount() const override;
// |Codec|
int repetitionCount() const override;
// |Codec|
Dart_Handle getNextFrame(Dart_Handle args) override;
private:
// Captures the state shared between the IO and UI task runners.
//
// The state is initialized on the UI task runner when the Dart object is
// created. Decoding occurs on the IO task runner. Since it is possible for
// the UI object to be collected independently of the IO task runner work,
// it is not safe for this state to live directly on the MultiFrameCodec.
// Instead, the MultiFrameCodec creates this object when it is constructed,
// shares it with the IO task runner's decoding work, and sets the live_
// member to false when it is destructed.
struct State {
explicit State(std::shared_ptr<ImageGenerator> generator);
const std::shared_ptr<ImageGenerator> generator_;
const int frameCount_;
const int repetitionCount_;
bool is_impeller_enabled_ = false;
// The non-const members and functions below here are only read or written
// to on the IO thread. They are not safe to access or write on the UI
// thread.
int nextFrameIndex_;
// The last decoded frame that's required to decode any subsequent frames.
std::optional<SkBitmap> lastRequiredFrame_;
// The index of the last decoded required frame.
int lastRequiredFrameIndex_ = -1;
// The rectangle that should be cleared if the previous frame's disposal
// method was kRestoreBGColor.
std::optional<SkIRect> restoreBGColorRect_;
std::pair<sk_sp<DlImage>, std::string> GetNextFrameImage(
fml::WeakPtr<GrDirectContext> resourceContext,
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
const std::shared_ptr<impeller::Context>& impeller_context,
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue);
void GetNextFrameAndInvokeCallback(
std::unique_ptr<DartPersistentValue> callback,
const fml::RefPtr<fml::TaskRunner>& ui_task_runner,
fml::WeakPtr<GrDirectContext> resourceContext,
fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue,
const std::shared_ptr<const fml::SyncSwitch>& gpu_disable_sync_switch,
size_t trace_id,
const std::shared_ptr<impeller::Context>& impeller_context);
};
// Shared across the UI and IO task runners.
std::shared_ptr<State> state_;
FML_FRIEND_MAKE_REF_COUNTED(MultiFrameCodec);
FML_FRIEND_REF_COUNTED_THREAD_SAFE(MultiFrameCodec);
};
} // namespace flutter
#endif // FLUTTER_LIB_UI_PAINTING_MUTLI_FRAME_CODEC_H_