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_FLOW_SURFACE_FRAME_H_ |
6 | #define FLUTTER_FLOW_SURFACE_FRAME_H_ |
7 | |
8 | #include <memory> |
9 | #include <optional> |
10 | |
11 | #include "flutter/common/graphics/gl_context_switch.h" |
12 | #include "flutter/display_list/dl_builder.h" |
13 | #include "flutter/display_list/skia/dl_sk_canvas.h" |
14 | #include "flutter/fml/macros.h" |
15 | #include "flutter/fml/time/time_point.h" |
16 | |
17 | #include "third_party/skia/include/core/SkCanvas.h" |
18 | #include "third_party/skia/include/core/SkSurface.h" |
19 | |
20 | namespace flutter { |
21 | |
22 | // This class represents a frame that has been fully configured for the |
23 | // underlying client rendering API. A frame may only be submitted once. |
24 | class SurfaceFrame { |
25 | public: |
26 | using SubmitCallback = |
27 | std::function<bool(SurfaceFrame& surface_frame, DlCanvas* canvas)>; |
28 | |
29 | // Information about the underlying framebuffer |
30 | struct FramebufferInfo { |
31 | // Indicates whether or not the surface supports pixel readback as used in |
32 | // circumstances such as a BackdropFilter. |
33 | bool supports_readback = false; |
34 | |
35 | // Indicates that target device supports partial repaint. At very minimum |
36 | // this means that the surface will provide valid existing damage. |
37 | bool supports_partial_repaint = false; |
38 | |
39 | // For some targets it may be beneficial or even required to snap clip |
40 | // rect to tile grid. I.e. repainting part of a tile may cause performance |
41 | // degradation if the tile needs to be decompressed first. |
42 | int vertical_clip_alignment = 1; |
43 | int horizontal_clip_alignment = 1; |
44 | |
45 | // This is the area of framebuffer that lags behind the front buffer. |
46 | // |
47 | // Correctly providing exiting_damage is necessary for supporting double and |
48 | // triple buffering. Embedder is responsible for tracking this area for each |
49 | // of the back buffers used. When doing partial redraw, this area will be |
50 | // repainted alongside of dirty area determined by diffing current and |
51 | // last successfully rasterized layer tree; |
52 | // |
53 | // If existing damage is unspecified (nullopt), entire frame will be |
54 | // rasterized (no partial redraw). To signal that there is no existing |
55 | // damage use an empty SkIRect. |
56 | std::optional<SkIRect> existing_damage = std::nullopt; |
57 | }; |
58 | |
59 | SurfaceFrame(sk_sp<SkSurface> surface, |
60 | FramebufferInfo framebuffer_info, |
61 | const SubmitCallback& submit_callback, |
62 | SkISize frame_size, |
63 | std::unique_ptr<GLContextResult> context_result = nullptr, |
64 | bool display_list_fallback = false); |
65 | |
66 | struct SubmitInfo { |
67 | // The frame damage for frame n is the difference between frame n and |
68 | // frame (n-1), and represents the area that a compositor must recompose. |
69 | // |
70 | // Corresponds to EGL_KHR_swap_buffers_with_damage |
71 | std::optional<SkIRect> frame_damage; |
72 | |
73 | // The buffer damage for a frame is the area changed since that same buffer |
74 | // was last used. If the buffer has not been used before, the buffer damage |
75 | // is the entire area of the buffer. |
76 | // |
77 | // Corresponds to EGL_KHR_partial_update |
78 | std::optional<SkIRect> buffer_damage; |
79 | |
80 | // Time at which this frame is scheduled to be presented. This is a hint |
81 | // that can be passed to the platform to drop queued frames. |
82 | std::optional<fml::TimePoint> presentation_time; |
83 | }; |
84 | |
85 | bool Submit(); |
86 | |
87 | bool IsSubmitted() const; |
88 | |
89 | sk_sp<SkSurface> SkiaSurface() const; |
90 | |
91 | DlCanvas* Canvas(); |
92 | |
93 | const FramebufferInfo& framebuffer_info() const { return framebuffer_info_; } |
94 | |
95 | void set_submit_info(const SubmitInfo& submit_info) { |
96 | submit_info_ = submit_info; |
97 | } |
98 | const SubmitInfo& submit_info() const { return submit_info_; } |
99 | |
100 | sk_sp<DisplayList> BuildDisplayList(); |
101 | |
102 | private: |
103 | bool submitted_ = false; |
104 | |
105 | DlSkCanvasAdapter adapter_; |
106 | sk_sp<DisplayListBuilder> dl_builder_; |
107 | sk_sp<SkSurface> surface_; |
108 | DlCanvas* canvas_ = nullptr; |
109 | FramebufferInfo framebuffer_info_; |
110 | SubmitInfo submit_info_; |
111 | SubmitCallback submit_callback_; |
112 | std::unique_ptr<GLContextResult> context_result_; |
113 | |
114 | bool PerformSubmit(); |
115 | |
116 | FML_DISALLOW_COPY_AND_ASSIGN(SurfaceFrame); |
117 | }; |
118 | |
119 | } // namespace flutter |
120 | |
121 | #endif // FLUTTER_FLOW_SURFACE_FRAME_H_ |
122 | |