OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/gl/gl_image_io_surface.h" | 5 #include "ui/gl/gl_image_io_surface.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/callback_helpers.h" | 9 #include "base/callback_helpers.h" |
10 #include "base/mac/bind_objc_block.h" | 10 #include "base/mac/bind_objc_block.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 case GL_RGB: | 35 case GL_RGB: |
36 case GL_RGB_YCBCR_420V_CHROMIUM: | 36 case GL_RGB_YCBCR_420V_CHROMIUM: |
37 case GL_RGB_YCBCR_422_CHROMIUM: | 37 case GL_RGB_YCBCR_422_CHROMIUM: |
38 case GL_RGBA: | 38 case GL_RGBA: |
39 return true; | 39 return true; |
40 default: | 40 default: |
41 return false; | 41 return false; |
42 } | 42 } |
43 } | 43 } |
44 | 44 |
45 bool ValidFormat(BufferFormat format) { | 45 bool ValidFormat(gfx::BufferFormat format) { |
46 switch (format) { | 46 switch (format) { |
47 case BufferFormat::R_8: | 47 case gfx::BufferFormat::R_8: |
48 case BufferFormat::BGRA_8888: | 48 case gfx::BufferFormat::BGRA_8888: |
49 case BufferFormat::BGRX_8888: | 49 case gfx::BufferFormat::BGRX_8888: |
50 case BufferFormat::RGBA_8888: | 50 case gfx::BufferFormat::RGBA_8888: |
51 case BufferFormat::UYVY_422: | 51 case gfx::BufferFormat::UYVY_422: |
52 case BufferFormat::YUV_420_BIPLANAR: | 52 case gfx::BufferFormat::YUV_420_BIPLANAR: |
53 return true; | 53 return true; |
54 case BufferFormat::ATC: | 54 case gfx::BufferFormat::ATC: |
55 case BufferFormat::ATCIA: | 55 case gfx::BufferFormat::ATCIA: |
56 case BufferFormat::DXT1: | 56 case gfx::BufferFormat::DXT1: |
57 case BufferFormat::DXT5: | 57 case gfx::BufferFormat::DXT5: |
58 case BufferFormat::ETC1: | 58 case gfx::BufferFormat::ETC1: |
59 case BufferFormat::BGR_565: | 59 case gfx::BufferFormat::BGR_565: |
60 case BufferFormat::RGBA_4444: | 60 case gfx::BufferFormat::RGBA_4444: |
61 case BufferFormat::RGBX_8888: | 61 case gfx::BufferFormat::RGBX_8888: |
62 case BufferFormat::YUV_420: | 62 case gfx::BufferFormat::YUV_420: |
63 return false; | 63 return false; |
64 } | 64 } |
65 | 65 |
66 NOTREACHED(); | 66 NOTREACHED(); |
67 return false; | 67 return false; |
68 } | 68 } |
69 | 69 |
70 GLenum TextureFormat(BufferFormat format) { | 70 GLenum TextureFormat(gfx::BufferFormat format) { |
71 switch (format) { | 71 switch (format) { |
72 case BufferFormat::R_8: | 72 case gfx::BufferFormat::R_8: |
73 return GL_RED; | 73 return GL_RED; |
74 case BufferFormat::BGRA_8888: | 74 case gfx::BufferFormat::BGRA_8888: |
75 case BufferFormat::BGRX_8888: | 75 case gfx::BufferFormat::BGRX_8888: |
76 case BufferFormat::RGBA_8888: | 76 case gfx::BufferFormat::RGBA_8888: |
77 return GL_RGBA; | 77 return GL_RGBA; |
78 case BufferFormat::UYVY_422: | 78 case gfx::BufferFormat::UYVY_422: |
79 return GL_RGB; | 79 return GL_RGB; |
80 case BufferFormat::YUV_420_BIPLANAR: | 80 case gfx::BufferFormat::YUV_420_BIPLANAR: |
81 return GL_RGB_YCBCR_420V_CHROMIUM; | 81 return GL_RGB_YCBCR_420V_CHROMIUM; |
82 case BufferFormat::ATC: | 82 case gfx::BufferFormat::ATC: |
83 case BufferFormat::ATCIA: | 83 case gfx::BufferFormat::ATCIA: |
84 case BufferFormat::DXT1: | 84 case gfx::BufferFormat::DXT1: |
85 case BufferFormat::DXT5: | 85 case gfx::BufferFormat::DXT5: |
86 case BufferFormat::ETC1: | 86 case gfx::BufferFormat::ETC1: |
87 case BufferFormat::BGR_565: | 87 case gfx::BufferFormat::BGR_565: |
88 case BufferFormat::RGBA_4444: | 88 case gfx::BufferFormat::RGBA_4444: |
89 case BufferFormat::RGBX_8888: | 89 case gfx::BufferFormat::RGBX_8888: |
90 case BufferFormat::YUV_420: | 90 case gfx::BufferFormat::YUV_420: |
91 NOTREACHED(); | 91 NOTREACHED(); |
92 return 0; | 92 return 0; |
93 } | 93 } |
94 | 94 |
95 NOTREACHED(); | 95 NOTREACHED(); |
96 return 0; | 96 return 0; |
97 } | 97 } |
98 | 98 |
99 GLenum DataFormat(BufferFormat format) { | 99 GLenum DataFormat(gfx::BufferFormat format) { |
100 switch (format) { | 100 switch (format) { |
101 case BufferFormat::R_8: | 101 case gfx::BufferFormat::R_8: |
102 return GL_RED; | 102 return GL_RED; |
103 case BufferFormat::BGRA_8888: | 103 case gfx::BufferFormat::BGRA_8888: |
104 case BufferFormat::BGRX_8888: | 104 case gfx::BufferFormat::BGRX_8888: |
105 case BufferFormat::RGBA_8888: | 105 case gfx::BufferFormat::RGBA_8888: |
106 return GL_BGRA; | 106 return GL_BGRA; |
107 case BufferFormat::UYVY_422: | 107 case gfx::BufferFormat::UYVY_422: |
108 return GL_YCBCR_422_APPLE; | 108 return GL_YCBCR_422_APPLE; |
109 case BufferFormat::ATC: | 109 case gfx::BufferFormat::ATC: |
110 case BufferFormat::ATCIA: | 110 case gfx::BufferFormat::ATCIA: |
111 case BufferFormat::DXT1: | 111 case gfx::BufferFormat::DXT1: |
112 case BufferFormat::DXT5: | 112 case gfx::BufferFormat::DXT5: |
113 case BufferFormat::ETC1: | 113 case gfx::BufferFormat::ETC1: |
114 case BufferFormat::BGR_565: | 114 case gfx::BufferFormat::BGR_565: |
115 case BufferFormat::RGBA_4444: | 115 case gfx::BufferFormat::RGBA_4444: |
116 case BufferFormat::RGBX_8888: | 116 case gfx::BufferFormat::RGBX_8888: |
117 case BufferFormat::YUV_420: | 117 case gfx::BufferFormat::YUV_420: |
118 case BufferFormat::YUV_420_BIPLANAR: | 118 case gfx::BufferFormat::YUV_420_BIPLANAR: |
119 NOTREACHED(); | 119 NOTREACHED(); |
120 return 0; | 120 return 0; |
121 } | 121 } |
122 | 122 |
123 NOTREACHED(); | 123 NOTREACHED(); |
124 return 0; | 124 return 0; |
125 } | 125 } |
126 | 126 |
127 GLenum DataType(BufferFormat format) { | 127 GLenum DataType(gfx::BufferFormat format) { |
128 switch (format) { | 128 switch (format) { |
129 case BufferFormat::R_8: | 129 case gfx::BufferFormat::R_8: |
130 return GL_UNSIGNED_BYTE; | 130 return GL_UNSIGNED_BYTE; |
131 case BufferFormat::BGRA_8888: | 131 case gfx::BufferFormat::BGRA_8888: |
132 case BufferFormat::BGRX_8888: | 132 case gfx::BufferFormat::BGRX_8888: |
133 case BufferFormat::RGBA_8888: | 133 case gfx::BufferFormat::RGBA_8888: |
134 return GL_UNSIGNED_INT_8_8_8_8_REV; | 134 return GL_UNSIGNED_INT_8_8_8_8_REV; |
135 case BufferFormat::UYVY_422: | 135 case gfx::BufferFormat::UYVY_422: |
136 return GL_UNSIGNED_SHORT_8_8_APPLE; | 136 return GL_UNSIGNED_SHORT_8_8_APPLE; |
137 break; | 137 break; |
138 case BufferFormat::ATC: | 138 case gfx::BufferFormat::ATC: |
139 case BufferFormat::ATCIA: | 139 case gfx::BufferFormat::ATCIA: |
140 case BufferFormat::DXT1: | 140 case gfx::BufferFormat::DXT1: |
141 case BufferFormat::DXT5: | 141 case gfx::BufferFormat::DXT5: |
142 case BufferFormat::ETC1: | 142 case gfx::BufferFormat::ETC1: |
143 case BufferFormat::BGR_565: | 143 case gfx::BufferFormat::BGR_565: |
144 case BufferFormat::RGBA_4444: | 144 case gfx::BufferFormat::RGBA_4444: |
145 case BufferFormat::RGBX_8888: | 145 case gfx::BufferFormat::RGBX_8888: |
146 case BufferFormat::YUV_420: | 146 case gfx::BufferFormat::YUV_420: |
147 case BufferFormat::YUV_420_BIPLANAR: | 147 case gfx::BufferFormat::YUV_420_BIPLANAR: |
148 NOTREACHED(); | 148 NOTREACHED(); |
149 return 0; | 149 return 0; |
150 } | 150 } |
151 | 151 |
152 NOTREACHED(); | 152 NOTREACHED(); |
153 return 0; | 153 return 0; |
154 } | 154 } |
155 | 155 |
156 // When an IOSurface is bound to a texture with internalformat "GL_RGB", many | 156 // When an IOSurface is bound to a texture with internalformat "GL_RGB", many |
157 // OpenGL operations are broken. Therefore, never allow an IOSurface to be bound | 157 // OpenGL operations are broken. Therefore, never allow an IOSurface to be bound |
158 // with GL_RGB. https://crbug.com/595948. | 158 // with GL_RGB. https://crbug.com/595948. |
159 GLenum ConvertRequestedInternalFormat(GLenum internalformat) { | 159 GLenum ConvertRequestedInternalFormat(GLenum internalformat) { |
160 if (internalformat == GL_RGB) | 160 if (internalformat == GL_RGB) |
161 return GL_RGBA; | 161 return GL_RGBA; |
162 return internalformat; | 162 return internalformat; |
163 } | 163 } |
164 | 164 |
165 } // namespace | 165 } // namespace |
166 | 166 |
167 GLImageIOSurface::GLImageIOSurface(const gfx::Size& size, | 167 GLImageIOSurface::GLImageIOSurface(const gfx::Size& size, |
168 unsigned internalformat) | 168 unsigned internalformat) |
169 : size_(size), | 169 : size_(size), |
170 internalformat_(ConvertRequestedInternalFormat(internalformat)), | 170 internalformat_(ConvertRequestedInternalFormat(internalformat)), |
171 client_internalformat_(internalformat), | 171 client_internalformat_(internalformat), |
172 format_(BufferFormat::RGBA_8888) {} | 172 format_(gfx::BufferFormat::RGBA_8888) {} |
173 | 173 |
174 GLImageIOSurface::~GLImageIOSurface() { | 174 GLImageIOSurface::~GLImageIOSurface() { |
175 DCHECK(thread_checker_.CalledOnValidThread()); | 175 DCHECK(thread_checker_.CalledOnValidThread()); |
176 DCHECK(!io_surface_); | 176 DCHECK(!io_surface_); |
177 } | 177 } |
178 | 178 |
179 bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface, | 179 bool GLImageIOSurface::Initialize(IOSurfaceRef io_surface, |
180 gfx::GenericSharedMemoryId io_surface_id, | 180 gfx::GenericSharedMemoryId io_surface_id, |
181 BufferFormat format) { | 181 gfx::BufferFormat format) { |
182 DCHECK(thread_checker_.CalledOnValidThread()); | 182 DCHECK(thread_checker_.CalledOnValidThread()); |
183 DCHECK(!io_surface_); | 183 DCHECK(!io_surface_); |
184 | 184 |
185 if (!ValidInternalFormat(internalformat_)) { | 185 if (!ValidInternalFormat(internalformat_)) { |
186 LOG(ERROR) << "Invalid internalformat: " << internalformat_; | 186 LOG(ERROR) << "Invalid internalformat: " << internalformat_; |
187 return false; | 187 return false; |
188 } | 188 } |
189 | 189 |
190 if (!ValidFormat(format)) { | 190 if (!ValidFormat(format)) { |
191 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); | 191 LOG(ERROR) << "Invalid format: " << static_cast<int>(format); |
192 return false; | 192 return false; |
193 } | 193 } |
194 | 194 |
195 format_ = format; | 195 format_ = format; |
196 io_surface_.reset(io_surface, base::scoped_policy::RETAIN); | 196 io_surface_.reset(io_surface, base::scoped_policy::RETAIN); |
197 io_surface_id_ = io_surface_id; | 197 io_surface_id_ = io_surface_id; |
198 return true; | 198 return true; |
199 } | 199 } |
200 | 200 |
201 bool GLImageIOSurface::InitializeWithCVPixelBuffer( | 201 bool GLImageIOSurface::InitializeWithCVPixelBuffer( |
202 CVPixelBufferRef cv_pixel_buffer, | 202 CVPixelBufferRef cv_pixel_buffer, |
203 gfx::GenericSharedMemoryId io_surface_id, | 203 gfx::GenericSharedMemoryId io_surface_id, |
204 BufferFormat format) { | 204 gfx::BufferFormat format) { |
205 IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(cv_pixel_buffer); | 205 IOSurfaceRef io_surface = CVPixelBufferGetIOSurface(cv_pixel_buffer); |
206 if (!io_surface) { | 206 if (!io_surface) { |
207 LOG(ERROR) << "Can't init GLImage from CVPixelBuffer with no IOSurface"; | 207 LOG(ERROR) << "Can't init GLImage from CVPixelBuffer with no IOSurface"; |
208 return false; | 208 return false; |
209 } | 209 } |
210 | 210 |
211 if (!Initialize(io_surface, io_surface_id, format)) | 211 if (!Initialize(io_surface, io_surface_id, format)) |
212 return false; | 212 return false; |
213 | 213 |
214 cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); | 214 cv_pixel_buffer_.reset(cv_pixel_buffer, base::scoped_policy::RETAIN); |
(...skipping 13 matching lines...) Expand all Loading... |
228 unsigned GLImageIOSurface::GetInternalFormat() { | 228 unsigned GLImageIOSurface::GetInternalFormat() { |
229 return internalformat_; | 229 return internalformat_; |
230 } | 230 } |
231 | 231 |
232 bool GLImageIOSurface::BindTexImage(unsigned target) { | 232 bool GLImageIOSurface::BindTexImage(unsigned target) { |
233 DCHECK(thread_checker_.CalledOnValidThread()); | 233 DCHECK(thread_checker_.CalledOnValidThread()); |
234 | 234 |
235 // YUV_420_BIPLANAR is not supported by BindTexImage. | 235 // YUV_420_BIPLANAR is not supported by BindTexImage. |
236 // CopyTexImage is supported by this format as that performs conversion to RGB | 236 // CopyTexImage is supported by this format as that performs conversion to RGB |
237 // as part of the copy operation. | 237 // as part of the copy operation. |
238 if (format_ == BufferFormat::YUV_420_BIPLANAR) | 238 if (format_ == gfx::BufferFormat::YUV_420_BIPLANAR) |
239 return false; | 239 return false; |
240 | 240 |
241 if (target != GL_TEXTURE_RECTANGLE_ARB) { | 241 if (target != GL_TEXTURE_RECTANGLE_ARB) { |
242 // This might be supported in the future. For now, perform strict | 242 // This might be supported in the future. For now, perform strict |
243 // validation so we know what's going on. | 243 // validation so we know what's going on. |
244 LOG(ERROR) << "IOSurface requires TEXTURE_RECTANGLE_ARB target"; | 244 LOG(ERROR) << "IOSurface requires TEXTURE_RECTANGLE_ARB target"; |
245 return false; | 245 return false; |
246 } | 246 } |
247 | 247 |
248 CGLContextObj cgl_context = | 248 CGLContextObj cgl_context = |
249 static_cast<CGLContextObj>(gfx::GLContext::GetCurrent()->GetHandle()); | 249 static_cast<CGLContextObj>(gl::GLContext::GetCurrent()->GetHandle()); |
250 | 250 |
251 DCHECK(io_surface_); | 251 DCHECK(io_surface_); |
252 CGLError cgl_error = | 252 CGLError cgl_error = |
253 CGLTexImageIOSurface2D(cgl_context, target, TextureFormat(format_), | 253 CGLTexImageIOSurface2D(cgl_context, target, TextureFormat(format_), |
254 size_.width(), size_.height(), DataFormat(format_), | 254 size_.width(), size_.height(), DataFormat(format_), |
255 DataType(format_), io_surface_.get(), 0); | 255 DataType(format_), io_surface_.get(), 0); |
256 if (cgl_error != kCGLNoError) { | 256 if (cgl_error != kCGLNoError) { |
257 LOG(ERROR) << "Error in CGLTexImageIOSurface2D: " | 257 LOG(ERROR) << "Error in CGLTexImageIOSurface2D: " |
258 << CGLErrorString(cgl_error); | 258 << CGLErrorString(cgl_error); |
259 return false; | 259 return false; |
260 } | 260 } |
261 | 261 |
262 return true; | 262 return true; |
263 } | 263 } |
264 | 264 |
265 bool GLImageIOSurface::CopyTexImage(unsigned target) { | 265 bool GLImageIOSurface::CopyTexImage(unsigned target) { |
266 DCHECK(thread_checker_.CalledOnValidThread()); | 266 DCHECK(thread_checker_.CalledOnValidThread()); |
267 | 267 |
268 if (format_ != BufferFormat::YUV_420_BIPLANAR) | 268 if (format_ != gfx::BufferFormat::YUV_420_BIPLANAR) |
269 return false; | 269 return false; |
270 | 270 |
271 if (target != GL_TEXTURE_RECTANGLE_ARB) { | 271 if (target != GL_TEXTURE_RECTANGLE_ARB) { |
272 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; | 272 LOG(ERROR) << "YUV_420_BIPLANAR requires GL_TEXTURE_RECTANGLE_ARB target"; |
273 return false; | 273 return false; |
274 } | 274 } |
275 | 275 |
276 gfx::GLContext* gl_context = gfx::GLContext::GetCurrent(); | 276 gl::GLContext* gl_context = gl::GLContext::GetCurrent(); |
277 DCHECK(gl_context); | 277 DCHECK(gl_context); |
278 | 278 |
279 gl::YUVToRGBConverter* yuv_to_rgb_converter = | 279 gl::YUVToRGBConverter* yuv_to_rgb_converter = |
280 gl_context->GetYUVToRGBConverter(); | 280 gl_context->GetYUVToRGBConverter(); |
281 DCHECK(yuv_to_rgb_converter); | 281 DCHECK(yuv_to_rgb_converter); |
282 | 282 |
283 gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; | 283 gl::ScopedSetGLToRealGLApi scoped_set_gl_api; |
284 | 284 |
285 // Note that state restoration is done explicitly instead of scoped binders to | 285 // Note that state restoration is done explicitly instead of scoped binders to |
286 // avoid https://crbug.com/601729. | 286 // avoid https://crbug.com/601729. |
287 GLint rgb_texture = 0; | 287 GLint rgb_texture = 0; |
288 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &rgb_texture); | 288 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &rgb_texture); |
289 base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{ | 289 base::ScopedClosureRunner destroy_resources_runner(base::BindBlock(^{ |
290 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, rgb_texture); | 290 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, rgb_texture); |
291 })); | 291 })); |
292 | 292 |
293 CGLContextObj cgl_context = CGLGetCurrentContext(); | 293 CGLContextObj cgl_context = CGLGetCurrentContext(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 return cv_pixel_buffer_; | 367 return cv_pixel_buffer_; |
368 } | 368 } |
369 | 369 |
370 // static | 370 // static |
371 unsigned GLImageIOSurface::GetInternalFormatForTesting( | 371 unsigned GLImageIOSurface::GetInternalFormatForTesting( |
372 gfx::BufferFormat format) { | 372 gfx::BufferFormat format) { |
373 DCHECK(ValidFormat(format)); | 373 DCHECK(ValidFormat(format)); |
374 return TextureFormat(format); | 374 return TextureFormat(format); |
375 } | 375 } |
376 } // namespace gl | 376 } // namespace gl |
OLD | NEW |