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

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: Use base::SharedMemory, expand ObjectTraits macros, etc 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 "base/memory/shared_memory.h"
11 #include "third_party/skia/include/core/SkSurface.h"
12 #include "ui/gfx/vsync_provider.h"
13 #include "ui/ozone/platform/wayland/wayland_display.h"
14 #include "ui/ozone/platform/wayland/wayland_object.h"
15 #include "ui/ozone/platform/wayland/wayland_window.h"
16 #include "ui/ozone/public/surface_ozone_canvas.h"
17 #include "ui/ozone/public/surface_ozone_egl.h"
18
19 namespace ui {
20
21 static void DeleteSharedMemory(void* pixels, void* context) {
22 delete static_cast<base::SharedMemory*>(context);
23 }
24
25 class WaylandCanvasSurface : public SurfaceOzoneCanvas {
26 public:
27 WaylandCanvasSurface(WaylandDisplay* display, WaylandWindow* window_);
28 ~WaylandCanvasSurface() override;
29
30 // SurfaceOzoneCanvas
31 skia::RefPtr<SkSurface> GetSurface() override;
32 void ResizeCanvas(const gfx::Size& viewport_size) override;
33 void PresentCanvas(const gfx::Rect& damage) override;
34 scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override;
35
36 private:
37 WaylandDisplay* display_;
38 WaylandWindow* window_;
39
40 gfx::Size size_;
41 skia::RefPtr<SkSurface> sk_surface_;
42 wl::Object<wl_shm_pool> pool_;
43 wl::Object<wl_buffer> buffer_;
44
45 DISALLOW_COPY_AND_ASSIGN(WaylandCanvasSurface);
46 };
47
48 WaylandCanvasSurface::WaylandCanvasSurface(WaylandDisplay* display,
49 WaylandWindow* window)
50 : display_(display), window_(window) {}
51
52 WaylandCanvasSurface::~WaylandCanvasSurface() {}
53
54 skia::RefPtr<SkSurface> WaylandCanvasSurface::GetSurface() {
55 if (sk_surface_)
56 return sk_surface_;
57
58 size_t length = size_.width() * size_.height() * 4;
59 auto shared_memory = make_scoped_ptr(new base::SharedMemory);
60 if (!shared_memory->CreateAndMapAnonymous(length))
61 return nullptr;
62
63 wl::Object<wl_shm_pool> pool(
64 wl_shm_create_pool(display_->shm(), shared_memory->handle().fd, length));
65 if (!pool) {
66 LOG(ERROR) << "Failed to create SHM pool";
67 return nullptr;
68 }
69 wl::Object<wl_buffer> buffer(
70 wl_shm_pool_create_buffer(pool.get(), 0, size_.width(), size_.height(),
71 size_.width() * 4, WL_SHM_FORMAT_ARGB8888));
72 if (!buffer) {
73 LOG(ERROR) << "Failed to create SHM buffer";
74 return nullptr;
75 }
76
77 void* pixels = shared_memory->memory();
78 sk_surface_ = skia::AdoptRef(SkSurface::NewRasterDirectReleaseProc(
79 SkImageInfo::MakeN32Premul(size_.width(), size_.height()), pixels,
80 size_.width() * 4, &DeleteSharedMemory, shared_memory.release(),
spang 2016/01/25 18:57:57 Is it possible for NewRasterDirectReleaseProc to f
Michael Forney 2016/01/26 02:25:26 It looks like it does do some width/height/stride
81 nullptr));
82 pool_ = std::move(pool);
83 buffer_ = std::move(buffer);
84 return sk_surface_;
85 }
86
87 void WaylandCanvasSurface::ResizeCanvas(const gfx::Size& viewport_size) {
88 if (size_ == viewport_size)
89 return;
90 // TODO(forney): We could implement more efficient resizes by allocating
91 // buffers rounded up to larger sizes, and then reusing them if the new size
92 // still fits (but still reallocate if the new size is much smaller than the
93 // old size).
94 if (sk_surface_) {
95 sk_surface_.clear();
96 buffer_.reset();
97 pool_.reset();
98 }
99 size_ = viewport_size;
100 }
101
102 void WaylandCanvasSurface::PresentCanvas(const gfx::Rect& damage) {
103 // TODO(forney): This is just a naive implementation that allows chromium to
104 // draw to the buffer at any time, even if it is being used by the Wayland
kalyank 2016/01/25 22:05:16 Also, we should make sure that we don't release bu
Michael Forney 2016/01/26 02:25:26 Acknowledged.
105 // compositor. Instead, we should track buffer releases and frame callbacks
106 // from Wayland to ensure perfect frames (while minimizing copies).
107 wl_surface* surface = window_->GetSurface();
108 wl_surface_damage(surface, damage.x(), damage.y(), damage.width(),
109 damage.height());
110 wl_surface_attach(surface, buffer_.get(), 0, 0);
111 wl_surface_commit(surface);
112 display_->Flush();
113 }
114
115 scoped_ptr<gfx::VSyncProvider> WaylandCanvasSurface::CreateVSyncProvider() {
116 // TODO(forney): This can be implemented with information from frame
117 // callbacks, and possibly output refresh rate.
118 NOTIMPLEMENTED();
119 return nullptr;
120 }
121
122 WaylandSurfaceFactory::WaylandSurfaceFactory(WaylandDisplay* display)
123 : display_(display) {}
124
125 WaylandSurfaceFactory::~WaylandSurfaceFactory() {}
126
127 intptr_t WaylandSurfaceFactory::GetNativeDisplay() {
128 NOTIMPLEMENTED();
129 return 0;
130 }
131
132 const int32_t* WaylandSurfaceFactory::GetEGLSurfaceProperties(
133 const int32_t* desired_list) {
134 NOTIMPLEMENTED();
135 return nullptr;
136 }
137
138 bool WaylandSurfaceFactory::LoadEGLGLES2Bindings(
139 AddGLLibraryCallback add_gl_library,
140 SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
141 // This Ozone implementation does not support multi-process rendering so
142 // disable EGL unconditionally for now.
143 return false;
144 }
145
146 scoped_ptr<SurfaceOzoneCanvas> WaylandSurfaceFactory::CreateCanvasForWidget(
147 gfx::AcceleratedWidget widget) {
148 DCHECK(display_);
149 WaylandWindow* window = display_->GetWindow(widget);
150 DCHECK(window);
151 return make_scoped_ptr(new WaylandCanvasSurface(display_, window));
152 }
153
154 scoped_ptr<SurfaceOzoneEGL> WaylandSurfaceFactory::CreateEGLSurfaceForWidget(
155 gfx::AcceleratedWidget widget) {
156 NOTREACHED();
157 return nullptr;
158 }
159
160 scoped_refptr<NativePixmap> WaylandSurfaceFactory::CreateNativePixmap(
161 gfx::AcceleratedWidget widget,
162 gfx::Size size,
163 gfx::BufferFormat format,
164 gfx::BufferUsage usage) {
165 NOTIMPLEMENTED();
166 return nullptr;
167 }
168
169 scoped_refptr<NativePixmap> WaylandSurfaceFactory::CreateNativePixmapFromHandle(
170 const gfx::NativePixmapHandle& handle) {
171 NOTIMPLEMENTED();
172 return nullptr;
173 }
174
175 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698