blob: a3706787e488021f0d164a800f35417e2bcdaa6f [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;
fsamuel01f36202016-10-06 01:08:2870 void WillDrawSurface(const cc::LocalFrameId& id,
xlai92e65342016-06-30 15:58:5771 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
fsamuel01f36202016-10-06 01:08:28105 const cc::LocalFrameId& local_frame_id() const { return local_frame_id_; }
106 cc::SurfaceId GetSurfaceId() const;
jbauman45c06862016-06-23 19:35:02107
revemanb195f41d2015-11-19 22:16:48108 // Set a buffer as the content of this surface. A buffer can only be attached
109 // to one surface at a time.
110 void Attach(Buffer* buffer);
111
112 // Describe the regions where the pending buffer is different from the
113 // current surface contents, and where the surface therefore needs to be
114 // repainted.
115 void Damage(const gfx::Rect& rect);
116
117 // Request notification when the next frame is displayed. Useful for
118 // throttling redrawing operations, and driving animations.
119 using FrameCallback = base::Callback<void(base::TimeTicks frame_time)>;
120 void RequestFrameCallback(const FrameCallback& callback);
121
122 // This sets the region of the surface that contains opaque content.
123 void SetOpaqueRegion(const SkRegion& region);
124
reveman2966d7702016-02-12 02:09:54125 // This sets the region of the surface that can receive pointer and touch
126 // events.
127 void SetInputRegion(const SkRegion& region);
128
reveman7efa4b02016-01-06 08:29:54129 // This sets the scaling factor used to interpret the contents of the buffer
130 // attached to the surface. Note that if the scale is larger than 1, then you
131 // have to attach a buffer that is larger (by a factor of scale in each
132 // dimension) than the desired surface size.
133 void SetBufferScale(float scale);
134
reveman27fe2642015-11-20 06:33:39135 // Functions that control sub-surface state. All sub-surface state is
136 // double-buffered and will be applied when Commit() is called.
137 void AddSubSurface(Surface* sub_surface);
138 void RemoveSubSurface(Surface* sub_surface);
139 void SetSubSurfacePosition(Surface* sub_surface, const gfx::Point& position);
140 void PlaceSubSurfaceAbove(Surface* sub_surface, Surface* reference);
141 void PlaceSubSurfaceBelow(Surface* sub_surface, Surface* sibling);
142
reveman642d8c332016-02-19 19:55:44143 // This sets the surface viewport for scaling.
144 void SetViewport(const gfx::Size& viewport);
145
reveman8e323902016-05-23 21:55:36146 // This sets the surface crop rectangle.
147 void SetCrop(const gfx::RectF& crop);
148
reveman85b7a562016-03-17 23:27:32149 // This sets the only visible on secure output flag, preventing it from
150 // appearing in screenshots or from being viewed on non-secure displays.
151 void SetOnlyVisibleOnSecureOutput(bool only_visible_on_secure_output);
152
revemanfca687e2016-05-10 21:44:48153 // This sets the blend mode that will be used when drawing the surface.
154 void SetBlendMode(SkXfermode::Mode blend_mode);
155
156 // This sets the alpha value that will be applied to the whole surface.
157 void SetAlpha(float alpha);
158
revemanb195f41d2015-11-19 22:16:48159 // Surface state (damage regions, attached buffers, etc.) is double-buffered.
160 // A Commit() call atomically applies all pending state, replacing the
reveman27fe2642015-11-20 06:33:39161 // current state. Commit() is not guaranteed to be synchronous. See
162 // CommitSurfaceHierarchy() below.
revemanb195f41d2015-11-19 22:16:48163 void Commit();
164
reveman27fe2642015-11-20 06:33:39165 // This will synchronously commit all pending state of the surface and its
166 // descendants by recursively calling CommitSurfaceHierarchy() for each
167 // sub-surface with pending state.
168 void CommitSurfaceHierarchy();
169
170 // Returns true if surface is in synchronized mode.
171 bool IsSynchronized() const;
172
revemanb9470762016-04-10 03:49:24173 // Returns the bounds of the current input region of surface.
174 gfx::Rect GetHitTestBounds() const;
reveman2966d7702016-02-12 02:09:54175
176 // Returns true if |rect| intersects this surface's bounds.
177 bool HitTestRect(const gfx::Rect& rect) const;
178
179 // Returns true if the current input region is different than the surface
180 // bounds.
181 bool HasHitTestMask() const;
182
183 // Returns the current input region of surface in the form of a hit-test mask.
184 void GetHitTestMask(gfx::Path* mask) const;
reveman4c94cf962015-12-03 06:49:43185
reveman70baca12016-05-31 20:35:30186 // Surface does not own cursor providers. It is the responsibility of the
187 // caller to remove the cursor provider before it is destroyed.
188 void RegisterCursorProvider(CursorProvider* provider);
189 void UnregisterCursorProvider(CursorProvider* provider);
190
191 // Returns true if surface has at least one cursor provider registered.
192 bool HasCursorProvider() const;
193
revemanb195f41d2015-11-19 22:16:48194 // Set the surface delegate.
195 void SetSurfaceDelegate(SurfaceDelegate* delegate);
196
reveman27fe2642015-11-20 06:33:39197 // Returns true if surface has been assigned a surface delegate.
198 bool HasSurfaceDelegate() const;
199
200 // Surface does not own observers. It is the responsibility of the observer
201 // to remove itself when it is done observing.
202 void AddSurfaceObserver(SurfaceObserver* observer);
203 void RemoveSurfaceObserver(SurfaceObserver* observer);
204 bool HasSurfaceObserver(const SurfaceObserver* observer) const;
205
revemanb195f41d2015-11-19 22:16:48206 // Returns a trace value representing the state of the surface.
dcheng31759da2016-04-21 01:26:31207 std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const;
revemanb195f41d2015-11-19 22:16:48208
reveman5c353d52016-02-11 21:28:56209 bool HasPendingDamageForTesting(const gfx::Rect& damage) const {
210 return pending_damage_.contains(gfx::RectToSkIRect(damage));
211 }
revemanb195f41d2015-11-19 22:16:48212
reveman56f345902016-06-06 03:58:28213 // Overridden from ui::LayerOwnerDelegate:
214 void OnLayerRecreated(ui::Layer* old_layer, ui::Layer* new_layer) override;
215
jbauman45c06862016-06-23 19:35:02216 // Overridden from ui::ContextFactoryObserver.
217 void OnLostResources() override;
218
fsamuel01f36202016-10-06 01:08:28219 void WillDraw(const cc::LocalFrameId& local_frame_id);
jbaumanbd9586a92016-05-28 01:09:03220
jbaumanf4c3f292016-06-11 00:57:33221 // Check whether this Surface and its children need to create new cc::Surface
222 // IDs for their contents next time they get new buffer contents.
223 void CheckIfSurfaceHierarchyNeedsCommitToNewSurfaces();
224
jbaumanb362a892016-06-17 03:30:56225 gfx::Size content_size() const { return content_size_; }
226
227 // Sets the |value| of the given surface |property|. Setting to the default
228 // value (e.g., NULL) removes the property. The caller is responsible for the
229 // lifetime of any object set as a property on the Surface.
230 template <typename T>
231 void SetProperty(const SurfaceProperty<T>* property, T value);
232
233 // Returns the value of the given surface |property|. Returns the
234 // property-specific default value if the property was not previously set.
235 template <typename T>
236 T GetProperty(const SurfaceProperty<T>* property) const;
237
238 // Sets the |property| to its default value. Useful for avoiding a cast when
239 // setting to NULL.
240 template <typename T>
241 void ClearProperty(const SurfaceProperty<T>* property);
242
revemanb195f41d2015-11-19 22:16:48243 private:
jbaumanf4c3f292016-06-11 00:57:33244 struct State {
245 State();
246 ~State();
247
248 bool operator==(const State& other);
249 bool operator!=(const State& other) { return !(*this == other); }
250
251 SkRegion opaque_region;
252 SkRegion input_region;
reveman2d3815d2016-06-26 20:13:25253 float buffer_scale = 1.0f;
jbaumanf4c3f292016-06-11 00:57:33254 gfx::Size viewport;
255 gfx::RectF crop;
256 bool only_visible_on_secure_output = false;
257 SkXfermode::Mode blend_mode = SkXfermode::kSrcOver_Mode;
258 float alpha = 1.0f;
jbauman45c06862016-06-23 19:35:02259 };
260 class BufferAttachment {
261 public:
262 BufferAttachment();
263 ~BufferAttachment();
264
265 BufferAttachment& operator=(BufferAttachment&& buffer);
266
267 base::WeakPtr<Buffer>& buffer();
268 const base::WeakPtr<Buffer>& buffer() const;
269 void Reset(base::WeakPtr<Buffer> buffer);
270
271 private:
272 base::WeakPtr<Buffer> buffer_;
273
274 DISALLOW_COPY_AND_ASSIGN(BufferAttachment);
jbaumanf4c3f292016-06-11 00:57:33275 };
276
jbaumanb362a892016-06-17 03:30:56277 friend class subtle::PropertyHelper;
278
reveman27fe2642015-11-20 06:33:39279 bool needs_commit_surface_hierarchy() const {
280 return needs_commit_surface_hierarchy_;
281 }
282
jbaumanf4c3f292016-06-11 00:57:33283 // Returns true if this surface or any child surface needs a commit and has
284 // has_pending_layer_changes_ true.
285 bool HasLayerHierarchyChanged() const;
286
287 // Sets that all children must create new cc::SurfaceIds for their contents.
288 void SetSurfaceHierarchyNeedsCommitToNewSurfaces();
289
reveman56f345902016-06-06 03:58:28290 // Set SurfaceLayer contents to the current buffer.
291 void SetSurfaceLayerContents(ui::Layer* layer);
292
jbauman45c06862016-06-23 19:35:02293 // Updates current_resource_ with a new resource id corresponding to the
294 // contents of the attached buffer (or id 0, if no buffer is attached).
295 // UpdateSurface must be called afterwards to ensure the release callback
296 // will be called.
297 void UpdateResource(bool client_usage);
298
299 // Updates the current Surface with a new frame referring to the resource in
300 // current_resource_.
301 void UpdateSurface(bool full_damage);
302
jbaumanb362a892016-06-17 03:30:56303 int64_t SetPropertyInternal(const void* key,
304 const char* name,
305 PropertyDeallocator deallocator,
306 int64_t value,
307 int64_t default_value);
308 int64_t GetPropertyInternal(const void* key, int64_t default_value) const;
309
revemanced21f862015-11-24 00:42:49310 // This returns true when the surface has some contents assigned to it.
jbauman45c06862016-06-23 19:35:02311 bool has_contents() const { return !!current_buffer_.buffer(); }
revemanced21f862015-11-24 00:42:49312
jbaumane3526252016-06-09 18:43:05313 // This window has the layer which contains the Surface contents.
314 std::unique_ptr<aura::Window> window_;
315
jbaumanf4c3f292016-06-11 00:57:33316 // This is true if it's possible that the layer properties (size, opacity,
317 // etc.) may have been modified since the last commit. Attaching a new
318 // buffer with the same size as the old shouldn't set this to true.
319 bool has_pending_layer_changes_ = true;
320
321 // This is true if the next commit to this surface should put its contents
322 // into a new cc::SurfaceId. This allows for synchronization between Surface
323 // and layer changes.
324 bool needs_commit_to_new_surface_ = true;
325
jbaumanb362a892016-06-17 03:30:56326 // This is the size of the last committed contents.
327 gfx::Size content_size_;
328
revemanced21f862015-11-24 00:42:49329 // This is true when Attach() has been called and new contents should take
330 // effect next time Commit() is called.
reveman2d3815d2016-06-26 20:13:25331 bool has_pending_contents_ = false;
reveman27fe2642015-11-20 06:33:39332
revemanb195f41d2015-11-19 22:16:48333 // The buffer that will become the content of surface when Commit() is called.
jbauman45c06862016-06-23 19:35:02334 BufferAttachment pending_buffer_;
revemanb195f41d2015-11-19 22:16:48335
jbaumanbd9586a92016-05-28 01:09:03336 cc::SurfaceManager* surface_manager_;
337
338 scoped_refptr<SurfaceFactoryOwner> factory_owner_;
339
340 // The Surface Id currently attached to the window.
fsamuel01f36202016-10-06 01:08:28341 cc::LocalFrameId local_frame_id_;
jbaumanbd9586a92016-05-28 01:09:03342
343 // The next resource id the buffer will be attached to.
jbauman2fdc0732016-06-07 00:55:36344 int next_resource_id_ = 1;
jbaumanbd9586a92016-05-28 01:09:03345
revemanb195f41d2015-11-19 22:16:48346 // The damage region to schedule paint for when Commit() is called.
reveman5c353d52016-02-11 21:28:56347 SkRegion pending_damage_;
revemanb195f41d2015-11-19 22:16:48348
349 // These lists contains the callbacks to notify the client when it is a good
350 // time to start producing a new frame. These callbacks move to
351 // |frame_callbacks_| when Commit() is called. Later they are moved to
352 // |active_frame_callbacks_| when the effect of the Commit() is reflected in
353 // the compositor's active layer tree. The callbacks fire once we're notified
354 // that the compositor started drawing that active layer tree.
355 std::list<FrameCallback> pending_frame_callbacks_;
356 std::list<FrameCallback> frame_callbacks_;
357 std::list<FrameCallback> active_frame_callbacks_;
358
jbaumanf4c3f292016-06-11 00:57:33359 // This is the state that has yet to be committed.
360 State pending_state_;
revemanb195f41d2015-11-19 22:16:48361
jbaumanf4c3f292016-06-11 00:57:33362 // This is the state that has been committed.
363 State state_;
reveman7efa4b02016-01-06 08:29:54364
reveman27fe2642015-11-20 06:33:39365 // The stack of sub-surfaces to take effect when Commit() is called.
366 // Bottom-most sub-surface at the front of the list and top-most sub-surface
367 // at the back.
368 using SubSurfaceEntry = std::pair<Surface*, gfx::Point>;
369 using SubSurfaceEntryList = std::list<SubSurfaceEntry>;
370 SubSurfaceEntryList pending_sub_surfaces_;
371
revemanced21f862015-11-24 00:42:49372 // The buffer that is currently set as content of surface.
jbauman45c06862016-06-23 19:35:02373 BufferAttachment current_buffer_;
revemanced21f862015-11-24 00:42:49374
jbauman2fdc0732016-06-07 00:55:36375 // The last resource that was sent to a surface.
376 cc::TransferableResource current_resource_;
377
reveman27fe2642015-11-20 06:33:39378 // This is true if a call to Commit() as been made but
379 // CommitSurfaceHierarchy() has not yet been called.
reveman2d3815d2016-06-26 20:13:25380 bool needs_commit_surface_hierarchy_ = false;
reveman27fe2642015-11-20 06:33:39381
reveman7cadea42016-02-05 20:14:38382 // This is set when the compositing starts and passed to active frame
383 // callbacks when compositing successfully ends.
384 base::TimeTicks last_compositing_start_time_;
385
reveman70baca12016-05-31 20:35:30386 // Cursor providers. Surface does not own the cursor providers.
387 std::set<CursorProvider*> cursor_providers_;
388
revemanb195f41d2015-11-19 22:16:48389 // This can be set to have some functions delegated. E.g. ShellSurface class
390 // can set this to handle Commit() and apply any double buffered state it
391 // maintains.
reveman2d3815d2016-06-26 20:13:25392 SurfaceDelegate* delegate_ = nullptr;
revemanb195f41d2015-11-19 22:16:48393
jbaumanb362a892016-06-17 03:30:56394 struct Value {
395 const char* name;
396 int64_t value;
397 PropertyDeallocator deallocator;
398 };
399
400 std::map<const void*, Value> prop_map_;
401
reveman27fe2642015-11-20 06:33:39402 // Surface observer list. Surface does not own the observers.
403 base::ObserverList<SurfaceObserver, true> observers_;
404
revemanb195f41d2015-11-19 22:16:48405 DISALLOW_COPY_AND_ASSIGN(Surface);
406};
407
408} // namespace exo
409
410#endif // COMPONENTS_EXO_SURFACE_H_