blob: f73180baaec308c68fed1b03237143d56783f5a8 [file] [log] [blame]
revemanb195f41d2015-11-19 22:16:481// Copyright 2015 The Chromium 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 COMPONENTS_EXO_SURFACE_H_
6#define COMPONENTS_EXO_SURFACE_H_
7
8#include <list>
reveman70baca12016-05-31 20:35:309#include <set>
reveman27fe2642015-11-20 06:33:3910#include <utility>
revemanb195f41d2015-11-19 22:16:4811
12#include "base/callback.h"
13#include "base/macros.h"
jbaumanbd9586a92016-05-28 01:09:0314#include "base/memory/ref_counted.h"
revemanb195f41d2015-11-19 22:16:4815#include "base/memory/weak_ptr.h"
reveman27fe2642015-11-20 06:33:3916#include "base/observer_list.h"
danakjc7afae52017-06-20 21:12:4117#include "components/exo/layer_tree_frame_sink_holder.h"
David Reveman93f67c02017-09-06 03:23:0818#include "components/exo/surface_delegate.h"
Fady Samuelc645ffe2017-07-24 17:28:2019#include "components/viz/common/frame_sinks/begin_frame_source.h"
Fady Samuel4f7f0fb32017-07-28 15:33:3720#include "components/viz/common/resources/transferable_resource.h"
reedcc9c70f2016-11-22 04:26:0121#include "third_party/skia/include/core/SkBlendMode.h"
revemanb195f41d2015-11-19 22:16:4822#include "third_party/skia/include/core/SkRegion.h"
reveman4c94cf962015-12-03 06:49:4323#include "ui/aura/window.h"
revemanb195f41d2015-11-19 22:16:4824#include "ui/gfx/geometry/rect.h"
revemane295c662017-01-30 23:01:2125#include "ui/gfx/native_widget_types.h"
revemanb195f41d2015-11-19 22:16:4826
27namespace base {
28namespace trace_event {
29class TracedValue;
30}
31}
32
Peng Huang583c9dc62017-07-27 23:38:2833namespace cc {
34class CompositorFrame;
35}
36
reveman2966d7702016-02-12 02:09:5437namespace gfx {
38class Path;
39}
40
revemanb195f41d2015-11-19 22:16:4841namespace exo {
42class Buffer;
Peng Huang583c9dc62017-07-27 23:38:2843class LayerTreeFrameSinkHolder;
reveman70baca12016-05-31 20:35:3044class Pointer;
reveman27fe2642015-11-20 06:33:3945class SurfaceObserver;
jbaumanbd9586a92016-05-28 01:09:0346class Surface;
47
jbaumanb362a892016-06-17 03:30:5648namespace subtle {
49class PropertyHelper;
50}
51
David Revemanfca309b2017-08-24 18:18:1152// Counter-clockwise rotations.
53enum class Transform { NORMAL, ROTATE_90, ROTATE_180, ROTATE_270 };
54
reveman70baca12016-05-31 20:35:3055// The pointer class is currently the only cursor provider class but this can
56// change in the future when better hardware cursor support is added.
57using CursorProvider = Pointer;
58
revemanb195f41d2015-11-19 22:16:4859// This class represents a rectangular area that is displayed on the screen.
60// It has a location, size and pixel contents.
Hans Wennborgaf90ff12017-09-04 19:46:0261class Surface final : public ui::PropertyHandler {
revemanb195f41d2015-11-19 22:16:4862 public:
reveman2d3815d2016-06-26 20:13:2563 using PropertyDeallocator = void (*)(int64_t value);
jbaumanb362a892016-06-17 03:30:5664
revemanb195f41d2015-11-19 22:16:4865 Surface();
Peng Huang583c9dc62017-07-27 23:38:2866 ~Surface();
revemanb195f41d2015-11-19 22:16:4867
reveman39b32c872015-12-08 05:34:0568 // Type-checking downcast routine.
kinabad14ca03e2016-02-23 04:43:3569 static Surface* AsSurface(const aura::Window* window);
reveman39b32c872015-12-08 05:34:0570
jbaumane3526252016-06-09 18:43:0571 aura::Window* window() { return window_.get(); }
72
revemanb195f41d2015-11-19 22:16:4873 // Set a buffer as the content of this surface. A buffer can only be attached
74 // to one surface at a time.
75 void Attach(Buffer* buffer);
76
77 // Describe the regions where the pending buffer is different from the
78 // current surface contents, and where the surface therefore needs to be
79 // repainted.
80 void Damage(const gfx::Rect& rect);
81
reveman211cf802017-01-10 00:30:5982 // Request notification when it's a good time to produce a new frame. Useful
83 // for throttling redrawing operations, and driving animations.
revemanb195f41d2015-11-19 22:16:4884 using FrameCallback = base::Callback<void(base::TimeTicks frame_time)>;
85 void RequestFrameCallback(const FrameCallback& callback);
86
reveman211cf802017-01-10 00:30:5987 // Request notification when the next frame is displayed. Useful for
88 // throttling redrawing operations, and driving animations.
89 using PresentationCallback =
90 base::Callback<void(base::TimeTicks presentation_time,
91 base::TimeDelta refresh)>;
92 void RequestPresentationCallback(const PresentationCallback& callback);
93
revemanb195f41d2015-11-19 22:16:4894 // This sets the region of the surface that contains opaque content.
95 void SetOpaqueRegion(const SkRegion& region);
96
reveman2966d7702016-02-12 02:09:5497 // This sets the region of the surface that can receive pointer and touch
98 // events.
99 void SetInputRegion(const SkRegion& region);
100
reveman7efa4b02016-01-06 08:29:54101 // This sets the scaling factor used to interpret the contents of the buffer
102 // attached to the surface. Note that if the scale is larger than 1, then you
103 // have to attach a buffer that is larger (by a factor of scale in each
104 // dimension) than the desired surface size.
105 void SetBufferScale(float scale);
106
David Revemanfca309b2017-08-24 18:18:11107 // This sets the transformation used to interpret the contents of the buffer
108 // attached to the surface.
109 void SetBufferTransform(Transform transform);
110
reveman27fe2642015-11-20 06:33:39111 // Functions that control sub-surface state. All sub-surface state is
112 // double-buffered and will be applied when Commit() is called.
113 void AddSubSurface(Surface* sub_surface);
114 void RemoveSubSurface(Surface* sub_surface);
115 void SetSubSurfacePosition(Surface* sub_surface, const gfx::Point& position);
116 void PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference);
117 void PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling);
118
reveman642d8c332016-02-19 19:55:44119 // This sets the surface viewport for scaling.
120 void SetViewport(const gfx::Size& viewport);
121
reveman8e323902016-05-23 21:55:36122 // This sets the surface crop rectangle.
123 void SetCrop(const gfx::RectF& crop);
124
reveman85b7a562016-03-17 23:27:32125 // This sets the only visible on secure output flag, preventing it from
126 // appearing in screenshots or from being viewed on non-secure displays.
127 void SetOnlyVisibleOnSecureOutput(bool only_visible_on_secure_output);
128
revemanfca687e2016-05-10 21:44:48129 // This sets the blend mode that will be used when drawing the surface.
reedcc9c70f2016-11-22 04:26:01130 void SetBlendMode(SkBlendMode blend_mode);
revemanfca687e2016-05-10 21:44:48131
132 // This sets the alpha value that will be applied to the whole surface.
133 void SetAlpha(float alpha);
134
David Reveman93f67c02017-09-06 03:23:08135 // Request that surface should have the specified frame type.
136 void SetFrame(SurfaceFrameType type);
137
revemanb195f41d2015-11-19 22:16:48138 // Surface state (damage regions, attached buffers, etc.) is double-buffered.
139 // A Commit() call atomically applies all pending state, replacing the
reveman27fe2642015-11-20 06:33:39140 // current state. Commit() is not guaranteed to be synchronous. See
141 // CommitSurfaceHierarchy() below.
revemanb195f41d2015-11-19 22:16:48142 void Commit();
143
reveman27fe2642015-11-20 06:33:39144 // This will synchronously commit all pending state of the surface and its
145 // descendants by recursively calling CommitSurfaceHierarchy() for each
146 // sub-surface with pending state.
Peng Huang583c9dc62017-07-27 23:38:28147 void CommitSurfaceHierarchy(
148 const gfx::Point& origin,
Peng Huang583c9dc62017-07-27 23:38:28149 std::list<FrameCallback>* frame_callbacks,
150 std::list<PresentationCallback>* presentation_callbacks);
reveman27fe2642015-11-20 06:33:39151
Peng Huang76f5fd02017-09-01 00:59:39152 void AppendSurfaceHierarchyContentsToFrame(
153 const gfx::Point& origin,
154 float device_scale_factor,
155 LayerTreeFrameSinkHolder* frame_sink_holder,
156 cc::CompositorFrame* frame);
157
reveman27fe2642015-11-20 06:33:39158 // Returns true if surface is in synchronized mode.
159 bool IsSynchronized() const;
160
revemanb9470762016-04-10 03:49:24161 // Returns the bounds of the current input region of surface.
162 gfx::Rect GetHitTestBounds() const;
reveman2966d7702016-02-12 02:09:54163
164 // Returns true if |rect| intersects this surface's bounds.
165 bool HitTestRect(const gfx::Rect& rect) const;
166
167 // Returns true if the current input region is different than the surface
168 // bounds.
169 bool HasHitTestMask() const;
170
171 // Returns the current input region of surface in the form of a hit-test mask.
172 void GetHitTestMask(gfx::Path* mask) const;
reveman4c94cf962015-12-03 06:49:43173
reveman70baca12016-05-31 20:35:30174 // Surface does not own cursor providers. It is the responsibility of the
175 // caller to remove the cursor provider before it is destroyed.
176 void RegisterCursorProvider(CursorProvider* provider);
177 void UnregisterCursorProvider(CursorProvider* provider);
178
revemane295c662017-01-30 23:01:21179 // Returns the cursor for the surface. If no cursor provider is registered
ergeeba7c622017-04-25 18:06:16180 // then CursorType::kNull is returned.
revemane295c662017-01-30 23:01:21181 gfx::NativeCursor GetCursor();
reveman70baca12016-05-31 20:35:30182
revemanb195f41d2015-11-19 22:16:48183 // Set the surface delegate.
184 void SetSurfaceDelegate(SurfaceDelegate* delegate);
185
reveman27fe2642015-11-20 06:33:39186 // Returns true if surface has been assigned a surface delegate.
187 bool HasSurfaceDelegate() const;
188
189 // Surface does not own observers. It is the responsibility of the observer
190 // to remove itself when it is done observing.
191 void AddSurfaceObserver(SurfaceObserver* observer);
192 void RemoveSurfaceObserver(SurfaceObserver* observer);
193 bool HasSurfaceObserver(const SurfaceObserver* observer) const;
194
revemanb195f41d2015-11-19 22:16:48195 // Returns a trace value representing the state of the surface.
dcheng31759da2016-04-21 01:26:31196 std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
revemanb195f41d2015-11-19 22:16:48197
eseckler599d86bb2017-03-15 09:02:55198 // Called when the begin frame source has changed.
Fady Samuelc645ffe2017-07-24 17:28:20199 void SetBeginFrameSource(viz::BeginFrameSource* begin_frame_source);
jbaumanbd9586a92016-05-28 01:09:03200
reveman15aee282016-11-04 19:09:20201 // Returns the active contents size.
Peng Huangb07b0652017-06-27 17:25:22202 const gfx::Size& content_size() const { return content_size_; }
jbaumanb362a892016-06-17 03:30:56203
kaznacheev8e270592017-05-25 06:13:26204 // Returns true if the associated window is in 'stylus-only' mode.
205 bool IsStylusOnly();
206
207 // Enables 'stylus-only' mode for the associated window.
208 void SetStylusOnly();
209
Peng Huangc51f7aba2017-09-05 16:00:39210 // Notify surface that resources and subsurfaces' resources have been lost.
211 void SurfaceHierarchyResourcesLost();
reveman15aee282016-11-04 19:09:20212
Peng Huang583c9dc62017-07-27 23:38:28213 // Returns true if the surface's bounds should be filled opaquely.
214 bool FillsBoundsOpaquely() const;
reveman211cf802017-01-10 00:30:59215
reveman15aee282016-11-04 19:09:20216 bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
217 return pending_damage_.contains(gfx::RectToSkIRect(damage));
218 }
219
revemanb195f41d2015-11-19 22:16:48220 private:
jbaumanf4c3f292016-06-11 00:57:33221 struct State {
222 State();
223 ~State();
224
225 bool operator==(const State& other);
226 bool operator!=(const State& other) { return !(*this == other); }
227
228 SkRegion opaque_region;
229 SkRegion input_region;
reveman2d3815d2016-06-26 20:13:25230 float buffer_scale = 1.0f;
David Revemanfca309b2017-08-24 18:18:11231 Transform buffer_transform = Transform::NORMAL;
jbaumanf4c3f292016-06-11 00:57:33232 gfx::Size viewport;
233 gfx::RectF crop;
234 bool only_visible_on_secure_output = false;
reedcc9c70f2016-11-22 04:26:01235 SkBlendMode blend_mode = SkBlendMode::kSrcOver;
jbaumanf4c3f292016-06-11 00:57:33236 float alpha = 1.0f;
jbauman45c06862016-06-23 19:35:02237 };
238 class BufferAttachment {
239 public:
240 BufferAttachment();
241 ~BufferAttachment();
242
243 BufferAttachment& operator=(BufferAttachment&& buffer);
244
245 base::WeakPtr<Buffer>& buffer();
246 const base::WeakPtr<Buffer>& buffer() const;
247 void Reset(base::WeakPtr<Buffer> buffer);
248
249 private:
250 base::WeakPtr<Buffer> buffer_;
251
252 DISALLOW_COPY_AND_ASSIGN(BufferAttachment);
jbaumanf4c3f292016-06-11 00:57:33253 };
254
jbaumanb362a892016-06-17 03:30:56255 friend class subtle::PropertyHelper;
256
jbauman45c06862016-06-23 19:35:02257 // Updates current_resource_ with a new resource id corresponding to the
258 // contents of the attached buffer (or id 0, if no buffer is attached).
259 // UpdateSurface must be called afterwards to ensure the release callback
260 // will be called.
Peng Huangc51f7aba2017-09-05 16:00:39261 void UpdateResource(LayerTreeFrameSinkHolder* frame_sink_holder);
jbauman45c06862016-06-23 19:35:02262
Peng Huang583c9dc62017-07-27 23:38:28263 // Puts the current surface into a draw quad, and appends the draw quads into
264 // the |frame|.
265 void AppendContentsToFrame(const gfx::Point& origin,
Peng Huang76f5fd02017-09-01 00:59:39266 float device_scale_factor,
267 cc::CompositorFrame* frame);
jbauman45c06862016-06-23 19:35:02268
Peng Huangc51f7aba2017-09-05 16:00:39269 // Update surface content size base on current buffer size.
Peng Huang583c9dc62017-07-27 23:38:28270 void UpdateContentSize();
eseckler599d86bb2017-03-15 09:02:55271
revemanced21f862015-11-24 00:42:49272 // This returns true when the surface has some contents assigned to it.
jbauman45c06862016-06-23 19:35:02273 bool has_contents() const { return !!current_buffer_.buffer(); }
revemanced21f862015-11-24 00:42:49274
jbaumane3526252016-06-09 18:43:05275 // This window has the layer which contains the Surface contents.
276 std::unique_ptr<aura::Window> window_;
277
Peng Huang583c9dc62017-07-27 23:38:28278 // This true, if sub_surfaces_ has changes (order, position, etc).
279 bool sub_surfaces_changed_ = false;
jbaumanf4c3f292016-06-11 00:57:33280
jbaumanb362a892016-06-17 03:30:56281 // This is the size of the last committed contents.
282 gfx::Size content_size_;
283
revemanced21f862015-11-24 00:42:49284 // This is true when Attach() has been called and new contents should take
285 // effect next time Commit() is called.
reveman2d3815d2016-06-26 20:13:25286 bool has_pending_contents_ = false;
reveman27fe2642015-11-20 06:33:39287
revemanb195f41d2015-11-19 22:16:48288 // The buffer that will become the content of surface when Commit() is called.
jbauman45c06862016-06-23 19:35:02289 BufferAttachment pending_buffer_;
revemanb195f41d2015-11-19 22:16:48290
291 // The damage region to schedule paint for when Commit() is called.
reveman5c353d52016-02-11 21:28:56292 SkRegion pending_damage_;
revemanb195f41d2015-11-19 22:16:48293
Peng Huang76f5fd02017-09-01 00:59:39294 // The damage region which will be used by
295 // AppendSurfaceHierarchyContentsToFrame() to generate frame.
296 SkRegion damage_;
297
revemanb195f41d2015-11-19 22:16:48298 // These lists contains the callbacks to notify the client when it is a good
299 // time to start producing a new frame. These callbacks move to
300 // |frame_callbacks_| when Commit() is called. Later they are moved to
reveman15aee282016-11-04 19:09:20301 // |active_frame_callbacks_| when the effect of the Commit() is scheduled to
302 // be drawn. They fire at the first begin frame notification after this.
revemanb195f41d2015-11-19 22:16:48303 std::list<FrameCallback> pending_frame_callbacks_;
reveman211cf802017-01-10 00:30:59304
305 // These lists contains the callbacks to notify the client when surface
306 // contents have been presented. These callbacks move to
307 // |presentation_callbacks_| when Commit() is called. Later they are moved to
308 // |swapping_presentation_callbacks_| when the effect of the Commit() is
309 // scheduled to be drawn and then moved to |swapped_presentation_callbacks_|
310 // after receiving VSync parameters update for the previous frame. They fire
311 // at the next VSync parameters update after that.
312 std::list<PresentationCallback> pending_presentation_callbacks_;
revemanb195f41d2015-11-19 22:16:48313
jbaumanf4c3f292016-06-11 00:57:33314 // This is the state that has yet to be committed.
315 State pending_state_;
revemanb195f41d2015-11-19 22:16:48316
jbaumanf4c3f292016-06-11 00:57:33317 // This is the state that has been committed.
318 State state_;
reveman7efa4b02016-01-06 08:29:54319
reveman27fe2642015-11-20 06:33:39320 // The stack of sub-surfaces to take effect when Commit() is called.
321 // Bottom-most sub-surface at the front of the list and top-most sub-surface
322 // at the back.
323 using SubSurfaceEntry = std::pair<Surface*, gfx::Point>;
324 using SubSurfaceEntryList = std::list<SubSurfaceEntry>;
325 SubSurfaceEntryList pending_sub_surfaces_;
Peng Huang583c9dc62017-07-27 23:38:28326 SubSurfaceEntryList sub_surfaces_;
reveman27fe2642015-11-20 06:33:39327
revemanced21f862015-11-24 00:42:49328 // The buffer that is currently set as content of surface.
jbauman45c06862016-06-23 19:35:02329 BufferAttachment current_buffer_;
revemanced21f862015-11-24 00:42:49330
jbauman2fdc0732016-06-07 00:55:36331 // The last resource that was sent to a surface.
Fady Samuel4f7f0fb32017-07-28 15:33:37332 viz::TransferableResource current_resource_;
jbauman2fdc0732016-06-07 00:55:36333
revemanca132dc2017-01-31 22:35:54334 // Whether the last resource that was sent to a surface has an alpha channel.
335 bool current_resource_has_alpha_ = false;
336
reveman27fe2642015-11-20 06:33:39337 // This is true if a call to Commit() as been made but
338 // CommitSurfaceHierarchy() has not yet been called.
Peng Huang76f5fd02017-09-01 00:59:39339 bool needs_commit_surface_ = false;
reveman27fe2642015-11-20 06:33:39340
Peng Huangc51f7aba2017-09-05 16:00:39341 // This is true if UpdateResources() should be called.
342 bool needs_update_resource_ = true;
343
reveman7cadea42016-02-05 20:14:38344 // This is set when the compositing starts and passed to active frame
345 // callbacks when compositing successfully ends.
346 base::TimeTicks last_compositing_start_time_;
347
reveman70baca12016-05-31 20:35:30348 // Cursor providers. Surface does not own the cursor providers.
349 std::set<CursorProvider*> cursor_providers_;
350
revemanb195f41d2015-11-19 22:16:48351 // This can be set to have some functions delegated. E.g. ShellSurface class
352 // can set this to handle Commit() and apply any double buffered state it
353 // maintains.
reveman2d3815d2016-06-26 20:13:25354 SurfaceDelegate* delegate_ = nullptr;
revemanb195f41d2015-11-19 22:16:48355
reveman27fe2642015-11-20 06:33:39356 // Surface observer list. Surface does not own the observers.
357 base::ObserverList<SurfaceObserver, true> observers_;
358
revemanb195f41d2015-11-19 22:16:48359 DISALLOW_COPY_AND_ASSIGN(Surface);
360};
361
362} // namespace exo
363
364#endif // COMPONENTS_EXO_SURFACE_H_