Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: ui/ozone/platform/wayland/wayland_surface_factory.cc

Issue 1610683003: Add initial SHM-only Wayland Ozone implementation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "ui/ozone/platform/wayland/wayland_surface_factory.h"
6
7 #include <fcntl.h>
8 #include <sys/mman.h>
9
10 #include "third_party/skia/include/core/SkSurface.h"
11 #include "ui/gfx/vsync_provider.h"
12 #include "ui/ozone/platform/wayland/wayland_display.h"
13 #include "ui/ozone/platform/wayland/wayland_object.h"
14 #include "ui/ozone/platform/wayland/wayland_window.h"
15 #include "ui/ozone/public/surface_ozone_canvas.h"
16 #include "ui/ozone/public/surface_ozone_egl.h"
17
18 namespace ui {
19
20 void UnmapPixels(void* pixels, void* context) {
21 size_t* length = static_cast<size_t*>(context);
22 munmap(pixels, *length);
23 delete length;
24 }
25
26 class WaylandCanvasSurface : public SurfaceOzoneCanvas {
27 public:
28 WaylandCanvasSurface(WaylandDisplay* display, WaylandWindow* window_);
29 ~WaylandCanvasSurface() override;
30
31 // SurfaceOzoneCanvas
32 skia::RefPtr<SkSurface> GetSurface() override;
33 void ResizeCanvas(const gfx::Size& viewport_size) override;
34 void PresentCanvas(const gfx::Rect& damage) override;
35 scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override;
36
37 private:
38 WaylandDisplay* display_;
39 WaylandWindow* window_;
40
41 gfx::Size size_;
42 skia::RefPtr<SkSurface> sksurface_;
spang 2016/01/22 23:42:32 SkSurface would become sk_surface_. Most code seem
Michael Forney 2016/01/23 01:08:05 I called it sk_surface_ to make the distinction be
43 wl::Object<wl_shm_pool> pool_;
44 wl::Object<wl_buffer> buffer_;
45
46 DISALLOW_COPY_AND_ASSIGN(WaylandCanvasSurface);
47 };
48
49 WaylandCanvasSurface::WaylandCanvasSurface(WaylandDisplay* display,
50 WaylandWindow* window)
51 : display_(display), window_(window) {}
52
53 WaylandCanvasSurface::~WaylandCanvasSurface() {}
54
55 skia::RefPtr<SkSurface> WaylandCanvasSurface::GetSurface() {
56 if (sksurface_)
57 return sksurface_;
58
59 char tmp[] = "/tmp/chromium-XXXXXX";
60 base::ScopedFD fd(mkostemp(tmp, O_CLOEXEC));
spang 2016/01/22 23:42:32 I think you want to use base::SharedMemory which w
Michael Forney 2016/01/23 01:08:05 I should've guessed something like this would alre
61 unlink(tmp);
62 if (!fd.is_valid()) {
63 LOG(ERROR) << "Failed to create temporary file to back SHM buffer";
64 return nullptr;
65 }
66 size_t length = size_.width() * size_.height() * 4;
67 if (posix_fallocate(fd.get(), 0, length) != 0) {
68 LOG(ERROR) << "Failed to allocate memory for SHM buffer";
69 return nullptr;
70 }
71
72 wl::Object<wl_shm_pool> pool(
73 wl_shm_create_pool(display_->GetShm(), fd.get(), length));
74 if (!pool) {
75 LOG(ERROR) << "Failed to create SHM pool";
76 return nullptr;
77 }
78 wl::Object<wl_buffer> buffer(
79 wl_shm_pool_create_buffer(pool.get(), 0, size_.width(), size_.height(),
80 size_.width() * 4, WL_SHM_FORMAT_ARGB8888));
81 if (!buffer) {
82 LOG(ERROR) << "Failed to create SHM buffer";
83 return nullptr;
84 }
85
86 void* pixels =
87 mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
88 if (pixels == MAP_FAILED) {
89 LOG(ERROR) << "Failed to mmap contents of SHM buffer";
90 return nullptr;
91 }
92
93 sksurface_ = skia::AdoptRef(SkSurface::NewRasterDirectReleaseProc(
94 SkImageInfo::MakeN32Premul(size_.width(), size_.height()), pixels,
95 size_.width() * 4, &UnmapPixels, new size_t(length), nullptr));
96 pool_ = std::move(pool);
97 buffer_ = std::move(buffer);
98 return sksurface_;
99 }
100
101 void WaylandCanvasSurface::ResizeCanvas(const gfx::Size& viewport_size) {
102 if (size_ == viewport_size)
103 return;
104 // TODO(forney): We could implement more efficient resizes by allocating
105 // buffers rounded up to larger sizes, and then reusing them if the new size
106 // still fits (but still reallocate if the new size is much smaller than the
107 // old size).
108 if (sksurface_) {
109 sksurface_.clear();
110 buffer_.reset();
111 pool_.reset();
112 }
113 size_ = viewport_size;
114 }
115
116 void WaylandCanvasSurface::PresentCanvas(const gfx::Rect& damage) {
117 // TODO(forney): This is just a naive implementation that allows chromium to
118 // draw to the buffer at any time, even if it is being used by the Wayland
119 // compositor. Instead, we should track buffer releases and frame callbacks
120 // from Wayland to ensure perfect frames (while minimizing copies).
121 wl_surface* surface = window_->GetSurface();
122 wl_surface_damage(surface, damage.x(), damage.y(), damage.width(),
123 damage.height());
124 wl_surface_attach(surface, buffer_.get(), 0, 0);
125 wl_surface_commit(surface);
126 display_->Flush();
127 }
128
129 scoped_ptr<gfx::VSyncProvider> WaylandCanvasSurface::CreateVSyncProvider() {
130 // TODO(forney): This can be implemented with information from frame
131 // callbacks, and possibly output refresh rate.
132 NOTIMPLEMENTED();
133 return nullptr;
134 }
135
136 WaylandSurfaceFactory::WaylandSurfaceFactory(WaylandDisplay* display)
137 : display_(display) {}
138
139 WaylandSurfaceFactory::~WaylandSurfaceFactory() {}
140
141 intptr_t WaylandSurfaceFactory::GetNativeDisplay() {
142 NOTIMPLEMENTED();
143 return 0;
144 }
145
146 const int32_t* WaylandSurfaceFactory::GetEGLSurfaceProperties(
147 const int32_t* desired_list) {
148 NOTIMPLEMENTED();
149 return nullptr;
150 }
151
152 bool WaylandSurfaceFactory::LoadEGLGLES2Bindings(
153 AddGLLibraryCallback add_gl_library,
154 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
155 // This Ozone implementation does not support multi-process rendering so
156 // disable EGL unconditionally for now.
157 return false;
Michael Forney 2016/01/21 22:11:48 Even with returning false here, I have to comment
spang 2016/01/22 23:42:33 Your link is cut off :(
Michael Forney 2016/01/23 01:08:05 Sorry, I copied from a draft comment on a previous
spang 2016/01/25 18:57:57 Some CrOS-only code doesn't support software rende
158 }
159
160 scoped_ptr<SurfaceOzoneCanvas> WaylandSurfaceFactory::CreateCanvasForWidget(
161 gfx::AcceleratedWidget widget) {
162 DCHECK(display_);
163 WaylandWindow* window = display_->GetWindow(widget);
164 DCHECK(window);
165 return make_scoped_ptr(new WaylandCanvasSurface(display_, window));
166 }
167
168 scoped_ptr<SurfaceOzoneEGL> WaylandSurfaceFactory::CreateEGLSurfaceForWidget(
169 gfx::AcceleratedWidget widget) {
170 NOTREACHED();
171 return nullptr;
172 }
173
174 scoped_refptr<NativePixmap> WaylandSurfaceFactory::CreateNativePixmap(
175 gfx::AcceleratedWidget widget,
176 gfx::Size size,
177 gfx::BufferFormat format,
178 gfx::BufferUsage usage) {
179 NOTIMPLEMENTED();
180 return nullptr;
181 }
182
183 scoped_refptr<NativePixmap> WaylandSurfaceFactory::CreateNativePixmapFromHandle(
184 const gfx::NativePixmapHandle& handle) {
185 NOTIMPLEMENTED();
186 return nullptr;
187 }
188
189 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698