OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "ui/ozone/gl/gl_image_ozone_native_pixmap.h" |
| 6 |
| 7 #include <vector> |
| 8 |
5 #include "ui/gfx/buffer_format_util.h" | 9 #include "ui/gfx/buffer_format_util.h" |
6 #include "ui/gl/gl_image_ozone_native_pixmap.h" | |
7 #include "ui/gl/gl_surface_egl.h" | 10 #include "ui/gl/gl_surface_egl.h" |
8 | 11 |
9 #define FOURCC(a, b, c, d) \ | 12 #define FOURCC(a, b, c, d) \ |
10 ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \ | 13 ((static_cast<uint32_t>(a)) | (static_cast<uint32_t>(b) << 8) | \ |
11 (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24)) | 14 (static_cast<uint32_t>(c) << 16) | (static_cast<uint32_t>(d) << 24)) |
12 | 15 |
13 #define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ') | 16 #define DRM_FORMAT_R8 FOURCC('R', '8', ' ', ' ') |
14 #define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6') | 17 #define DRM_FORMAT_RGB565 FOURCC('R', 'G', '1', '6') |
15 #define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4') | 18 #define DRM_FORMAT_ARGB8888 FOURCC('A', 'R', '2', '4') |
16 #define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4') | 19 #define DRM_FORMAT_ABGR8888 FOURCC('A', 'B', '2', '4') |
17 #define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4') | 20 #define DRM_FORMAT_XRGB8888 FOURCC('X', 'R', '2', '4') |
18 #define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4') | 21 #define DRM_FORMAT_XBGR8888 FOURCC('X', 'B', '2', '4') |
19 #define DRM_FORMAT_YV12 FOURCC('Y', 'V', '1', '2') | 22 #define DRM_FORMAT_YV12 FOURCC('Y', 'V', '1', '2') |
20 | 23 |
21 namespace gl { | 24 namespace ui { |
22 namespace { | 25 namespace { |
23 | 26 |
24 bool ValidInternalFormat(unsigned internalformat, gfx::BufferFormat format) { | 27 bool ValidInternalFormat(unsigned internalformat, gfx::BufferFormat format) { |
25 switch (internalformat) { | 28 switch (internalformat) { |
26 case GL_RGB: | 29 case GL_RGB: |
27 return format == gfx::BufferFormat::BGR_565 || | 30 return format == gfx::BufferFormat::BGR_565 || |
28 format == gfx::BufferFormat::RGBX_8888 || | 31 format == gfx::BufferFormat::RGBX_8888 || |
29 format == gfx::BufferFormat::BGRX_8888; | 32 format == gfx::BufferFormat::BGRX_8888; |
30 case GL_RGB_YCRCB_420_CHROMIUM: | 33 case GL_RGB_YCRCB_420_CHROMIUM: |
31 return format == gfx::BufferFormat::YVU_420; | 34 return format == gfx::BufferFormat::YVU_420; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 return 0; | 100 return 0; |
98 } | 101 } |
99 | 102 |
100 } // namespace | 103 } // namespace |
101 | 104 |
102 GLImageOzoneNativePixmap::GLImageOzoneNativePixmap(const gfx::Size& size, | 105 GLImageOzoneNativePixmap::GLImageOzoneNativePixmap(const gfx::Size& size, |
103 unsigned internalformat) | 106 unsigned internalformat) |
104 : GLImageEGL(size), | 107 : GLImageEGL(size), |
105 internalformat_(internalformat), | 108 internalformat_(internalformat), |
106 has_image_flush_external_( | 109 has_image_flush_external_( |
107 GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external")) {} | 110 gl::GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_flush_external")) {} |
108 | 111 |
109 GLImageOzoneNativePixmap::~GLImageOzoneNativePixmap() { | 112 GLImageOzoneNativePixmap::~GLImageOzoneNativePixmap() {} |
110 } | |
111 | 113 |
112 bool GLImageOzoneNativePixmap::Initialize(ui::NativePixmap* pixmap, | 114 bool GLImageOzoneNativePixmap::Initialize(NativePixmap* pixmap, |
113 gfx::BufferFormat format) { | 115 gfx::BufferFormat format) { |
114 DCHECK(!pixmap_); | 116 DCHECK(!pixmap_); |
115 if (pixmap->GetEGLClientBuffer()) { | 117 if (pixmap->GetEGLClientBuffer()) { |
116 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; | 118 EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
117 if (!GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR, | 119 if (!GLImageEGL::Initialize(EGL_NATIVE_PIXMAP_KHR, |
118 pixmap->GetEGLClientBuffer(), attrs)) { | 120 pixmap->GetEGLClientBuffer(), attrs)) { |
119 return false; | 121 return false; |
120 } | 122 } |
121 } else if (pixmap->AreDmaBufFdsValid()) { | 123 } else if (pixmap->AreDmaBufFdsValid()) { |
122 | |
123 if (!ValidFormat(format)) { | 124 if (!ValidFormat(format)) { |
124 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); | 125 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); |
125 return false; | 126 return false; |
126 } | 127 } |
127 | 128 |
128 if (!ValidInternalFormat(internalformat_, format)) { | 129 if (!ValidInternalFormat(internalformat_, format)) { |
129 LOG(ERROR) << "Invalid internalformat: " << internalformat_ | 130 LOG(ERROR) << "Invalid internalformat: " << internalformat_ |
130 << " for format: " << static_cast<int>(format); | 131 << " for format: " << static_cast<int>(format); |
131 return false; | 132 return false; |
132 } | 133 } |
133 | 134 |
134 // Note: If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT | 135 // Note: If eglCreateImageKHR is successful for a EGL_LINUX_DMA_BUF_EXT |
135 // target, the EGL will take a reference to the dma_buf. | 136 // target, the EGL will take a reference to the dma_buf. |
136 std::vector<EGLint> attrs; | 137 std::vector<EGLint> attrs; |
137 attrs.push_back(EGL_WIDTH); | 138 attrs.push_back(EGL_WIDTH); |
138 attrs.push_back(size_.width()); | 139 attrs.push_back(size_.width()); |
139 attrs.push_back(EGL_HEIGHT); | 140 attrs.push_back(EGL_HEIGHT); |
140 attrs.push_back(size_.height()); | 141 attrs.push_back(size_.height()); |
141 attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT); | 142 attrs.push_back(EGL_LINUX_DRM_FOURCC_EXT); |
142 attrs.push_back(FourCC(format)); | 143 attrs.push_back(FourCC(format)); |
143 | 144 |
144 const EGLint kLinuxDrmModifiers[] = {EGL_LINUX_DRM_PLANE0_MODIFIER0_EXT, | 145 const EGLint kLinuxDrmModifiers[] = {EGL_LINUX_DRM_PLANE0_MODIFIER0_EXT, |
145 EGL_LINUX_DRM_PLANE1_MODIFIER0_EXT, | 146 EGL_LINUX_DRM_PLANE1_MODIFIER0_EXT, |
146 EGL_LINUX_DRM_PLANE2_MODIFIER0_EXT}; | 147 EGL_LINUX_DRM_PLANE2_MODIFIER0_EXT}; |
147 bool has_dma_buf_import_modifier = | 148 bool has_dma_buf_import_modifier = gl::GLSurfaceEGL::HasEGLExtension( |
148 GLSurfaceEGL::HasEGLExtension("EGL_EXT_image_dma_buf_import_modifiers"); | 149 "EGL_EXT_image_dma_buf_import_modifiers"); |
149 | 150 |
150 for (size_t plane = 0; | 151 for (size_t plane = 0; |
151 plane < gfx::NumberOfPlanesForBufferFormat(pixmap->GetBufferFormat()); | 152 plane < gfx::NumberOfPlanesForBufferFormat(pixmap->GetBufferFormat()); |
152 ++plane) { | 153 ++plane) { |
153 attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3); | 154 attrs.push_back(EGL_DMA_BUF_PLANE0_FD_EXT + plane * 3); |
154 attrs.push_back( | 155 attrs.push_back( |
155 pixmap->GetDmaBufFd(plane < pixmap->GetDmaBufFdCount() ? plane : 0)); | 156 pixmap->GetDmaBufFd(plane < pixmap->GetDmaBufFdCount() ? plane : 0)); |
156 attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3); | 157 attrs.push_back(EGL_DMA_BUF_PLANE0_OFFSET_EXT + plane * 3); |
157 attrs.push_back(pixmap->GetDmaBufOffset(plane)); | 158 attrs.push_back(pixmap->GetDmaBufOffset(plane)); |
158 attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3); | 159 attrs.push_back(EGL_DMA_BUF_PLANE0_PITCH_EXT + plane * 3); |
(...skipping 26 matching lines...) Expand all Loading... |
185 | 186 |
186 void GLImageOzoneNativePixmap::Destroy(bool have_context) { | 187 void GLImageOzoneNativePixmap::Destroy(bool have_context) { |
187 GLImageEGL::Destroy(have_context); | 188 GLImageEGL::Destroy(have_context); |
188 } | 189 } |
189 | 190 |
190 bool GLImageOzoneNativePixmap::CopyTexImage(unsigned target) { | 191 bool GLImageOzoneNativePixmap::CopyTexImage(unsigned target) { |
191 if (egl_image_ == EGL_NO_IMAGE_KHR) { | 192 if (egl_image_ == EGL_NO_IMAGE_KHR) { |
192 // Pass-through image type fails to bind and copy; make sure we | 193 // Pass-through image type fails to bind and copy; make sure we |
193 // don't draw with uninitialized texture. | 194 // don't draw with uninitialized texture. |
194 std::vector<unsigned char> data(size_.width() * size_.height() * 4); | 195 std::vector<unsigned char> data(size_.width() * size_.height() * 4); |
195 glTexImage2D(target, 0, GL_RGBA, size_.width(), | 196 glTexImage2D(target, 0, GL_RGBA, size_.width(), size_.height(), 0, GL_RGBA, |
196 size_.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, | 197 GL_UNSIGNED_BYTE, data.data()); |
197 data.data()); | |
198 return true; | 198 return true; |
199 } | 199 } |
200 return GLImageEGL::CopyTexImage(target); | 200 return GLImageEGL::CopyTexImage(target); |
201 } | 201 } |
202 | 202 |
203 bool GLImageOzoneNativePixmap::ScheduleOverlayPlane( | 203 bool GLImageOzoneNativePixmap::ScheduleOverlayPlane( |
204 gfx::AcceleratedWidget widget, | 204 gfx::AcceleratedWidget widget, |
205 int z_order, | 205 int z_order, |
206 gfx::OverlayTransform transform, | 206 gfx::OverlayTransform transform, |
207 const gfx::Rect& bounds_rect, | 207 const gfx::Rect& bounds_rect, |
208 const gfx::RectF& crop_rect) { | 208 const gfx::RectF& crop_rect) { |
209 DCHECK(pixmap_); | 209 DCHECK(pixmap_); |
210 return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect, | 210 return pixmap_->ScheduleOverlayPlane(widget, z_order, transform, bounds_rect, |
211 crop_rect); | 211 crop_rect); |
212 } | 212 } |
213 | 213 |
214 void GLImageOzoneNativePixmap::Flush() { | 214 void GLImageOzoneNativePixmap::Flush() { |
215 if (!has_image_flush_external_) | 215 if (!has_image_flush_external_) |
216 return; | 216 return; |
217 | 217 |
218 EGLDisplay display = GLSurfaceEGL::GetHardwareDisplay(); | 218 EGLDisplay display = gl::GLSurfaceEGL::GetHardwareDisplay(); |
219 const EGLAttrib attribs[] = { | 219 const EGLAttrib attribs[] = { |
220 EGL_NONE, | 220 EGL_NONE, |
221 }; | 221 }; |
222 if (!eglImageFlushExternalEXT(display, egl_image_, attribs)) { | 222 if (!eglImageFlushExternalEXT(display, egl_image_, attribs)) { |
223 LOG(ERROR) << "Failed to flush rendering"; | 223 LOG(ERROR) << "Failed to flush rendering"; |
224 return; | 224 return; |
225 } | 225 } |
226 } | 226 } |
227 | 227 |
228 void GLImageOzoneNativePixmap::OnMemoryDump( | 228 void GLImageOzoneNativePixmap::OnMemoryDump( |
(...skipping 28 matching lines...) Expand all Loading... |
257 case gfx::BufferFormat::YUV_420_BIPLANAR: | 257 case gfx::BufferFormat::YUV_420_BIPLANAR: |
258 case gfx::BufferFormat::UYVY_422: | 258 case gfx::BufferFormat::UYVY_422: |
259 NOTREACHED(); | 259 NOTREACHED(); |
260 return GL_NONE; | 260 return GL_NONE; |
261 } | 261 } |
262 | 262 |
263 NOTREACHED(); | 263 NOTREACHED(); |
264 return GL_NONE; | 264 return GL_NONE; |
265 } | 265 } |
266 | 266 |
267 } // namespace gl | 267 } // namespace ui |
OLD | NEW |