blob: aba532a53868e022d3f9f5056797112fc8d697ac [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"
jbauman45c06862016-06-23 19:35:0223#include "ui/compositor/compositor.h"
reveman56f345902016-06-06 03:58:2824#include "ui/compositor/layer_owner_delegate.h"
revemanb195f41d2015-11-19 22:16:4825#include "ui/gfx/geometry/rect.h"
revemanb195f41d2015-11-19 22:16:4826
27namespace base {
28namespace trace_event {
29class TracedValue;
30}
31}
32
jbaumanbd9586a92016-05-28 01:09:0333namespace cc {
34class SurfaceFactory;
jbaumanbd9586a92016-05-28 01:09:0335}
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;
xlai92e65342016-06-30 15:58:5770 void WillDrawSurface(const cc::SurfaceId& id,
71 const gfx::Rect& damage_rect) override;
jbaumanbd9586a92016-05-28 01:09:0372 void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override;
73
74 private:
75 friend class base::RefCounted<SurfaceFactoryOwner>;
76 friend class Surface;
reveman2d3815d2016-06-26 20:13:2577
jbaumanbd9586a92016-05-28 01:09:0378 ~SurfaceFactoryOwner() override;
79
80 std::map<int,
81 std::pair<scoped_refptr<SurfaceFactoryOwner>,
82 std::unique_ptr<cc::SingleReleaseCallback>>>
83 release_callbacks_;
fsamuelb6acafa2016-10-04 03:21:5284 cc::FrameSinkId frame_sink_id_;
jbaumanbd9586a92016-05-28 01:09:0385 std::unique_ptr<cc::SurfaceIdAllocator> id_allocator_;
86 std::unique_ptr<cc::SurfaceFactory> surface_factory_;
reveman2d3815d2016-06-26 20:13:2587 Surface* surface_ = nullptr;
jbaumanbd9586a92016-05-28 01:09:0388};
revemanb195f41d2015-11-19 22:16:4889
90// This class represents a rectangular area that is displayed on the screen.
91// It has a location, size and pixel contents.
jbauman45c06862016-06-23 19:35:0292class Surface : public ui::LayerOwnerDelegate,
93 public ui::ContextFactoryObserver {
revemanb195f41d2015-11-19 22:16:4894 public:
reveman2d3815d2016-06-26 20:13:2595 using PropertyDeallocator = void (*)(int64_t value);
jbaumanb362a892016-06-17 03:30:5696
revemanb195f41d2015-11-19 22:16:4897 Surface();
98 ~Surface() override;
99
reveman39b32c872015-12-08 05:34:05100 // Type-checking downcast routine.
kinabad14ca03e2016-02-23 04:43:35101 static Surface* AsSurface(const aura::Window* window);
reveman39b32c872015-12-08 05:34:05102
jbaumane3526252016-06-09 18:43:05103 aura::Window* window() { return window_.get(); }
104
fsamuel278664272016-07-13 04:06:59105 const cc::SurfaceId& surface_id() const { return surface_id_; }
jbauman45c06862016-06-23 19:35:02106
revemanb195f41d2015-11-19 22:16:48107 // Set a buffer as the content of this surface. A buffer can only be attached
108 // to one surface at a time.
109 void Attach(Buffer* buffer);
110
111 // Describe the regions where the pending buffer is different from the
112 // current surface contents, and where the surface therefore needs to be
113 // repainted.
114 void Damage(const gfx::Rect& rect);
115
116 // Request notification when the next frame is displayed. Useful for
117 // throttling redrawing operations, and driving animations.
118 using FrameCallback = base::Callback<void(base::TimeTicks frame_time)>;
119 void RequestFrameCallback(const FrameCallback& callback);
120
121 // This sets the region of the surface that contains opaque content.
122 void SetOpaqueRegion(const SkRegion& region);
123
reveman2966d7702016-02-12 02:09:54124 // This sets the region of the surface that can receive pointer and touch
125 // events.
126 void SetInputRegion(const SkRegion& region);
127
reveman7efa4b02016-01-06 08:29:54128 // This sets the scaling factor used to interpret the contents of the buffer
129 // attached to the surface. Note that if the scale is larger than 1, then you
130 // have to attach a buffer that is larger (by a factor of scale in each
131 // dimension) than the desired surface size.
132 void SetBufferScale(float scale);
133
reveman27fe2642015-11-20 06:33:39134 // Functions that control sub-surface state. All sub-surface state is
135 // double-buffered and will be applied when Commit() is called.
136 void AddSubSurface(Surface* sub_surface);
137 void RemoveSubSurface(Surface* sub_surface);
138 void SetSubSurfacePosition(Surface* sub_surface, const gfx::Point& position);
139 void PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference);
140 void PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling);
141
reveman642d8c332016-02-19 19:55:44142 // This sets the surface viewport for scaling.
143 void SetViewport(const gfx::Size& viewport);
144
reveman8e323902016-05-23 21:55:36145 // This sets the surface crop rectangle.
146 void SetCrop(const gfx::RectF& crop);
147
reveman85b7a562016-03-17 23:27:32148 // This sets the only visible on secure output flag, preventing it from
149 // appearing in screenshots or from being viewed on non-secure displays.
150 void SetOnlyVisibleOnSecureOutput(bool only_visible_on_secure_output);
151
revemanfca687e2016-05-10 21:44:48152 // This sets the blend mode that will be used when drawing the surface.
153 void SetBlendMode(SkXfermode::Mode blend_mode);
154
155 // This sets the alpha value that will be applied to the whole surface.
156 void SetAlpha(float alpha);
157
revemanb195f41d2015-11-19 22:16:48158 // Surface state (damage regions, attached buffers, etc.) is double-buffered.
159 // A Commit() call atomically applies all pending state, replacing the
reveman27fe2642015-11-20 06:33:39160 // current state. Commit() is not guaranteed to be synchronous. See
161 // CommitSurfaceHierarchy() below.
revemanb195f41d2015-11-19 22:16:48162 void Commit();
163
reveman27fe2642015-11-20 06:33:39164 // This will synchronously commit all pending state of the surface and its
165 // descendants by recursively calling CommitSurfaceHierarchy() for each
166 // sub-surface with pending state.
167 void CommitSurfaceHierarchy();
168
169 // Returns true if surface is in synchronized mode.
170 bool IsSynchronized() const;
171
revemanb9470762016-04-10 03:49:24172 // Returns the bounds of the current input region of surface.
173 gfx::Rect GetHitTestBounds() const;
reveman2966d7702016-02-12 02:09:54174
175 // Returns true if |rect| intersects this surface's bounds.
176 bool HitTestRect(const gfx::Rect& rect) const;
177
178 // Returns true if the current input region is different than the surface
179 // bounds.
180 bool HasHitTestMask() const;
181
182 // Returns the current input region of surface in the form of a hit-test mask.
183 void GetHitTestMask(gfx::Path* mask) const;
reveman4c94cf962015-12-03 06:49:43184
reveman70baca12016-05-31 20:35:30185 // Surface does not own cursor providers. It is the responsibility of the
186 // caller to remove the cursor provider before it is destroyed.
187 void RegisterCursorProvider(CursorProvider* provider);
188 void UnregisterCursorProvider(CursorProvider* provider);
189
190 // Returns true if surface has at least one cursor provider registered.
191 bool HasCursorProvider() const;
192
revemanb195f41d2015-11-19 22:16:48193 // Set the surface delegate.
194 void SetSurfaceDelegate(SurfaceDelegate* delegate);
195
reveman27fe2642015-11-20 06:33:39196 // Returns true if surface has been assigned a surface delegate.
197 bool HasSurfaceDelegate() const;
198
199 // Surface does not own observers. It is the responsibility of the observer
200 // to remove itself when it is done observing.
201 void AddSurfaceObserver(SurfaceObserver* observer);
202 void RemoveSurfaceObserver(SurfaceObserver* observer);
203 bool HasSurfaceObserver(const SurfaceObserver* observer) const;
204
revemanb195f41d2015-11-19 22:16:48205 // Returns a trace value representing the state of the surface.
dcheng31759da2016-04-21 01:26:31206 std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
revemanb195f41d2015-11-19 22:16:48207
reveman5c353d52016-02-11 21:28:56208 bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
209 return pending_damage_.contains(gfx::RectToSkIRect(damage));
210 }
revemanb195f41d2015-11-19 22:16:48211
reveman56f345902016-06-06 03:58:28212 // Overridden from ui::LayerOwnerDelegate:
213 void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
214
jbauman45c06862016-06-23 19:35:02215 // Overridden from ui::ContextFactoryObserver.
216 void OnLostResources() override;
217
fsamuel278664272016-07-13 04:06:59218 void WillDraw(const cc::SurfaceId& surface_id);
jbaumanbd9586a92016-05-28 01:09:03219
jbaumanf4c3f292016-06-11 00:57:33220 // Check whether this Surface and its children need to create new cc::Surface
221 // IDs for their contents next time they get new buffer contents.
222 void CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
223
jbaumanb362a892016-06-17 03:30:56224 gfx::Size content_size() const { return content_size_; }
225
226 // Sets the |value| of the given surface |property|. Setting to the default
227 // value (e.g., NULL) removes the property. The caller is responsible for the
228 // lifetime of any object set as a property on the Surface.
229 template <typename T>
230 void SetProperty(const SurfaceProperty<T>* property, T value);
231
232 // Returns the value of the given surface |property|. Returns the
233 // property-specific default value if the property was not previously set.
234 template <typename T>
235 T GetProperty(const SurfaceProperty<T>* property) const;
236
237 // Sets the |property| to its default value. Useful for avoiding a cast when
238 // setting to NULL.
239 template <typename T>
240 void ClearProperty(const SurfaceProperty<T>* property);
241
revemanb195f41d2015-11-19 22:16:48242 private:
jbaumanf4c3f292016-06-11 00:57:33243 struct State {
244 State();
245 ~State();
246
247 bool operator==(const State& other);
248 bool operator!=(const State& other) { return !(*this == other); }
249
250 SkRegion opaque_region;
251 SkRegion input_region;
reveman2d3815d2016-06-26 20:13:25252 float buffer_scale = 1.0f;
jbaumanf4c3f292016-06-11 00:57:33253 gfx::Size viewport;
254 gfx::RectF crop;
255 bool only_visible_on_secure_output = false;
256 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
257 float alpha = 1.0f;
jbauman45c06862016-06-23 19:35:02258 };
259 class BufferAttachment {
260 public:
261 BufferAttachment();
262 ~BufferAttachment();
263
264 BufferAttachment& operator=(BufferAttachment&& buffer);
265
266 base::WeakPtr<Buffer>& buffer();
267 const base::WeakPtr<Buffer>& buffer() const;
268 void Reset(base::WeakPtr<Buffer> buffer);
269
270 private:
271 base::WeakPtr<Buffer> buffer_;
272
273 DISALLOW_COPY_AND_ASSIGN(BufferAttachment);
jbaumanf4c3f292016-06-11 00:57:33274 };
275
jbaumanb362a892016-06-17 03:30:56276 friend class subtle::PropertyHelper;
277
reveman27fe2642015-11-20 06:33:39278 bool needs_commit_surface_hierarchy() const {
279 return needs_commit_surface_hierarchy_;
280 }
281
jbaumanf4c3f292016-06-11 00:57:33282 // Returns true if this surface or any child surface needs a commit and has
283 // has_pending_layer_changes_ true.
284 bool HasLayerHierarchyChanged() const;
285
286 // Sets that all children must create new cc::SurfaceIds for their contents.
287 void SetSurfaceHierarchyNeedsCommitToNewSurfaces();
288
reveman56f345902016-06-06 03:58:28289 // Set SurfaceLayer contents to the current buffer.
290 void SetSurfaceLayerContents(ui::Layer* layer);
291
jbauman45c06862016-06-23 19:35:02292 // Updates current_resource_ with a new resource id corresponding to the
293 // contents of the attached buffer (or id 0, if no buffer is attached).
294 // UpdateSurface must be called afterwards to ensure the release callback
295 // will be called.
296 void UpdateResource(bool client_usage);
297
298 // Updates the current Surface with a new frame referring to the resource in
299 // current_resource_.
300 void UpdateSurface(bool full_damage);
301
jbaumanb362a892016-06-17 03:30:56302 int64_t SetPropertyInternal(const void* key,
303 const char* name,
304 PropertyDeallocator deallocator,
305 int64_t value,
306 int64_t default_value);
307 int64_t GetPropertyInternal(const void* key, int64_t default_value) const;
308
revemanced21f862015-11-24 00:42:49309 // This returns true when the surface has some contents assigned to it.
jbauman45c06862016-06-23 19:35:02310 bool has_contents() const { return !!current_buffer_.buffer(); }
revemanced21f862015-11-24 00:42:49311
jbaumane3526252016-06-09 18:43:05312 // This window has the layer which contains the Surface contents.
313 std::unique_ptr<aura::Window> window_;
314
jbaumanf4c3f292016-06-11 00:57:33315 // This is true if it's possible that the layer properties (size, opacity,
316 // etc.) may have been modified since the last commit. Attaching a new
317 // buffer with the same size as the old shouldn't set this to true.
318 bool has_pending_layer_changes_ = true;
319
320 // This is true if the next commit to this surface should put its contents
321 // into a new cc::SurfaceId. This allows for synchronization between Surface
322 // and layer changes.
323 bool needs_commit_to_new_surface_ = true;
324
jbaumanb362a892016-06-17 03:30:56325 // This is the size of the last committed contents.
326 gfx::Size content_size_;
327
revemanced21f862015-11-24 00:42:49328 // This is true when Attach() has been called and new contents should take
329 // effect next time Commit() is called.
reveman2d3815d2016-06-26 20:13:25330 bool has_pending_contents_ = false;
reveman27fe2642015-11-20 06:33:39331
revemanb195f41d2015-11-19 22:16:48332 // The buffer that will become the content of surface when Commit() is called.
jbauman45c06862016-06-23 19:35:02333 BufferAttachment pending_buffer_;
revemanb195f41d2015-11-19 22:16:48334
jbaumanbd9586a92016-05-28 01:09:03335 cc::SurfaceManager* surface_manager_;
336
337 scoped_refptr<SurfaceFactoryOwner> factory_owner_;
338
339 // The Surface Id currently attached to the window.
340 cc::SurfaceId surface_id_;
341
342 // The next resource id the buffer will be attached to.
jbauman2fdc0732016-06-07 00:55:36343 int next_resource_id_ = 1;
jbaumanbd9586a92016-05-28 01:09:03344
revemanb195f41d2015-11-19 22:16:48345 // The damage region to schedule paint for when Commit() is called.
reveman5c353d52016-02-11 21:28:56346 SkRegion pending_damage_;
revemanb195f41d2015-11-19 22:16:48347
348 // These lists contains the callbacks to notify the client when it is a good
349 // time to start producing a new frame. These callbacks move to
350 // |frame_callbacks_| when Commit() is called. Later they are moved to
351 // |active_frame_callbacks_| when the effect of the Commit() is reflected in
352 // the compositor's active layer tree. The callbacks fire once we're notified
353 // that the compositor started drawing that active layer tree.
354 std::list<FrameCallback> pending_frame_callbacks_;
355 std::list<FrameCallback> frame_callbacks_;
356 std::list<FrameCallback> active_frame_callbacks_;
357
jbaumanf4c3f292016-06-11 00:57:33358 // This is the state that has yet to be committed.
359 State pending_state_;
revemanb195f41d2015-11-19 22:16:48360
jbaumanf4c3f292016-06-11 00:57:33361 // This is the state that has been committed.
362 State state_;
reveman7efa4b02016-01-06 08:29:54363
reveman27fe2642015-11-20 06:33:39364 // The stack of sub-surfaces to take effect when Commit() is called.
365 // Bottom-most sub-surface at the front of the list and top-most sub-surface
366 // at the back.
367 using SubSurfaceEntry = std::pair<Surface*, gfx::Point>;
368 using SubSurfaceEntryList = std::list<SubSurfaceEntry>;
369 SubSurfaceEntryList pending_sub_surfaces_;
370
revemanced21f862015-11-24 00:42:49371 // The buffer that is currently set as content of surface.
jbauman45c06862016-06-23 19:35:02372 BufferAttachment current_buffer_;
revemanced21f862015-11-24 00:42:49373
jbauman2fdc0732016-06-07 00:55:36374 // The last resource that was sent to a surface.
375 cc::TransferableResource current_resource_;
376
reveman27fe2642015-11-20 06:33:39377 // This is true if a call to Commit() as been made but
378 // CommitSurfaceHierarchy() has not yet been called.
reveman2d3815d2016-06-26 20:13:25379 bool needs_commit_surface_hierarchy_ = false;
reveman27fe2642015-11-20 06:33:39380
reveman7cadea42016-02-05 20:14:38381 // This is set when the compositing starts and passed to active frame
382 // callbacks when compositing successfully ends.
383 base::TimeTicks last_compositing_start_time_;
384
reveman70baca12016-05-31 20:35:30385 // Cursor providers. Surface does not own the cursor providers.
386 std::set<CursorProvider*> cursor_providers_;
387
revemanb195f41d2015-11-19 22:16:48388 // This can be set to have some functions delegated. E.g. ShellSurface class
389 // can set this to handle Commit() and apply any double buffered state it
390 // maintains.
reveman2d3815d2016-06-26 20:13:25391 SurfaceDelegate* delegate_ = nullptr;
revemanb195f41d2015-11-19 22:16:48392
jbaumanb362a892016-06-17 03:30:56393 struct Value {
394 const char* name;
395 int64_t value;
396 PropertyDeallocator deallocator;
397 };
398
399 std::map<const void*, Value> prop_map_;
400
reveman27fe2642015-11-20 06:33:39401 // Surface observer list. Surface does not own the observers.
402 base::ObserverList<SurfaceObserver, true> observers_;
403
revemanb195f41d2015-11-19 22:16:48404 DISALLOW_COPY_AND_ASSIGN(Surface);
405};
406
407} // namespace exo
408
409#endif // COMPONENTS_EXO_SURFACE_H_