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 | |
12 | namespace flutter { |
13 | |
14 | class 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 | |