1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_LIB_UI_PAINTING_MUTLI_FRAME_CODEC_H_
6#define FLUTTER_LIB_UI_PAINTING_MUTLI_FRAME_CODEC_H_
7
8#include "flutter/fml/macros.h"
9#include "flutter/lib/ui/painting/codec.h"
10#include "third_party/skia/src/codec/SkCodecImageGenerator.h"
11
12namespace flutter {
13
14class MultiFrameCodec : public Codec {
15 public:
16 MultiFrameCodec(std::shared_ptr<SkCodecImageGenerator> generator);
17
18 ~MultiFrameCodec() override;
19
20 // |Codec|
21 int frameCount() const override;
22
23 // |Codec|
24 int repetitionCount() const override;
25
26 // |Codec|
27 Dart_Handle getNextFrame(Dart_Handle args) override;
28
29 private:
30 // Captures the state shared between the IO and UI task runners.
31 //
32 // The state is initialized on the UI task runner when the Dart object is
33 // created. Decoding occurs on the IO task runner. Since it is possible for
34 // the UI object to be collected independently of the IO task runner work,
35 // it is not safe for this state to live directly on the MultiFrameCodec.
36 // Instead, the MultiFrameCodec creates this object when it is constructed,
37 // shares it with the IO task runner's decoding work, and sets the live_
38 // member to false when it is destructed.
39 struct State {
40 State(std::shared_ptr<SkCodecImageGenerator> generator);
41
42 const std::shared_ptr<SkCodecImageGenerator> generator_;
43 const int frameCount_;
44 const int repetitionCount_;
45
46 // The non-const members and functions below here are only read or written
47 // to on the IO thread. They are not safe to access or write on the UI
48 // thread.
49 int nextFrameIndex_;
50 // The last decoded frame that's required to decode any subsequent frames.
51 std::unique_ptr<SkBitmap> lastRequiredFrame_;
52
53 // The index of the last decoded required frame.
54 int lastRequiredFrameIndex_ = -1;
55
56 sk_sp<SkImage> GetNextFrameImage(
57 fml::WeakPtr<GrDirectContext> resourceContext);
58
59 void GetNextFrameAndInvokeCallback(
60 std::unique_ptr<DartPersistentValue> callback,
61 fml::RefPtr<fml::TaskRunner> ui_task_runner,
62 fml::WeakPtr<GrDirectContext> resourceContext,
63 fml::RefPtr<flutter::SkiaUnrefQueue> unref_queue,
64 size_t trace_id);
65 };
66
67 // Shared across the UI and IO task runners.
68 std::shared_ptr<State> state_;
69
70 FML_FRIEND_MAKE_REF_COUNTED(MultiFrameCodec);
71 FML_FRIEND_REF_COUNTED_THREAD_SAFE(MultiFrameCodec);
72};
73
74} // namespace flutter
75
76#endif // FLUTTER_LIB_UI_PAINTING_MUTLI_FRAME_CODEC_H_
77