blob: 45395e955a494fc394d52eda077c809ebbf545e3 [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>
dcheng31759da2016-04-21 01:26:319#include <memory>
reveman70baca12016-05-31 20:35:3010#include <set>
reveman27fe2642015-11-20 06:33:3911#include <utility>
revemanb195f41d2015-11-19 22:16:4812
13#include "base/callback.h"
14#include "base/macros.h"
jbaumanbd9586a92016-05-28 01:09:0315#include "base/memory/ref_counted.h"
revemanb195f41d2015-11-19 22:16:4816#include "base/memory/weak_ptr.h"
reveman27fe2642015-11-20 06:33:3917#include "base/observer_list.h"
jbauman2fdc0732016-06-07 00:55:3618#include "cc/resources/transferable_resource.h"
jbaumanbd9586a92016-05-28 01:09:0319#include "cc/surfaces/surface_factory_client.h"
revemanb195f41d2015-11-19 22:16:4820#include "third_party/skia/include/core/SkRegion.h"
revemanfca687e2016-05-10 21:44:4821#include "third_party/skia/include/core/SkXfermode.h"
reveman4c94cf962015-12-03 06:49:4322#include "ui/aura/window.h"
reveman56f345902016-06-06 03:58:2823#include "ui/compositor/layer_owner_delegate.h"
revemanb195f41d2015-11-19 22:16:4824#include "ui/gfx/geometry/rect.h"
revemanb195f41d2015-11-19 22:16:4825
26namespace base {
27namespace trace_event {
28class TracedValue;
29}
30}
31
jbaumanbd9586a92016-05-28 01:09:0332namespace cc {
33class SurfaceFactory;
34enum class SurfaceDrawStatus;
35}
36
reveman2966d7702016-02-12 02:09:5437namespace gfx {
38class Path;
39}
40
revemanb195f41d2015-11-19 22:16:4841namespace exo {
42class Buffer;
reveman70baca12016-05-31 20:35:3043class Pointer;
revemanb195f41d2015-11-19 22:16:4844class SurfaceDelegate;
reveman27fe2642015-11-20 06:33:3945class SurfaceObserver;
jbaumanbd9586a92016-05-28 01:09:0346class Surface;
47
jbaumanb362a892016-06-17 03:30:5648template <typename T>
49struct SurfaceProperty;
50
51namespace subtle {
52class PropertyHelper;
53}
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
jbaumanbd9586a92016-05-28 01:09:0359// This class owns the SurfaceFactory and keeps track of references to the
60// contents of Buffers. It's keeped alive by references from
61// release_callbacks_. It's destroyed when its owning Surface is destroyed and
62// the last outstanding release callback is called.
63class SurfaceFactoryOwner : public base::RefCounted<SurfaceFactoryOwner>,
64 public cc::SurfaceFactoryClient {
65 public:
66 SurfaceFactoryOwner();
67
68 // Overridden from cc::SurfaceFactoryClient:
69 void ReturnResources(const cc::ReturnedResourceArray& resources) override;
70 void WillDrawSurface(cc::SurfaceId id, const gfx::Rect& damage_rect) override;
71 void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override;
72
73 private:
74 friend class base::RefCounted<SurfaceFactoryOwner>;
75 friend class Surface;
76 ~SurfaceFactoryOwner() override;
77
78 std::map<int,
79 std::pair<scoped_refptr<SurfaceFactoryOwner>,
80 std::unique_ptr<cc::SingleReleaseCallback>>>
81 release_callbacks_;
82 std::unique_ptr<cc::SurfaceIdAllocator> id_allocator_;
83 std::unique_ptr<cc::SurfaceFactory> surface_factory_;
84 Surface* surface_;
85};
revemanb195f41d2015-11-19 22:16:4886
87// This class represents a rectangular area that is displayed on the screen.
88// It has a location, size and pixel contents.
jbauman90410452016-06-15 22:40:5689class Surface : public ui::LayerOwnerDelegate {
revemanb195f41d2015-11-19 22:16:4890 public:
jbaumanb362a892016-06-17 03:30:5691 typedef void (*PropertyDeallocator)(int64_t value);
92
revemanb195f41d2015-11-19 22:16:4893 Surface();
94 ~Surface() override;
95
reveman39b32c872015-12-08 05:34:0596 // Type-checking downcast routine.
kinabad14ca03e2016-02-23 04:43:3597 static Surface* AsSurface(const aura::Window* window);
reveman39b32c872015-12-08 05:34:0598
jbaumane3526252016-06-09 18:43:0599 aura::Window* window() { return window_.get(); }
100
revemanb195f41d2015-11-19 22:16:48101 // Set a buffer as the content of this surface. A buffer can only be attached
102 // to one surface at a time.
103 void Attach(Buffer* buffer);
104
105 // Describe the regions where the pending buffer is different from the
106 // current surface contents, and where the surface therefore needs to be
107 // repainted.
108 void Damage(const gfx::Rect& rect);
109
110 // Request notification when the next frame is displayed. Useful for
111 // throttling redrawing operations, and driving animations.
112 using FrameCallback = base::Callback<void(base::TimeTicks frame_time)>;
113 void RequestFrameCallback(const FrameCallback& callback);
114
115 // This sets the region of the surface that contains opaque content.
116 void SetOpaqueRegion(const SkRegion& region);
117
reveman2966d7702016-02-12 02:09:54118 // This sets the region of the surface that can receive pointer and touch
119 // events.
120 void SetInputRegion(const SkRegion& region);
121
reveman7efa4b02016-01-06 08:29:54122 // This sets the scaling factor used to interpret the contents of the buffer
123 // attached to the surface. Note that if the scale is larger than 1, then you
124 // have to attach a buffer that is larger (by a factor of scale in each
125 // dimension) than the desired surface size.
126 void SetBufferScale(float scale);
127
reveman27fe2642015-11-20 06:33:39128 // Functions that control sub-surface state. All sub-surface state is
129 // double-buffered and will be applied when Commit() is called.
130 void AddSubSurface(Surface* sub_surface);
131 void RemoveSubSurface(Surface* sub_surface);
132 void SetSubSurfacePosition(Surface* sub_surface, const gfx::Point& position);
133 void PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference);
134 void PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling);
135
reveman642d8c332016-02-19 19:55:44136 // This sets the surface viewport for scaling.
137 void SetViewport(const gfx::Size& viewport);
138
reveman8e323902016-05-23 21:55:36139 // This sets the surface crop rectangle.
140 void SetCrop(const gfx::RectF& crop);
141
reveman85b7a562016-03-17 23:27:32142 // This sets the only visible on secure output flag, preventing it from
143 // appearing in screenshots or from being viewed on non-secure displays.
144 void SetOnlyVisibleOnSecureOutput(bool only_visible_on_secure_output);
145
revemanfca687e2016-05-10 21:44:48146 // This sets the blend mode that will be used when drawing the surface.
147 void SetBlendMode(SkXfermode::Mode blend_mode);
148
149 // This sets the alpha value that will be applied to the whole surface.
150 void SetAlpha(float alpha);
151
revemanb195f41d2015-11-19 22:16:48152 // Surface state (damage regions, attached buffers, etc.) is double-buffered.
153 // A Commit() call atomically applies all pending state, replacing the
reveman27fe2642015-11-20 06:33:39154 // current state. Commit() is not guaranteed to be synchronous. See
155 // CommitSurfaceHierarchy() below.
revemanb195f41d2015-11-19 22:16:48156 void Commit();
157
reveman27fe2642015-11-20 06:33:39158 // This will synchronously commit all pending state of the surface and its
159 // descendants by recursively calling CommitSurfaceHierarchy() for each
160 // sub-surface with pending state.
161 void CommitSurfaceHierarchy();
162
163 // Returns true if surface is in synchronized mode.
164 bool IsSynchronized() const;
165
revemanb9470762016-04-10 03:49:24166 // Returns the bounds of the current input region of surface.
167 gfx::Rect GetHitTestBounds() const;
reveman2966d7702016-02-12 02:09:54168
169 // Returns true if |rect| intersects this surface's bounds.
170 bool HitTestRect(const gfx::Rect& rect) const;
171
172 // Returns true if the current input region is different than the surface
173 // bounds.
174 bool HasHitTestMask() const;
175
176 // Returns the current input region of surface in the form of a hit-test mask.
177 void GetHitTestMask(gfx::Path* mask) const;
reveman4c94cf962015-12-03 06:49:43178
reveman70baca12016-05-31 20:35:30179 // Surface does not own cursor providers. It is the responsibility of the
180 // caller to remove the cursor provider before it is destroyed.
181 void RegisterCursorProvider(CursorProvider* provider);
182 void UnregisterCursorProvider(CursorProvider* provider);
183
184 // Returns true if surface has at least one cursor provider registered.
185 bool HasCursorProvider() const;
186
revemanb195f41d2015-11-19 22:16:48187 // Set the surface delegate.
188 void SetSurfaceDelegate(SurfaceDelegate* delegate);
189
reveman27fe2642015-11-20 06:33:39190 // Returns true if surface has been assigned a surface delegate.
191 bool HasSurfaceDelegate() const;
192
193 // Surface does not own observers. It is the responsibility of the observer
194 // to remove itself when it is done observing.
195 void AddSurfaceObserver(SurfaceObserver* observer);
196 void RemoveSurfaceObserver(SurfaceObserver* observer);
197 bool HasSurfaceObserver(const SurfaceObserver* observer) const;
198
revemanb195f41d2015-11-19 22:16:48199 // Returns a trace value representing the state of the surface.
dcheng31759da2016-04-21 01:26:31200 std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
revemanb195f41d2015-11-19 22:16:48201
reveman5c353d52016-02-11 21:28:56202 bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
203 return pending_damage_.contains(gfx::RectToSkIRect(damage));
204 }
revemanb195f41d2015-11-19 22:16:48205
reveman56f345902016-06-06 03:58:28206 // Overridden from ui::LayerOwnerDelegate:
207 void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
208
jbaumanbd9586a92016-05-28 01:09:03209 void WillDraw(cc::SurfaceId surface_id);
210
jbaumanf4c3f292016-06-11 00:57:33211 // Check whether this Surface and its children need to create new cc::Surface
212 // IDs for their contents next time they get new buffer contents.
213 void CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
214
jbaumanb362a892016-06-17 03:30:56215 gfx::Size content_size() const { return content_size_; }
216
217 // Sets the |value| of the given surface |property|. Setting to the default
218 // value (e.g., NULL) removes the property. The caller is responsible for the
219 // lifetime of any object set as a property on the Surface.
220 template <typename T>
221 void SetProperty(const SurfaceProperty<T>* property, T value);
222
223 // Returns the value of the given surface |property|. Returns the
224 // property-specific default value if the property was not previously set.
225 template <typename T>
226 T GetProperty(const SurfaceProperty<T>* property) const;
227
228 // Sets the |property| to its default value. Useful for avoiding a cast when
229 // setting to NULL.
230 template <typename T>
231 void ClearProperty(const SurfaceProperty<T>* property);
232
revemanb195f41d2015-11-19 22:16:48233 private:
jbaumanf4c3f292016-06-11 00:57:33234 struct State {
235 State();
236 ~State();
237
238 bool operator==(const State& other);
239 bool operator!=(const State& other) { return !(*this == other); }
240
241 SkRegion opaque_region;
242 SkRegion input_region;
243 float buffer_scale = 1.f;
244 gfx::Size viewport;
245 gfx::RectF crop;
246 bool only_visible_on_secure_output = false;
247 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
248 float alpha = 1.0f;
249 ;
250 };
251
jbaumanb362a892016-06-17 03:30:56252 friend class subtle::PropertyHelper;
253
reveman27fe2642015-11-20 06:33:39254 bool needs_commit_surface_hierarchy() const {
255 return needs_commit_surface_hierarchy_;
256 }
257
jbaumanf4c3f292016-06-11 00:57:33258 // Returns true if this surface or any child surface needs a commit and has
259 // has_pending_layer_changes_ true.
260 bool HasLayerHierarchyChanged() const;
261
262 // Sets that all children must create new cc::SurfaceIds for their contents.
263 void SetSurfaceHierarchyNeedsCommitToNewSurfaces();
264
reveman56f345902016-06-06 03:58:28265 // Set SurfaceLayer contents to the current buffer.
266 void SetSurfaceLayerContents(ui::Layer* layer);
267
jbaumanb362a892016-06-17 03:30:56268 int64_t SetPropertyInternal(const void* key,
269 const char* name,
270 PropertyDeallocator deallocator,
271 int64_t value,
272 int64_t default_value);
273 int64_t GetPropertyInternal(const void* key, int64_t default_value) const;
274
revemanced21f862015-11-24 00:42:49275 // This returns true when the surface has some contents assigned to it.
276 bool has_contents() const { return !!current_buffer_; }
277
jbaumane3526252016-06-09 18:43:05278 // This window has the layer which contains the Surface contents.
279 std::unique_ptr<aura::Window> window_;
280
jbaumanf4c3f292016-06-11 00:57:33281 // This is true if it's possible that the layer properties (size, opacity,
282 // etc.) may have been modified since the last commit. Attaching a new
283 // buffer with the same size as the old shouldn't set this to true.
284 bool has_pending_layer_changes_ = true;
285
286 // This is true if the next commit to this surface should put its contents
287 // into a new cc::SurfaceId. This allows for synchronization between Surface
288 // and layer changes.
289 bool needs_commit_to_new_surface_ = true;
290
jbaumanb362a892016-06-17 03:30:56291 // This is the size of the last committed contents.
292 gfx::Size content_size_;
293
revemanced21f862015-11-24 00:42:49294 // This is true when Attach() has been called and new contents should take
295 // effect next time Commit() is called.
296 bool has_pending_contents_;
reveman27fe2642015-11-20 06:33:39297
revemanb195f41d2015-11-19 22:16:48298 // The buffer that will become the content of surface when Commit() is called.
299 base::WeakPtr<Buffer> pending_buffer_;
300
jbaumanbd9586a92016-05-28 01:09:03301 cc::SurfaceManager* surface_manager_;
302
303 scoped_refptr<SurfaceFactoryOwner> factory_owner_;
304
305 // The Surface Id currently attached to the window.
306 cc::SurfaceId surface_id_;
307
308 // The next resource id the buffer will be attached to.
jbauman2fdc0732016-06-07 00:55:36309 int next_resource_id_ = 1;
jbaumanbd9586a92016-05-28 01:09:03310
revemanb195f41d2015-11-19 22:16:48311 // The damage region to schedule paint for when Commit() is called.
reveman5c353d52016-02-11 21:28:56312 SkRegion pending_damage_;
revemanb195f41d2015-11-19 22:16:48313
314 // These lists contains the callbacks to notify the client when it is a good
315 // time to start producing a new frame. These callbacks move to
316 // |frame_callbacks_| when Commit() is called. Later they are moved to
317 // |active_frame_callbacks_| when the effect of the Commit() is reflected in
318 // the compositor's active layer tree. The callbacks fire once we're notified
319 // that the compositor started drawing that active layer tree.
320 std::list<FrameCallback> pending_frame_callbacks_;
321 std::list<FrameCallback> frame_callbacks_;
322 std::list<FrameCallback> active_frame_callbacks_;
323
jbaumanf4c3f292016-06-11 00:57:33324 // This is the state that has yet to be committed.
325 State pending_state_;
revemanb195f41d2015-11-19 22:16:48326
jbaumanf4c3f292016-06-11 00:57:33327 // This is the state that has been committed.
328 State state_;
reveman7efa4b02016-01-06 08:29:54329
reveman27fe2642015-11-20 06:33:39330 // The stack of sub-surfaces to take effect when Commit() is called.
331 // Bottom-most sub-surface at the front of the list and top-most sub-surface
332 // at the back.
333 using SubSurfaceEntry = std::pair<Surface*, gfx::Point>;
334 using SubSurfaceEntryList = std::list<SubSurfaceEntry>;
335 SubSurfaceEntryList pending_sub_surfaces_;
336
revemanced21f862015-11-24 00:42:49337 // The buffer that is currently set as content of surface.
338 base::WeakPtr<Buffer> current_buffer_;
339
jbauman2fdc0732016-06-07 00:55:36340 // The last resource that was sent to a surface.
341 cc::TransferableResource current_resource_;
342
reveman27fe2642015-11-20 06:33:39343 // This is true if a call to Commit() as been made but
344 // CommitSurfaceHierarchy() has not yet been called.
345 bool needs_commit_surface_hierarchy_;
346
reveman7cadea42016-02-05 20:14:38347 // This is set when the compositing starts and passed to active frame
348 // callbacks when compositing successfully ends.
349 base::TimeTicks last_compositing_start_time_;
350
reveman70baca12016-05-31 20:35:30351 // Cursor providers. Surface does not own the cursor providers.
352 std::set<CursorProvider*> cursor_providers_;
353
revemanb195f41d2015-11-19 22:16:48354 // This can be set to have some functions delegated. E.g. ShellSurface class
355 // can set this to handle Commit() and apply any double buffered state it
356 // maintains.
357 SurfaceDelegate* delegate_;
358
jbaumanb362a892016-06-17 03:30:56359 struct Value {
360 const char* name;
361 int64_t value;
362 PropertyDeallocator deallocator;
363 };
364
365 std::map<const void*, Value> prop_map_;
366
reveman27fe2642015-11-20 06:33:39367 // Surface observer list. Surface does not own the observers.
368 base::ObserverList<SurfaceObserver, true> observers_;
369
revemanb195f41d2015-11-19 22:16:48370 DISALLOW_COPY_AND_ASSIGN(Surface);
371};
372
373} // namespace exo
374
375#endif // COMPONENTS_EXO_SURFACE_H_