123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- // Copyright 2015 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.
- #include "components/exo/display.h"
- #include <GLES2/gl2extchromium.h>
- #include <iterator>
- #include <memory>
- #include <utility>
- #include "base/command_line.h"
- #include "base/trace_event/trace_event.h"
- #include "base/trace_event/traced_value.h"
- #include "build/build_config.h"
- #include "build/chromeos_buildflags.h"
- #include "components/exo/buffer.h"
- #include "components/exo/data_device.h"
- #include "components/exo/data_exchange_delegate.h"
- #include "components/exo/input_method_surface_manager.h"
- #include "components/exo/notification_surface.h"
- #include "components/exo/notification_surface_manager.h"
- #include "components/exo/shared_memory.h"
- #include "components/exo/shell_surface_util.h"
- #include "components/exo/sub_surface.h"
- #include "components/exo/surface.h"
- #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
- #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h"
- #include "third_party/khronos/GLES2/gl2.h"
- #include "third_party/khronos/GLES2/gl2ext.h"
- #include "ui/gfx/linux/client_native_pixmap_factory_dmabuf.h"
- #include "ui/ozone/public/ozone_switches.h"
- #include "ui/views/widget/widget.h"
- #include "ui/wm/core/coordinate_conversion.h"
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- #include "ash/public/cpp/shell_window_ids.h"
- #include "ash/wm/desks/desks_util.h"
- #include "components/exo/client_controlled_shell_surface.h"
- #include "components/exo/input_method_surface.h"
- #include "components/exo/shell_surface.h"
- #include "components/exo/toast_surface.h"
- #include "components/exo/toast_surface_manager.h"
- #include "components/exo/xdg_shell_surface.h"
- #endif
- namespace exo {
- ////////////////////////////////////////////////////////////////////////////////
- // Display, public:
- Display::Display()
- : seat_(nullptr),
- client_native_pixmap_factory_(
- gfx::CreateClientNativePixmapFactoryDmabuf()) {}
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- Display::Display(
- std::unique_ptr<NotificationSurfaceManager> notification_surface_manager,
- std::unique_ptr<InputMethodSurfaceManager> input_method_surface_manager,
- std::unique_ptr<ToastSurfaceManager> toast_surface_manager,
- std::unique_ptr<DataExchangeDelegate> data_exchange_delegate)
- : notification_surface_manager_(std::move(notification_surface_manager)),
- input_method_surface_manager_(std::move(input_method_surface_manager)),
- toast_surface_manager_(std::move(toast_surface_manager)),
- seat_(std::move(data_exchange_delegate)),
- client_native_pixmap_factory_(
- gfx::CreateClientNativePixmapFactoryDmabuf()) {}
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- Display::~Display() {
- Shutdown();
- }
- void Display::Shutdown() {
- if (shutdown_)
- return;
- shutdown_ = true;
- seat_.Shutdown();
- }
- std::unique_ptr<Surface> Display::CreateSurface() {
- TRACE_EVENT0("exo", "Display::CreateSurface");
- return std::make_unique<Surface>();
- }
- std::unique_ptr<SharedMemory> Display::CreateSharedMemory(
- base::UnsafeSharedMemoryRegion shared_memory_region) {
- TRACE_EVENT1("exo", "Display::CreateSharedMemory", "size",
- shared_memory_region.GetSize());
- if (!shared_memory_region.IsValid())
- return nullptr;
- return std::make_unique<SharedMemory>(std::move(shared_memory_region));
- }
- std::unique_ptr<Buffer> Display::CreateLinuxDMABufBuffer(
- const gfx::Size& size,
- gfx::BufferFormat format,
- gfx::NativePixmapHandle handle,
- bool y_invert) {
- TRACE_EVENT1("exo", "Display::CreateLinuxDMABufBuffer", "size",
- size.ToString());
- gfx::GpuMemoryBufferHandle gmb_handle;
- gmb_handle.type = gfx::NATIVE_PIXMAP;
- gmb_handle.native_pixmap_handle = std::move(handle);
- std::unique_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer =
- gpu::GpuMemoryBufferImplNativePixmap::CreateFromHandle(
- client_native_pixmap_factory_.get(), std::move(gmb_handle), size,
- format, gfx::BufferUsage::GPU_READ,
- gpu::GpuMemoryBufferImpl::DestructionCallback());
- if (!gpu_memory_buffer) {
- LOG(ERROR) << "Failed to create GpuMemoryBuffer from handle";
- return nullptr;
- }
- // Using zero-copy for optimal performance.
- bool use_zero_copy = true;
- return std::make_unique<Buffer>(
- std::move(gpu_memory_buffer),
- gpu::NativeBufferNeedsPlatformSpecificTextureTarget(format)
- ? gpu::GetPlatformSpecificTextureTarget()
- : GL_TEXTURE_2D,
- // COMMANDS_COMPLETED queries are required by native pixmaps.
- GL_COMMANDS_COMPLETED_CHROMIUM, use_zero_copy,
- /*is_overlay_candidate=*/true, y_invert);
- }
- #if BUILDFLAG(IS_CHROMEOS_ASH)
- std::unique_ptr<ShellSurface> Display::CreateShellSurface(Surface* surface) {
- TRACE_EVENT1("exo", "Display::CreateShellSurface", "surface",
- surface->AsTracedValue());
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- return std::make_unique<ShellSurface>(
- surface, gfx::Point(), /*can_minimize=*/false,
- ash::desks_util::GetActiveDeskContainerId());
- }
- std::unique_ptr<XdgShellSurface> Display::CreateXdgShellSurface(
- Surface* surface) {
- TRACE_EVENT1("exo", "Display::CreateXdgShellSurface", "surface",
- surface->AsTracedValue());
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- return std::make_unique<XdgShellSurface>(
- surface, gfx::Point(), /*can_minimize=*/false,
- ash::desks_util::GetActiveDeskContainerId());
- }
- std::unique_ptr<ClientControlledShellSurface>
- Display::CreateOrGetClientControlledShellSurface(
- Surface* surface,
- int container,
- double default_device_scale_factor,
- bool default_scale_cancellation) {
- TRACE_EVENT2("exo", "Display::CreateRemoteShellSurface", "surface",
- surface->AsTracedValue(), "container", container);
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- // Remote shell surfaces in system modal container cannot be minimized.
- bool can_minimize = container != ash::kShellWindowId_SystemModalContainer;
- std::unique_ptr<ClientControlledShellSurface> shell_surface;
- int window_session_id = surface->GetWindowSessionId();
- if (window_session_id > 0) {
- // Root surface has window session id, try get shell surface from external
- // source first.
- ui::PropertyHandler handler;
- WMHelper::AppPropertyResolver::Params params;
- params.window_session_id = window_session_id;
- WMHelper::GetInstance()->PopulateAppProperties(params, handler);
- shell_surface =
- base::WrapUnique(GetShellClientControlledShellSurface(&handler));
- }
- if (shell_surface) {
- shell_surface->RebindRootSurface(surface, can_minimize, container,
- default_scale_cancellation);
- } else {
- shell_surface = std::make_unique<ClientControlledShellSurface>(
- surface, can_minimize, container, default_scale_cancellation);
- }
- if (default_scale_cancellation) {
- shell_surface->SetScale(default_device_scale_factor);
- shell_surface->CommitPendingScale();
- }
- return shell_surface;
- }
- std::unique_ptr<NotificationSurface> Display::CreateNotificationSurface(
- Surface* surface,
- const std::string& notification_key) {
- TRACE_EVENT2("exo", "Display::CreateNotificationSurface", "surface",
- surface->AsTracedValue(), "notification_key", notification_key);
- if (!notification_surface_manager_ ||
- notification_surface_manager_->GetSurface(notification_key)) {
- DLOG(ERROR) << "Invalid notification key, key=" << notification_key;
- return nullptr;
- }
- return std::make_unique<NotificationSurface>(
- notification_surface_manager_.get(), surface, notification_key);
- }
- std::unique_ptr<InputMethodSurface> Display::CreateInputMethodSurface(
- Surface* surface,
- double default_device_scale_factor,
- bool default_scale_cancellation) {
- TRACE_EVENT1("exo", "Display::CreateInputMethodSurface", "surface",
- surface->AsTracedValue());
- if (!input_method_surface_manager_) {
- DLOG(ERROR) << "Input method surface cannot be registered";
- return nullptr;
- }
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- std::unique_ptr<InputMethodSurface> input_method_surface(
- std::make_unique<InputMethodSurface>(input_method_surface_manager_.get(),
- surface,
- default_scale_cancellation));
- if (default_scale_cancellation) {
- input_method_surface->SetScale(default_device_scale_factor);
- input_method_surface->CommitPendingScale();
- }
- return input_method_surface;
- }
- std::unique_ptr<ToastSurface> Display::CreateToastSurface(
- Surface* surface,
- double default_device_scale_factor,
- bool default_scale_cancellation) {
- TRACE_EVENT1("exo", "Display::CreateToastSurface", "surface",
- surface->AsTracedValue());
- if (!toast_surface_manager_) {
- DLOG(ERROR) << "Toast surface cannot be registered";
- return nullptr;
- }
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- std::unique_ptr<ToastSurface> toast_surface(std::make_unique<ToastSurface>(
- toast_surface_manager_.get(), surface, default_scale_cancellation));
- if (default_scale_cancellation) {
- toast_surface->SetScale(default_device_scale_factor);
- toast_surface->CommitPendingScale();
- }
- return toast_surface;
- }
- #endif // BUILDFLAG(IS_CHROMEOS_ASH)
- std::unique_ptr<SubSurface> Display::CreateSubSurface(Surface* surface,
- Surface* parent) {
- TRACE_EVENT2("exo", "Display::CreateSubSurface", "surface",
- surface->AsTracedValue(), "parent", parent->AsTracedValue());
- if (surface->window()->Contains(parent->window())) {
- DLOG(ERROR) << "Parent is contained within surface's hierarchy";
- return nullptr;
- }
- if (surface->HasSurfaceDelegate()) {
- DLOG(ERROR) << "Surface has already been assigned a role";
- return nullptr;
- }
- return std::make_unique<SubSurface>(surface, parent);
- }
- std::unique_ptr<DataDevice> Display::CreateDataDevice(
- DataDeviceDelegate* delegate) {
- return std::make_unique<DataDevice>(delegate, seat());
- }
- } // namespace exo
|