| 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 |