blob: 34042b38b9231f14306c22bbeb92d8b36b7dc650 [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_SURFACE_TREE_HOST_H_
#define COMPONENTS_EXO_SURFACE_TREE_HOST_H_
#include <memory>
#include "base/memory/weak_ptr.h"
#include "components/exo/layer_tree_frame_sink_holder.h"
#include "components/exo/surface.h"
#include "components/exo/surface_delegate.h"
#include "components/viz/common/gpu/context_lost_observer.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "ui/display/display_observer.h"
#include "ui/display/types/display_constants.h"
#include "ui/gfx/geometry/rect.h"
namespace aura {
class Window;
} // namespace aura
namespace viz {
class ContextProvider;
}
namespace exo {
class LayerTreeFrameSinkHolder;
// This class provides functionality for hosting a surface tree. The surface
// tree is hosted in the |host_window_|.
class SurfaceTreeHost : public SurfaceDelegate,
public display::DisplayObserver,
public viz::ContextLostObserver {
public:
explicit SurfaceTreeHost(const std::string& window_name);
SurfaceTreeHost(const SurfaceTreeHost&) = delete;
SurfaceTreeHost& operator=(const SurfaceTreeHost&) = delete;
~SurfaceTreeHost() override;
// Sets a root surface of a surface tree. This surface tree will be hosted in
// the |host_window_|.
void SetRootSurface(Surface* root_surface);
// Returns false if the hit test region is empty.
bool HasHitTestRegion() const;
// Sets |mask| to the path that delineates the hit test region of the hosted
// surface tree.
void GetHitTestMask(SkPath* mask) const;
// Call this to indicate that the previous CompositorFrame is processed and
// the surface is being scheduled for a draw.
virtual void DidReceiveCompositorFrameAck();
// Call this to indicate that the CompositorFrame with given
// |presentation_token| has been first time presented to user.
void DidPresentCompositorFrame(uint32_t presentation_token,
const gfx::PresentationFeedback& feedback);
aura::Window* host_window() { return host_window_.get(); }
const aura::Window* host_window() const { return host_window_.get(); }
Surface* root_surface() { return root_surface_; }
const Surface* root_surface() const { return root_surface_; }
const gfx::Point& root_surface_origin() const { return root_surface_origin_; }
LayerTreeFrameSinkHolder* layer_tree_frame_sink_holder() {
return layer_tree_frame_sink_holder_.get();
}
using PresentationCallbacks = std::list<Surface::PresentationCallback>;
const PresentationCallbacks& presentation_callbacks() const {
return presentation_callbacks_;
}
base::flat_map<uint32_t, PresentationCallbacks>&
GetActivePresentationCallbacksForTesting() {
return active_presentation_callbacks_;
}
// SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
bool IsInputEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {}
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override {
}
void OnSetParent(Surface* parent, const gfx::Point& position) override {}
void OnSetStartupId(const char* startup_id) override {}
void OnSetApplicationId(const char* application_id) override {}
void SetUseImmersiveForFullscreen(bool value) override {}
void OnActivationRequested() override {}
void OnNewOutputAdded() override;
void OnSetServerStartResize() override {}
void ShowSnapPreviewToPrimary() override {}
void ShowSnapPreviewToSecondary() override {}
void HideSnapPreview() override {}
void SetSnappedToPrimary() override {}
void SetSnappedToSecondary() override {}
void UnsetSnap() override {}
void SetCanGoBack() override {}
void UnsetCanGoBack() override {}
void SetPip() override {}
void UnsetPip() override {}
void SetAspectRatio(const gfx::SizeF& aspect_ratio) override {}
void MoveToDesk(int desk_index) override {}
void SetVisibleOnAllWorkspaces() override {}
void SetInitialWorkspace(const char* initial_workspace) override {}
void Pin(bool trusted) override {}
void Unpin() override {}
void SetSystemModal(bool system_modal) override {}
SecurityDelegate* GetSecurityDelegate() override;
// display::DisplayObserver:
void OnDisplayMetricsChanged(const display::Display& display,
uint32_t changed_metrics) override;
// viz::ContextLostObserver:
void OnContextLost() override;
void set_client_submits_surfaces_in_pixel_coordinates(bool enabled) {
client_submits_surfaces_in_pixel_coordinates_ = enabled;
}
void SetSecurityDelegate(SecurityDelegate* security_delegate);
protected:
void UpdateDisplayOnTree();
// Call this to submit a compositor frame.
void SubmitCompositorFrame();
// Call this to submit an empty compositor frame. This may be useful if
// the surface tree is becoming invisible but the resources (e.g. buffers)
// need to be released back to the client.
void SubmitEmptyCompositorFrame();
// Update the host window's size to cover sufaces that must be visible and
// not clipped.
virtual void UpdateHostWindowBounds();
bool client_submits_surfaces_in_pixel_coordinates() const {
return client_submits_surfaces_in_pixel_coordinates_;
}
private:
viz::CompositorFrame PrepareToSubmitCompositorFrame();
void HandleContextLost();
Surface* root_surface_ = nullptr;
// Position of root surface relative to topmost, leftmost sub-surface. The
// host window should be translated by the negation of this vector.
gfx::Point root_surface_origin_;
std::unique_ptr<aura::Window> host_window_;
std::unique_ptr<LayerTreeFrameSinkHolder> layer_tree_frame_sink_holder_;
// This list contains the callbacks to notify the client when it is a good
// time to start producing a new frame. These callbacks move to
// |frame_callbacks_| when Commit() is called. They fire when the effect
// of the Commit() is scheduled to be drawn.
std::list<Surface::FrameCallback> frame_callbacks_;
// These lists contains the callbacks to notify the client when surface
// contents have been presented.
PresentationCallbacks presentation_callbacks_;
base::flat_map<uint32_t, PresentationCallbacks>
active_presentation_callbacks_;
viz::FrameTokenGenerator next_token_;
scoped_refptr<viz::ContextProvider> context_provider_;
display::ScopedDisplayObserver display_observer_{this};
int64_t display_id_ = display::kInvalidDisplayId;
bool client_submits_surfaces_in_pixel_coordinates_ = false;
SecurityDelegate* security_delegate_ = nullptr;
base::WeakPtrFactory<SurfaceTreeHost> weak_ptr_factory_{this};
};
} // namespace exo
#endif // COMPONENTS_EXO_SURFACE_TREE_HOST_H_