OLD | NEW |
| (Empty) |
1 // Copyright 2014 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/gpu/gpu_memory_buffer_factory_ozone_native_pixmap.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "ui/gl/gl_image_egl.h" | |
9 #include "ui/gl/gl_image_linux_dma_buffer.h" | |
10 #include "ui/ozone/public/native_pixmap.h" | |
11 #include "ui/ozone/public/ozone_platform.h" | |
12 #include "ui/ozone/public/surface_factory_ozone.h" | |
13 #include "ui/ozone/public/surface_ozone_egl.h" | |
14 | |
15 namespace ui { | |
16 namespace { | |
17 class GLImageOzoneNativePixmap : public gfx::GLImageEGL { | |
18 public: | |
19 explicit GLImageOzoneNativePixmap(const gfx::Size& size) : GLImageEGL(size) {} | |
20 | |
21 void Destroy(bool have_context) override { | |
22 gfx::GLImageEGL::Destroy(have_context); | |
23 pixmap_ = nullptr; | |
24 } | |
25 | |
26 bool Initialize(NativePixmap* pixmap) { | |
27 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | |
28 if (!Initialize(EGL_NATIVE_PIXMAP_KHR, pixmap->GetEGLClientBuffer(), attrs)) | |
29 return false; | |
30 pixmap_ = pixmap; | |
31 return true; | |
32 } | |
33 | |
34 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
35 int z_order, | |
36 gfx::OverlayTransform transform, | |
37 const gfx::Rect& bounds_rect, | |
38 const gfx::RectF& crop_rect) override { | |
39 return pixmap_ && | |
40 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
41 bounds_rect, crop_rect); | |
42 } | |
43 | |
44 protected: | |
45 ~GLImageOzoneNativePixmap() override {} | |
46 | |
47 private: | |
48 using gfx::GLImageEGL::Initialize; | |
49 scoped_refptr<NativePixmap> pixmap_; | |
50 }; | |
51 | |
52 class GLImageOzoneNativePixmapDmaBuf : public gfx::GLImageLinuxDMABuffer { | |
53 public: | |
54 GLImageOzoneNativePixmapDmaBuf(const gfx::Size& size, unsigned internalformat) | |
55 : GLImageLinuxDMABuffer(size, internalformat) {} | |
56 | |
57 void Destroy(bool have_context) override { | |
58 gfx::GLImageLinuxDMABuffer::Destroy(have_context); | |
59 pixmap_ = nullptr; | |
60 } | |
61 | |
62 bool Initialize(NativePixmap* pixmap, gfx::GpuMemoryBuffer::Format format) { | |
63 base::FileDescriptor handle(pixmap->GetDmaBufFd(), false); | |
64 if (!GLImageLinuxDMABuffer::Initialize(handle, format, | |
65 pixmap->GetDmaBufPitch())) | |
66 return false; | |
67 pixmap_ = pixmap; | |
68 return true; | |
69 } | |
70 | |
71 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
72 int z_order, | |
73 gfx::OverlayTransform transform, | |
74 const gfx::Rect& bounds_rect, | |
75 const gfx::RectF& crop_rect) override { | |
76 return pixmap_ && | |
77 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
78 bounds_rect, crop_rect); | |
79 } | |
80 | |
81 protected: | |
82 ~GLImageOzoneNativePixmapDmaBuf() override {} | |
83 | |
84 private: | |
85 scoped_refptr<NativePixmap> pixmap_; | |
86 }; | |
87 | |
88 class GLImageOzoneOverlayOnlyPassThrough : public gfx::GLImage { | |
89 public: | |
90 GLImageOzoneOverlayOnlyPassThrough(scoped_refptr<NativePixmap> pixmap, | |
91 const gfx::Size& size, | |
92 unsigned internalformat) | |
93 : pixmap_(pixmap), size_(size), internalformat_(internalformat) {} | |
94 | |
95 void Destroy(bool have_context) override { pixmap_ = nullptr; } | |
96 gfx::Size GetSize() override { return size_; } | |
97 unsigned GetInternalFormat() override { return internalformat_; } | |
98 bool BindTexImage(unsigned target) override { return true; } | |
99 void ReleaseTexImage(unsigned target) override {} | |
100 bool CopyTexSubImage(unsigned target, | |
101 const gfx::Point& offset, | |
102 const gfx::Rect& rect) override { | |
103 return false; | |
104 } | |
105 void WillUseTexImage() override {} | |
106 void DidUseTexImage() override {} | |
107 void WillModifyTexImage() override {} | |
108 void DidModifyTexImage() override {} | |
109 bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
110 int z_order, | |
111 gfx::OverlayTransform transform, | |
112 const gfx::Rect& bounds_rect, | |
113 const gfx::RectF& crop_rect) override { | |
114 return pixmap_ && | |
115 pixmap_->ScheduleOverlayPlane(widget, z_order, transform, | |
116 bounds_rect, crop_rect); | |
117 } | |
118 | |
119 protected: | |
120 ~GLImageOzoneOverlayOnlyPassThrough() override {} | |
121 | |
122 private: | |
123 scoped_refptr<NativePixmap> pixmap_; | |
124 const gfx::Size size_; | |
125 unsigned internalformat_; | |
126 }; | |
127 | |
128 SurfaceFactoryOzone::BufferFormat GetOzoneFormatFor( | |
129 gfx::GpuMemoryBuffer::Format format) { | |
130 switch (format) { | |
131 case gfx::GpuMemoryBuffer::BGRA_8888: | |
132 return SurfaceFactoryOzone::BGRA_8888; | |
133 case gfx::GpuMemoryBuffer::RGBX_8888: | |
134 return SurfaceFactoryOzone::RGBX_8888; | |
135 case gfx::GpuMemoryBuffer::ATC: | |
136 case gfx::GpuMemoryBuffer::ATCIA: | |
137 case gfx::GpuMemoryBuffer::DXT1: | |
138 case gfx::GpuMemoryBuffer::DXT5: | |
139 case gfx::GpuMemoryBuffer::ETC1: | |
140 case gfx::GpuMemoryBuffer::R_8: | |
141 case gfx::GpuMemoryBuffer::RGBA_4444: | |
142 case gfx::GpuMemoryBuffer::RGBA_8888: | |
143 case gfx::GpuMemoryBuffer::YUV_420: | |
144 NOTREACHED(); | |
145 return SurfaceFactoryOzone::BGRA_8888; | |
146 } | |
147 | |
148 NOTREACHED(); | |
149 return SurfaceFactoryOzone::BGRA_8888; | |
150 } | |
151 | |
152 SurfaceFactoryOzone::BufferUsage GetOzoneUsageFor( | |
153 gfx::GpuMemoryBuffer::Usage usage) { | |
154 switch (usage) { | |
155 case gfx::GpuMemoryBuffer::MAP: | |
156 return SurfaceFactoryOzone::MAP; | |
157 case gfx::GpuMemoryBuffer::PERSISTENT_MAP: | |
158 return SurfaceFactoryOzone::PERSISTENT_MAP; | |
159 case gfx::GpuMemoryBuffer::SCANOUT: | |
160 return SurfaceFactoryOzone::SCANOUT; | |
161 } | |
162 | |
163 NOTREACHED(); | |
164 return SurfaceFactoryOzone::MAP; | |
165 } | |
166 | |
167 std::pair<uint32_t, uint32_t> GetIndex(gfx::GpuMemoryBufferId id, | |
168 int client_id) { | |
169 return std::pair<uint32_t, uint32_t>(id, client_id); | |
170 } | |
171 } // namespace | |
172 | |
173 GpuMemoryBufferFactoryOzoneNativePixmap:: | |
174 GpuMemoryBufferFactoryOzoneNativePixmap() {} | |
175 | |
176 GpuMemoryBufferFactoryOzoneNativePixmap:: | |
177 ~GpuMemoryBufferFactoryOzoneNativePixmap() {} | |
178 | |
179 bool GpuMemoryBufferFactoryOzoneNativePixmap::CreateGpuMemoryBuffer( | |
180 gfx::GpuMemoryBufferId id, | |
181 const gfx::Size& size, | |
182 gfx::GpuMemoryBuffer::Format format, | |
183 gfx::GpuMemoryBuffer::Usage usage, | |
184 int client_id, | |
185 gfx::PluginWindowHandle surface_handle) { | |
186 scoped_refptr<NativePixmap> pixmap = | |
187 OzonePlatform::GetInstance() | |
188 ->GetSurfaceFactoryOzone() | |
189 ->CreateNativePixmap(surface_handle, size, GetOzoneFormatFor(format), | |
190 GetOzoneUsageFor(usage)); | |
191 if (!pixmap.get()) { | |
192 LOG(ERROR) << "Failed to create pixmap " << size.width() << "x" | |
193 << size.height() << " format " << format << ", usage " << usage; | |
194 return false; | |
195 } | |
196 base::AutoLock lock(native_pixmap_map_lock_); | |
197 native_pixmap_map_[GetIndex(id, client_id)] = pixmap; | |
198 return true; | |
199 } | |
200 | |
201 void GpuMemoryBufferFactoryOzoneNativePixmap::DestroyGpuMemoryBuffer( | |
202 gfx::GpuMemoryBufferId id, | |
203 int client_id) { | |
204 base::AutoLock lock(native_pixmap_map_lock_); | |
205 native_pixmap_map_.erase(GetIndex(id, client_id)); | |
206 } | |
207 | |
208 scoped_refptr<gfx::GLImage> | |
209 GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForGpuMemoryBuffer( | |
210 gfx::GpuMemoryBufferId id, | |
211 const gfx::Size& size, | |
212 gfx::GpuMemoryBuffer::Format format, | |
213 unsigned internalformat, | |
214 int client_id) { | |
215 NativePixmap* pixmap = nullptr; | |
216 { | |
217 base::AutoLock lock(native_pixmap_map_lock_); | |
218 BufferToPixmapMap::iterator it = | |
219 native_pixmap_map_.find(GetIndex(id, client_id)); | |
220 if (it == native_pixmap_map_.end()) { | |
221 return scoped_refptr<gfx::GLImage>(); | |
222 } | |
223 pixmap = it->second.get(); | |
224 } | |
225 return CreateImageForPixmap(pixmap, size, format, internalformat); | |
226 } | |
227 | |
228 scoped_refptr<gfx::GLImage> | |
229 GpuMemoryBufferFactoryOzoneNativePixmap::CreateImageForPixmap( | |
230 scoped_refptr<NativePixmap> pixmap, | |
231 const gfx::Size& size, | |
232 gfx::GpuMemoryBuffer::Format format, | |
233 unsigned internalformat) { | |
234 if (!pixmap.get()) { | |
235 NOTREACHED(); | |
236 return scoped_refptr<gfx::GLImage>(); | |
237 } | |
238 | |
239 if (pixmap->GetEGLClientBuffer()) { | |
240 scoped_refptr<GLImageOzoneNativePixmap> image = | |
241 new GLImageOzoneNativePixmap(size); | |
242 if (!image->Initialize(pixmap.get())) { | |
243 return scoped_refptr<gfx::GLImage>(); | |
244 } | |
245 return image; | |
246 } | |
247 if (pixmap->GetDmaBufFd() > 0) { | |
248 scoped_refptr<GLImageOzoneNativePixmapDmaBuf> image = | |
249 new GLImageOzoneNativePixmapDmaBuf(size, internalformat); | |
250 if (!image->Initialize(pixmap.get(), format)) { | |
251 return scoped_refptr<gfx::GLImage>(); | |
252 } | |
253 return image; | |
254 } | |
255 return new GLImageOzoneOverlayOnlyPassThrough(pixmap, size, internalformat); | |
256 } | |
257 | |
258 } // namespace ui | |
OLD | NEW |