// 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_
