summaryrefslogtreecommitdiff
path: root/chromium/ui/ozone/platform/wayland/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/ui/ozone/platform/wayland/gpu')
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc63
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h11
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc5
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc30
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc25
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h4
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc32
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h16
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc7
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc3
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h1
-rw-r--r--chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc246
12 files changed, 126 insertions, 317 deletions
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
index 1b15b1c27f7..827cd1c9b7d 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.cc
@@ -11,6 +11,8 @@
#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/gpu_fence.h"
+#include "ui/gfx/gpu_fence_handle.h"
+#include "ui/gl/gl_bindings.h"
#include "ui/ozone/common/egl_util.h"
#include "ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h"
#include "ui/ozone/public/mojom/wayland/wayland_overlay_config.mojom.h"
@@ -19,12 +21,6 @@ namespace ui {
namespace {
-void WaitForEGLFence(EGLDisplay display, EGLSyncKHR fence) {
- eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
- EGL_FOREVER_KHR);
- eglDestroySyncKHR(display, fence);
-}
-
void WaitForGpuFences(std::vector<std::unique_ptr<gfx::GpuFence>> fences) {
for (auto& fence : fences)
fence->Wait();
@@ -60,9 +56,9 @@ bool GbmSurfacelessWayland::ScheduleOverlayPlane(
const gfx::RectF& crop_rect,
bool enable_blend,
std::unique_ptr<gfx::GpuFence> gpu_fence) {
- unsubmitted_frames_.back()->overlays.push_back(
- gl::GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect,
- enable_blend, std::move(gpu_fence)));
+ unsubmitted_frames_.back()->overlays.emplace_back(
+ z_order, transform, image, bounds_rect, crop_rect, enable_blend,
+ std::move(gpu_fence));
return true;
}
@@ -115,31 +111,23 @@ void GbmSurfacelessWayland::SwapBuffersAsync(
unsubmitted_frames_.push_back(std::make_unique<PendingFrame>());
- if (!use_egl_fence_sync_ || !frame->schedule_planes_succeeded) {
+ // If Wayland server supports linux_explicit_synchronization_protocol, fences
+ // should be shipped with buffers. Otherwise, we will wait for fences.
+ if (buffer_manager_->supports_acquire_fence() || !use_egl_fence_sync_ ||
+ !frame->schedule_planes_succeeded) {
frame->ready = true;
MaybeSubmitFrames();
return;
}
+ base::OnceClosure fence_wait_task;
std::vector<std::unique_ptr<gfx::GpuFence>> fences;
- // Uset in-fences provided in the overlays. If there are none, we insert our
- // own fence and wait.
for (auto& plane : frame->planes) {
if (plane.second.gpu_fence)
fences.push_back(std::move(plane.second.gpu_fence));
}
- base::OnceClosure fence_wait_task;
- if (!fences.empty()) {
- fence_wait_task = base::BindOnce(&WaitForGpuFences, std::move(fences));
- } else {
- // TODO(fangzhoug): the following should be replaced by a per surface flush
- // as it gets implemented in GL drivers.
- EGLSyncKHR fence = InsertFence(has_implicit_external_sync_);
- CHECK_NE(fence, EGL_NO_SYNC_KHR) << "eglCreateSyncKHR failed";
-
- fence_wait_task = base::BindOnce(&WaitForEGLFence, GetDisplay(), fence);
- }
+ fence_wait_task = base::BindOnce(&WaitForGpuFences, std::move(fences));
base::OnceClosure fence_retired_callback = base::BindOnce(
&GbmSurfacelessWayland::FenceRetired, weak_factory_.GetWeakPtr(), frame);
@@ -190,6 +178,14 @@ void GbmSurfacelessWayland::SetRelyOnImplicitSync() {
use_egl_fence_sync_ = false;
}
+bool GbmSurfacelessWayland::SupportsPlaneGpuFences() const {
+ return true;
+}
+
+bool GbmSurfacelessWayland::SupportsOverridePlatformSize() const {
+ return true;
+}
+
gfx::SurfaceOrigin GbmSurfacelessWayland::GetOrigin() const {
// GbmSurfacelessWayland's y-axis is flipped compare to GL - (0,0) is at top
// left corner.
@@ -200,9 +196,9 @@ GbmSurfacelessWayland::~GbmSurfacelessWayland() {
buffer_manager_->UnregisterSurface(widget_);
}
-GbmSurfacelessWayland::PendingFrame::PendingFrame() {}
+GbmSurfacelessWayland::PendingFrame::PendingFrame() = default;
-GbmSurfacelessWayland::PendingFrame::~PendingFrame() {}
+GbmSurfacelessWayland::PendingFrame::~PendingFrame() = default;
void GbmSurfacelessWayland::PendingFrame::ScheduleOverlayPlanes(
gfx::AcceleratedWidget widget) {
@@ -238,15 +234,19 @@ void GbmSurfacelessWayland::MaybeSubmitFrames() {
}
std::vector<ui::ozone::mojom::WaylandOverlayConfigPtr> overlay_configs;
- for (const auto& plane : submitted_frame->planes) {
+ for (auto& plane : submitted_frame->planes) {
overlay_configs.push_back(
ui::ozone::mojom::WaylandOverlayConfig::From(plane.second));
overlay_configs.back()->buffer_id = plane.first;
- if (plane.second.z_order == 0) {
+ if (plane.second.z_order == 0)
overlay_configs.back()->damage_region = submitted_frame->damage_region_;
- submitted_frame->buffer_id = plane.first;
- }
+#if DCHECK_IS_ON()
+ if (plane.second.z_order == INT32_MIN)
+ background_buffer_id_ = plane.first;
+#endif
+ plane.second.gpu_fence.reset();
}
+
buffer_manager_->CommitOverlays(widget_, std::move(overlay_configs));
submitted_frames_.push_back(std::move(submitted_frame));
}
@@ -273,7 +273,7 @@ void GbmSurfacelessWayland::OnSubmission(BufferId buffer_id,
const gfx::SwapResult& swap_result) {
// submitted_frames_ may temporarily have more than one buffer in it if
// buffers are released out of order by the Wayland server.
- DCHECK(!submitted_frames_.empty());
+ DCHECK(!submitted_frames_.empty() || background_buffer_id_ == buffer_id);
size_t erased = 0;
for (auto& submitted_frame : submitted_frames_) {
@@ -320,7 +320,8 @@ void GbmSurfacelessWayland::OnSubmission(BufferId buffer_id,
void GbmSurfacelessWayland::OnPresentation(
BufferId buffer_id,
const gfx::PresentationFeedback& feedback) {
- DCHECK(!submitted_frames_.empty() || !pending_presentation_frames_.empty());
+ DCHECK(!submitted_frames_.empty() || !pending_presentation_frames_.empty() ||
+ background_buffer_id_ == buffer_id);
size_t erased = 0;
for (auto& frame : pending_presentation_frames_) {
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
index 910b9a7056e..8be5c32391f 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/gbm_surfaceless_wayland.h
@@ -60,6 +60,8 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
PresentationCallback presentation_callback) override;
EGLConfig GetConfig() override;
void SetRelyOnImplicitSync() override;
+ bool SupportsPlaneGpuFences() const override;
+ bool SupportsOverridePlatformSize() const override;
gfx::SurfaceOrigin GetOrigin() const override;
private:
@@ -88,9 +90,6 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
bool ready = false;
- // The id of the buffer, which represents this frame.
- BufferId buffer_id = 0;
-
// A region of the updated content in a corresponding frame. It's used to
// advice Wayland which part of a buffer is going to be updated. Passing {0,
// 0, 0, 0} results in a whole buffer update on the Wayland compositor side.
@@ -120,6 +119,12 @@ class GbmSurfacelessWayland : public gl::SurfacelessEGL,
WaylandBufferManagerGpu* const buffer_manager_;
+ // |background_buffer_id| is sent to WaylandBufferManagerHost once per
+ // background_buffer allocation. However WaylandBufferManagerHost may commit
+ // this buffer more often b/c buffers needs to be re-attached when wl_surface
+ // is reshown.
+ BufferId background_buffer_id_;
+
// The native surface. Deleting this is allowed to free the EGLNativeWindow.
gfx::AcceleratedWidget widget_;
std::vector<std::unique_ptr<PendingFrame>> unsubmitted_frames_;
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
index 195d061926c..5383fb8209c 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_egl_readback_wayland.cc
@@ -116,8 +116,9 @@ void GLSurfaceEglReadbackWayland::SwapBuffersAsync(
CHECK(next_buffer->shm_mapping_.memory());
ReadPixels(next_buffer->shm_mapping_.memory());
- buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_,
- {{0, 0}, GetSize()});
+ const auto bounds = gfx::Rect(GetSize());
+ buffer_manager_->CommitBuffer(widget_, next_buffer->buffer_id_, bounds,
+ bounds);
}
gfx::SurfaceOrigin GLSurfaceEglReadbackWayland::GetOrigin() const {
diff --git a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
index e5cdaf12895..b430a061c26 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/gl_surface_wayland.cc
@@ -46,21 +46,21 @@ bool GLSurfaceWayland::Resize(const gfx::Size& size,
EGLConfig GLSurfaceWayland::GetConfig() {
if (!config_) {
- GLint config_attribs[] = {EGL_BUFFER_SIZE,
- 32,
- EGL_ALPHA_SIZE,
- 8,
- EGL_BLUE_SIZE,
- 8,
- EGL_GREEN_SIZE,
- 8,
- EGL_RED_SIZE,
- 8,
- EGL_RENDERABLE_TYPE,
- EGL_OPENGL_ES2_BIT,
- EGL_SURFACE_TYPE,
- EGL_WINDOW_BIT,
- EGL_NONE};
+ EGLint config_attribs[] = {EGL_BUFFER_SIZE,
+ 32,
+ EGL_ALPHA_SIZE,
+ 8,
+ EGL_BLUE_SIZE,
+ 8,
+ EGL_GREEN_SIZE,
+ 8,
+ EGL_RED_SIZE,
+ 8,
+ EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT,
+ EGL_SURFACE_TYPE,
+ EGL_WINDOW_BIT,
+ EGL_NONE};
config_ = ChooseEGLConfig(GetDisplay(), config_attribs);
}
return config_;
diff --git a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc
index 3a2be4275ef..1a3335da4e2 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.cc
@@ -34,8 +34,8 @@ bool InitializeVulkanFunctionPointers(
} // namespace
-VulkanImplementationWayland::VulkanImplementationWayland()
- : gpu::VulkanImplementation(false /* use_swiftshader */) {}
+VulkanImplementationWayland::VulkanImplementationWayland(bool use_swiftshader)
+ : gpu::VulkanImplementation(use_swiftshader) {}
VulkanImplementationWayland::~VulkanImplementationWayland() {}
@@ -47,14 +47,20 @@ bool VulkanImplementationWayland::InitializeVulkanInstance(bool using_surface) {
auto* vulkan_function_pointers = gpu::GetVulkanFunctionPointers();
- base::FilePath path("libvulkan.so.1");
+ base::FilePath path;
+ if (use_swiftshader()) {
+ if (!base::PathService::Get(base::DIR_MODULE, &path))
+ return false;
+
+ path = path.Append("libvk_swiftshader.so");
+ } else {
+ path = base::FilePath("libvulkan.so.1");
+ }
if (!InitializeVulkanFunctionPointers(path, vulkan_function_pointers))
return false;
- if (!vulkan_instance_.Initialize(required_extensions, {}))
- return false;
- return true;
+ return vulkan_instance_.Initialize(required_extensions, {});
}
gpu::VulkanInstance* VulkanImplementationWayland::GetVulkanInstance() {
@@ -77,13 +83,16 @@ bool VulkanImplementationWayland::GetPhysicalDevicePresentationSupport(
std::vector<const char*>
VulkanImplementationWayland::GetRequiredDeviceExtensions() {
- return {
- VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
+ std::vector<const char*> result{
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
};
+
+ if (!use_swiftshader())
+ result.push_back(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
+ return result;
}
std::vector<const char*>
diff --git a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h
index e504ac313ef..5acd1e07945 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/vulkan_implementation_wayland.h
@@ -14,7 +14,7 @@ namespace ui {
class VulkanImplementationWayland : public gpu::VulkanImplementation {
public:
- VulkanImplementationWayland();
+ explicit VulkanImplementationWayland(bool use_swiftshader = false);
~VulkanImplementationWayland() override;
VulkanImplementationWayland(const VulkanImplementationWayland&) = delete;
@@ -56,4 +56,4 @@ class VulkanImplementationWayland : public gpu::VulkanImplementation {
} // namespace ui
-#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_VULKAN_IMPLEMENTATION_WAYLAND_H_ \ No newline at end of file
+#endif // UI_OZONE_PLATFORM_WAYLAND_GPU_VULKAN_IMPLEMENTATION_WAYLAND_H_
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
index 5c14a1c918f..da7ce23565e 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.cc
@@ -44,7 +44,8 @@ void WaylandBufferManagerGpu::Initialize(
mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host,
const base::flat_map<::gfx::BufferFormat, std::vector<uint64_t>>&
buffer_formats_with_modifiers,
- bool supports_dma_buf) {
+ bool supports_dma_buf,
+ bool supports_acquire_fence) {
DCHECK(supported_buffer_formats_with_modifiers_.empty());
supported_buffer_formats_with_modifiers_ = buffer_formats_with_modifiers;
@@ -52,6 +53,7 @@ void WaylandBufferManagerGpu::Initialize(
if (!supports_dma_buf)
set_gbm_device(nullptr);
#endif
+ supports_acquire_fence_ = supports_acquire_fence;
BindHostInterface(std::move(remote_host));
@@ -182,18 +184,16 @@ void WaylandBufferManagerGpu::CreateShmBasedBuffer(
void WaylandBufferManagerGpu::CommitBuffer(gfx::AcceleratedWidget widget,
uint32_t buffer_id,
+ const gfx::Rect& bounds_rect,
const gfx::Rect& damage_region) {
- if (!remote_host_) {
- LOG(ERROR) << "Interface is not bound. Can't request "
- "WaylandBufferManagerHost to create/commit/destroy buffers.";
- return;
- }
-
- // Do the mojo call on the IO child thread.
- io_thread_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&WaylandBufferManagerGpu::CommitBufferInternal,
- base::Unretained(this), widget, buffer_id, damage_region));
+ std::vector<ui::ozone::mojom::WaylandOverlayConfigPtr> overlay_configs;
+ // This surface only commits one buffer per frame, use INT32_MIN to attach
+ // the buffer to root_surface of wayland window.
+ overlay_configs.push_back(ui::ozone::mojom::WaylandOverlayConfig::New(
+ INT32_MIN, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, buffer_id,
+ bounds_rect, gfx::RectF(), damage_region, false, gfx::GpuFenceHandle()));
+
+ CommitOverlays(widget, std::move(overlay_configs));
}
void WaylandBufferManagerGpu::CommitOverlays(
@@ -271,14 +271,6 @@ void WaylandBufferManagerGpu::CreateShmBasedBufferInternal(
length, size, buffer_id);
}
-void WaylandBufferManagerGpu::CommitBufferInternal(
- gfx::AcceleratedWidget widget,
- uint32_t buffer_id,
- const gfx::Rect& damage_region) {
- DCHECK(io_thread_runner_->BelongsToCurrentThread());
- remote_host_->CommitBuffer(widget, buffer_id, damage_region);
-}
-
void WaylandBufferManagerGpu::CommitOverlaysInternal(
gfx::AcceleratedWidget widget,
std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays) {
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
index 1f451202652..8123ade0306 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_buffer_manager_gpu.h
@@ -26,7 +26,6 @@
namespace gfx {
enum class SwapResult;
-class Rect;
} // namespace gfx
namespace ui {
@@ -51,7 +50,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
mojo::PendingRemote<ozone::mojom::WaylandBufferManagerHost> remote_host,
const base::flat_map<::gfx::BufferFormat, std::vector<uint64_t>>&
buffer_formats_with_modifiers,
- bool supports_dma_buf) override;
+ bool supports_dma_buf,
+ bool supports_acquire_fence) override;
// These two calls get the surface, which backs the |widget| and notifies it
// about the submission and the presentation. After the surface receives the
@@ -103,10 +103,13 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
// logic as well. This call must not be done twice for the same |widget| until
// the OnSubmission is called (which actually means the client can continue
// sending buffer swap requests).
+ //
+ // CommitBuffer() calls CommitOverlays() to commit only a primary plane
+ // buffer.
void CommitBuffer(gfx::AcceleratedWidget widget,
uint32_t buffer_id,
+ const gfx::Rect& bounds_rect,
const gfx::Rect& damage_region);
-
// Send overlay configurations for a frame to a WaylandWindow identified by
// |widget|.
void CommitOverlays(
@@ -124,6 +127,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
}
#endif
+ bool supports_acquire_fence() const { return supports_acquire_fence_; }
+
// Adds a WaylandBufferManagerGpu binding.
void AddBindingWaylandBufferManagerGpu(
mojo::PendingReceiver<ozone::mojom::WaylandBufferManagerGpu> receiver);
@@ -148,9 +153,6 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
size_t length,
gfx::Size size,
uint32_t buffer_id);
- void CommitBufferInternal(gfx::AcceleratedWidget widget,
- uint32_t buffer_id,
- const gfx::Rect& damage_region);
void CommitOverlaysInternal(
gfx::AcceleratedWidget widget,
std::vector<ozone::mojom::WaylandOverlayConfigPtr> overlays);
@@ -178,6 +180,8 @@ class WaylandBufferManagerGpu : public ozone::mojom::WaylandBufferManagerGpu {
// A DRM render node based gbm device.
std::unique_ptr<GbmDevice> gbm_device_;
#endif
+ // Whether Wayland server allows buffer submission with acquire fence.
+ bool supports_acquire_fence_ = false;
mojo::Receiver<ozone::mojom::WaylandBufferManagerGpu> receiver_{this};
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
index deb43b013e4..bb7029b7d29 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_canvas_surface.cc
@@ -58,6 +58,7 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
// based wl_buffer, which can be attached to a surface and have its contents
// shown on a screen.
bool Initialize(const gfx::Size& size) {
+ size_ = size;
base::CheckedNumeric<size_t> checked_length(size.width());
checked_length *= size.height();
checked_length *= 4;
@@ -92,7 +93,8 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
}
void CommitBuffer(const gfx::Rect& damage) {
- buffer_manager_->CommitBuffer(widget_, buffer_id_, damage);
+ buffer_manager_->CommitBuffer(widget_, buffer_id_, gfx::Rect(size_),
+ damage);
}
void OnUse() {
@@ -134,6 +136,9 @@ class WaylandCanvasSurface::SharedMemoryBuffer {
}
private:
+ // The size of the buffer.
+ gfx::Size size_;
+
// The id of the buffer this surface is backed.
const uint32_t buffer_id_;
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
index 0f20a7c0c39..18f555b2076 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.cc
@@ -164,9 +164,10 @@ GLOzone* WaylandSurfaceFactory::GetGLOzone(
#if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanImplementation>
WaylandSurfaceFactory::CreateVulkanImplementation(
+ bool use_swiftshader,
bool allow_protected_memory,
bool enforce_protected_memory) {
- return std::make_unique<VulkanImplementationWayland>();
+ return std::make_unique<VulkanImplementationWayland>(use_swiftshader);
}
#endif
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
index 1de11ed0104..18a0319c1d9 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory.h
@@ -31,6 +31,7 @@ class WaylandSurfaceFactory : public SurfaceFactoryOzone {
GLOzone* GetGLOzone(gl::GLImplementation implementation) override;
#if BUILDFLAG(ENABLE_VULKAN)
std::unique_ptr<gpu::VulkanImplementation> CreateVulkanImplementation(
+ bool use_swiftshader,
bool allow_protected_memory,
bool enforce_protected_memory) override;
#endif
diff --git a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
index cc71dc65c2b..310d4a9be16 100644
--- a/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
+++ b/chromium/ui/ozone/platform/wayland/gpu/wayland_surface_factory_unittest.cc
@@ -178,7 +178,7 @@ class WaylandSurfaceFactoryTest : public WaylandTest {
WaylandTest::SetUp();
auto manager_ptr = connection_->buffer_manager_host()->BindInterface();
- buffer_manager_gpu_->Initialize(std::move(manager_ptr), {}, false);
+ buffer_manager_gpu_->Initialize(std::move(manager_ptr), {}, false, false);
// Wait until initialization and mojo calls go through.
base::RunLoop().RunUntilIdle();
@@ -204,221 +204,10 @@ class WaylandSurfaceFactoryTest : public WaylandTest {
};
TEST_P(WaylandSurfaceFactoryTest,
- GbmSurfacelessWaylandCheckOrderOfCallbacksTest) {
- gl::SetGLImplementation(gl::kGLImplementationEGLGLES2);
-
- buffer_manager_gpu_->set_gbm_device(std::make_unique<MockGbmDevice>());
-
- auto* gl_ozone = surface_factory_->GetGLOzone(gl::kGLImplementationEGLGLES2);
- auto gl_surface = gl_ozone->CreateSurfacelessViewGLSurface(widget_);
- EXPECT_TRUE(gl_surface);
- gl_surface->SetRelyOnImplicitSync();
- static_cast<ui::GbmSurfacelessWayland*>(gl_surface.get())
- ->SetNoGLFlushForTests();
-
- // Expect to create 3 buffers.
- EXPECT_CALL(*server_.zwp_linux_dmabuf_v1(), CreateParams(_, _, _)).Times(3);
-
- // Create buffers and FakeGlImageNativePixmap.
- std::vector<scoped_refptr<FakeGLImageNativePixmap>> fake_gl_image;
- for (int i = 0; i < 3; ++i) {
- auto native_pixmap = surface_factory_->CreateNativePixmap(
- widget_, nullptr, window_->GetBounds().size(),
- gfx::BufferFormat::BGRA_8888, gfx::BufferUsage::SCANOUT);
- fake_gl_image.push_back(base::MakeRefCounted<FakeGLImageNativePixmap>(
- native_pixmap, window_->GetBounds().size()));
-
- Sync();
-
- // Create one buffer at a time.
- auto params_vector = server_.zwp_linux_dmabuf_v1()->buffer_params();
- DCHECK_EQ(params_vector.size(), 1u);
- zwp_linux_buffer_params_v1_send_created(
- params_vector.front()->resource(),
- params_vector.front()->buffer_resource());
-
- Sync();
- }
-
- // Now, schedule 3 buffers for swap.
- auto* mock_surface = server_.GetObject<wl::MockSurface>(
- window_->root_surface()->GetSurfaceId());
-
- CallbacksHelper cbs_helper;
- // Submit all the available buffers.
- for (const auto& gl_image : fake_gl_image) {
- // Associate each image with swap id so that we could track released
- // buffers.
- auto swap_id = cbs_helper.GetNextLocalSwapId();
- // Associate the image with the next swap id so that we can easily track if
- // it became free to reuse.
- gl_image->AssociateWithSwapId(swap_id);
- // And set it to be busy...
- gl_image->SetBusy(true);
-
- // Prepare overlay plane.
- gl_surface->ScheduleOverlayPlane(
- INT32_MIN, gfx::OverlayTransform::OVERLAY_TRANSFORM_FLIP_VERTICAL,
- gl_image.get(), window_->GetBounds(), {}, false, nullptr);
-
- std::vector<scoped_refptr<FakeGLImageNativePixmap>> gl_images;
- gl_images.push_back(gl_image);
-
- // And submit each image. They will be executed in FIFO manner.
- gl_surface->SwapBuffersAsync(
- base::BindOnce(&CallbacksHelper::FinishSwapBuffersAsync,
- base::Unretained(&cbs_helper), swap_id, gl_images),
- base::BindOnce(&CallbacksHelper::BufferPresented,
- base::Unretained(&cbs_helper), swap_id));
- }
-
- // Let's sync so that 1) GbmSurfacelessWayland submits the buffer according to
- // internal queue and fake server processes the request.
-
- // Also, we expect only one buffer to be committed.
- EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
- EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Commit()).Times(1);
-
- Sync();
-
- testing::Mock::VerifyAndClearExpectations(&mock_surface);
-
- // Give mojo the chance to pass the callbacks.
- base::RunLoop().RunUntilIdle();
-
- // We have just received Attach/DamageBuffer/Commit for buffer with swap
- // id=0u. The SwapCompletionCallback must be executed automatically as long as
- // we didn't have any buffers attached to the surface before.
- EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 0u);
-
- cbs_helper.ResetLastFinishedSwapId();
-
- for (const auto& gl_image : fake_gl_image) {
- // All the images except the first one, which was associated with swap
- // id=0u, must be busy and not displayed. The first one must be displayed.
- if (gl_image->GetAssociateWithSwapId() == 0u) {
- EXPECT_FALSE(gl_image->busy());
- EXPECT_TRUE(gl_image->displayed());
- } else {
- EXPECT_TRUE(gl_image->busy());
- EXPECT_FALSE(gl_image->displayed());
- }
- }
-
- // Expect buffer for swap with id=1u to be committed.
- EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
- EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Commit()).Times(1);
-
- // Send the frame callback so that pending buffer for swap id=1u is processed
- // and swapped.
- mock_surface->SendFrameCallback();
-
- Sync();
-
- // Give mojo the chance to pass the callbacks.
- base::RunLoop().RunUntilIdle();
-
- // Even though the second buffer was submitted, we mustn't receive
- // SwapCompletionCallback until the previous buffer is released.
- EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(),
- std::numeric_limits<uint32_t>::max());
-
- // This will result in Wayland server releasing previously attached buffer for
- // swap id=0u and calling OnSubmission for buffer with swap id=1u.
- mock_surface->ReleaseBuffer(mock_surface->prev_attached_buffer());
-
- Sync();
-
- // Give mojo the chance to pass the callbacks.
- base::RunLoop().RunUntilIdle();
-
- // We expect only one buffer to be released. Thus, the last swap id must be
- // 0 as we waited until next buffer was attached to the surface.
- EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 1u);
-
- // Reset to test further swap ids.
- cbs_helper.ResetLastFinishedSwapId();
-
- for (const auto& gl_image : fake_gl_image) {
- // The first image is not displayed and not busy, the second is displayed
- // and not busy. And others are not display and busy.
- if (gl_image->GetAssociateWithSwapId() == 0u) {
- EXPECT_FALSE(gl_image->busy());
- EXPECT_FALSE(gl_image->displayed());
- } else if (gl_image->GetAssociateWithSwapId() == 1u) {
- EXPECT_FALSE(gl_image->busy());
- EXPECT_TRUE(gl_image->displayed());
- } else {
- EXPECT_TRUE(gl_image->busy());
- EXPECT_FALSE(gl_image->displayed());
- }
- }
-
- EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Frame(_)).Times(1);
- EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(1);
- EXPECT_CALL(*mock_surface, Commit()).Times(1);
-
- // Send the frame callback, so that the pending buffer with swap id=2u can
- // be processed.
- mock_surface->SendFrameCallback();
-
- Sync();
-
- // Give mojo the chance to pass the callbacks.
- base::RunLoop().RunUntilIdle();
-
- // Even though the second buffer was submitted, we mustn't receive
- // SwapCompletionCallback until the previous buffer is released.
- EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(),
- std::numeric_limits<uint32_t>::max());
-
- // This will result in Wayland server releasing previously attached buffer for
- // swap id=1u and calling OnSubmission for buffer with swap id=2u.
- mock_surface->ReleaseBuffer(mock_surface->prev_attached_buffer());
-
- Sync();
-
- // Give mojo the chance to pass the callbacks.
- base::RunLoop().RunUntilIdle();
-
- // We should receive next callbacks for the next swap id.
- EXPECT_EQ(cbs_helper.GetLastFinishedSwapId(), 2u);
-
- cbs_helper.ResetLastFinishedSwapId();
-
- // All images must be free now and the last one is displayed.
- for (const auto& gl_image : fake_gl_image) {
- if (gl_image->GetAssociateWithSwapId() == 2u) {
- EXPECT_TRUE(gl_image->displayed());
- EXPECT_FALSE(gl_image->busy());
- } else {
- EXPECT_FALSE(gl_image->displayed());
- EXPECT_FALSE(gl_image->busy());
- }
- }
-
- // There are no buffers left. Send last frame callback and verify that.
- EXPECT_CALL(*mock_surface, Attach(_, _, _)).Times(0);
- EXPECT_CALL(*mock_surface, Frame(_)).Times(0);
- EXPECT_CALL(*mock_surface, DamageBuffer(_, _, _, _)).Times(0);
- EXPECT_CALL(*mock_surface, Commit()).Times(0);
-
- // Send a frame callback so that the WaylandBufferManagerHost processes the
- // pending buffers if any exist.
- mock_surface->SendFrameCallback();
-}
-
-TEST_P(WaylandSurfaceFactoryTest,
GbmSurfacelessWaylandCommitOverlaysCallbacksTest) {
- // GbmSurfacelessWaylandCheckOrderOfCallbacksTest tests with one buffer per
- // frame. This tests multiple buffers per-frame and order of
- // SwapCompletionCallbacks. Even when all OnSubmission from later frames are
- // called, their SwapCompletionCallbacks should not run until previous frames'
+ // This tests multiple buffers per-frame and order of SwapCompletionCallbacks.
+ // Even when all OnSubmission from later frames are called, their
+ // SwapCompletionCallbacks should not run until previous frames'
// SwapCompletionCallbacks run.
gl::SetGLImplementation(gl::kGLImplementationEGLGLES2);
@@ -493,10 +282,10 @@ TEST_P(WaylandSurfaceFactoryTest,
// Also, we expect only one buffer to be committed.
EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1);
EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1);
EXPECT_CALL(*mock_primary_surface, Commit()).Times(1);
- EXPECT_CALL(*root_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*root_surface, Frame(_)).Times(0);
EXPECT_CALL(*root_surface, Commit()).Times(1);
Sync();
@@ -553,15 +342,15 @@ TEST_P(WaylandSurfaceFactoryTest,
// Expect one buffer to be committed.
EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1);
EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1);
EXPECT_CALL(*mock_primary_surface, Commit()).Times(1);
- EXPECT_CALL(*root_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*root_surface, Frame(_)).Times(0);
EXPECT_CALL(*root_surface, Commit()).Times(1);
// Send the frame callback so that pending buffer for swap id=1u is processed
// and swapped.
- root_surface->SendFrameCallback();
+ mock_primary_surface->SendFrameCallback();
Sync();
@@ -620,12 +409,12 @@ TEST_P(WaylandSurfaceFactoryTest,
EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(0);
EXPECT_CALL(*mock_primary_surface, Commit()).Times(0);
// Expect root surface to be committed.
- EXPECT_CALL(*root_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*root_surface, Frame(_)).Times(0);
EXPECT_CALL(*root_surface, Commit()).Times(1);
// Send the frame callback so that pending buffer for swap id=2u is processed
// and swapped.
- root_surface->SendFrameCallback();
+ mock_primary_surface->SendFrameCallback();
Sync();
@@ -754,10 +543,10 @@ TEST_P(WaylandSurfaceFactoryTest,
// Also, we expect primary buffer to be committed.
EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1);
EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1);
EXPECT_CALL(*mock_primary_surface, Commit()).Times(1);
- EXPECT_CALL(*root_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*root_surface, Frame(_)).Times(0);
EXPECT_CALL(*root_surface, Commit()).Times(1);
Sync();
@@ -829,23 +618,24 @@ TEST_P(WaylandSurfaceFactoryTest,
// Expect primary buffer to be committed.
EXPECT_CALL(*mock_primary_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_primary_surface, Frame(_)).Times(1);
EXPECT_CALL(*mock_primary_surface, DamageBuffer(_, _, _, _)).Times(1);
EXPECT_CALL(*mock_primary_surface, Commit()).Times(1);
// Expect overlay buffer to be committed.
EXPECT_CALL(*mock_overlay_surface, Attach(_, _, _)).Times(1);
- EXPECT_CALL(*mock_overlay_surface, Frame(_)).Times(0);
+ EXPECT_CALL(*mock_overlay_surface, Frame(_)).Times(1);
EXPECT_CALL(*mock_overlay_surface, DamageBuffer(_, _, _, _)).Times(1);
EXPECT_CALL(*mock_overlay_surface, Commit()).Times(1);
// Expect root surface to be committed without buffer.
- EXPECT_CALL(*root_surface, Frame(_)).Times(1);
+ EXPECT_CALL(*root_surface, Frame(_)).Times(0);
EXPECT_CALL(*root_surface, Commit()).Times(1);
// Send the frame callback so that pending buffer for swap id=1u is processed
// and swapped.
- root_surface->SendFrameCallback();
+ mock_overlay_surface->SendFrameCallback();
+ mock_primary_surface->SendFrameCallback();
Sync();