Chromium Code Reviews| 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/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 10 #include "base/mac/foundation_util.h" | 11 #include "base/mac/foundation_util.h" |
| 12 #include "base/strings/stringize_macros.h" | |
| 11 #include "base/trace_event/memory_allocator_dump.h" | 13 #include "base/trace_event/memory_allocator_dump.h" |
| 12 #include "base/trace_event/memory_dump_manager.h" | 14 #include "base/trace_event/memory_dump_manager.h" |
| 13 #include "base/trace_event/process_memory_dump.h" | 15 #include "base/trace_event/process_memory_dump.h" |
| 14 #include "ui/gl/gl_bindings.h" | 16 #include "ui/gl/gl_bindings.h" |
| 15 #include "ui/gl/gl_context.h" | 17 #include "ui/gl/gl_context.h" |
| 18 #include "ui/gl/gl_helper.h" | |
| 19 #include "ui/gl/scoped_binders.h" | |
| 16 | 20 |
| 17 // Note that this must be included after gl_bindings.h to avoid conflicts. | 21 // Note that this must be included after gl_bindings.h to avoid conflicts. |
| 18 #include <OpenGL/CGLIOSurface.h> | 22 #include <OpenGL/CGLIOSurface.h> |
| 19 #include <Quartz/Quartz.h> | 23 #include <Quartz/Quartz.h> |
| 20 | 24 |
| 21 namespace gfx { | 25 namespace gfx { |
| 22 namespace { | 26 namespace { |
| 23 | 27 |
| 24 using WidgetToLayerMap = std::map<AcceleratedWidget, CALayer*>; | 28 using WidgetToLayerMap = std::map<AcceleratedWidget, CALayer*>; |
| 25 base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map; | 29 base::LazyInstance<WidgetToLayerMap> g_widget_to_layer_map; |
| 26 | 30 |
| 27 bool ValidInternalFormat(unsigned internalformat) { | 31 bool ValidInternalFormat(unsigned internalformat) { |
| 28 switch (internalformat) { | 32 switch (internalformat) { |
| 29 case GL_R8: | 33 case GL_R8: |
| 30 case GL_BGRA_EXT: | 34 case GL_BGRA_EXT: |
| 31 case GL_RGB: | 35 case GL_RGB: |
| 36 case GL_RGB_YCBCR_420V_CHROMIUM: | |
| 32 case GL_RGB_YCBCR_422_CHROMIUM: | 37 case GL_RGB_YCBCR_422_CHROMIUM: |
| 33 return true; | 38 return true; |
| 34 default: | 39 default: |
| 35 return false; | 40 return false; |
| 36 } | 41 } |
| 37 } | 42 } |
| 38 | 43 |
| 39 bool ValidFormat(BufferFormat format) { | 44 bool ValidFormat(BufferFormat format) { |
| 40 switch (format) { | 45 switch (format) { |
| 41 case BufferFormat::R_8: | 46 case BufferFormat::R_8: |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 56 return false; | 61 return false; |
| 57 } | 62 } |
| 58 | 63 |
| 59 NOTREACHED(); | 64 NOTREACHED(); |
| 60 return false; | 65 return false; |
| 61 } | 66 } |
| 62 | 67 |
| 63 GLenum TextureFormat(BufferFormat format) { | 68 GLenum TextureFormat(BufferFormat format) { |
| 64 switch (format) { | 69 switch (format) { |
| 65 case BufferFormat::R_8: | 70 case BufferFormat::R_8: |
| 66 case BufferFormat::YUV_420_BIPLANAR: | |
| 67 return GL_RED; | 71 return GL_RED; |
| 68 case BufferFormat::BGRA_8888: | 72 case BufferFormat::BGRA_8888: |
| 69 return GL_RGBA; | 73 return GL_RGBA; |
| 70 case BufferFormat::UYVY_422: | 74 case BufferFormat::UYVY_422: |
| 71 return GL_RGB; | |
| 72 case BufferFormat::ATC: | 75 case BufferFormat::ATC: |
| 73 case BufferFormat::ATCIA: | 76 case BufferFormat::ATCIA: |
| 74 case BufferFormat::DXT1: | 77 case BufferFormat::DXT1: |
| 75 case BufferFormat::DXT5: | 78 case BufferFormat::DXT5: |
| 76 case BufferFormat::ETC1: | 79 case BufferFormat::ETC1: |
| 77 case BufferFormat::RGBA_4444: | 80 case BufferFormat::RGBA_4444: |
| 78 case BufferFormat::RGBA_8888: | 81 case BufferFormat::RGBA_8888: |
| 79 case BufferFormat::RGBX_8888: | 82 case BufferFormat::RGBX_8888: |
| 80 case BufferFormat::BGRX_8888: | 83 case BufferFormat::BGRX_8888: |
| 81 case BufferFormat::YUV_420: | 84 case BufferFormat::YUV_420: |
| 85 case BufferFormat::YUV_420_BIPLANAR: | |
| 82 NOTREACHED(); | 86 NOTREACHED(); |
| 83 return 0; | 87 return 0; |
| 84 } | 88 } |
| 85 | 89 |
| 86 NOTREACHED(); | 90 NOTREACHED(); |
| 87 return 0; | 91 return 0; |
| 88 } | 92 } |
| 89 | 93 |
| 90 GLenum DataFormat(BufferFormat format) { | 94 GLenum DataFormat(BufferFormat format) { |
| 91 switch (format) { | 95 switch (format) { |
| 92 case BufferFormat::R_8: | 96 case BufferFormat::R_8: |
| 93 case BufferFormat::YUV_420_BIPLANAR: | |
| 94 return GL_RED; | 97 return GL_RED; |
| 95 case BufferFormat::BGRA_8888: | 98 case BufferFormat::BGRA_8888: |
| 96 return GL_BGRA; | 99 return GL_BGRA; |
| 97 case BufferFormat::UYVY_422: | 100 case BufferFormat::UYVY_422: |
| 98 return GL_YCBCR_422_APPLE; | 101 return GL_YCBCR_422_APPLE; |
| 99 break; | |
| 100 case BufferFormat::ATC: | 102 case BufferFormat::ATC: |
| 101 case BufferFormat::ATCIA: | 103 case BufferFormat::ATCIA: |
| 102 case BufferFormat::DXT1: | 104 case BufferFormat::DXT1: |
| 103 case BufferFormat::DXT5: | 105 case BufferFormat::DXT5: |
| 104 case BufferFormat::ETC1: | 106 case BufferFormat::ETC1: |
| 105 case BufferFormat::RGBA_4444: | 107 case BufferFormat::RGBA_4444: |
| 106 case BufferFormat::RGBA_8888: | 108 case BufferFormat::RGBA_8888: |
| 107 case BufferFormat::RGBX_8888: | 109 case BufferFormat::RGBX_8888: |
| 108 case BufferFormat::BGRX_8888: | 110 case BufferFormat::BGRX_8888: |
| 109 case BufferFormat::YUV_420: | 111 case BufferFormat::YUV_420: |
| 112 case BufferFormat::YUV_420_BIPLANAR: | |
| 110 NOTREACHED(); | 113 NOTREACHED(); |
| 111 return 0; | 114 return 0; |
| 112 } | 115 } |
| 113 | 116 |
| 114 NOTREACHED(); | 117 NOTREACHED(); |
| 115 return 0; | 118 return 0; |
| 116 } | 119 } |
| 117 | 120 |
| 118 GLenum DataType(BufferFormat format) { | 121 GLenum DataType(BufferFormat format) { |
| 119 switch (format) { | 122 switch (format) { |
| 120 case BufferFormat::R_8: | 123 case BufferFormat::R_8: |
| 121 case BufferFormat::YUV_420_BIPLANAR: | |
| 122 return GL_UNSIGNED_BYTE; | 124 return GL_UNSIGNED_BYTE; |
| 123 case BufferFormat::BGRA_8888: | 125 case BufferFormat::BGRA_8888: |
| 124 return GL_UNSIGNED_INT_8_8_8_8_REV; | 126 return GL_UNSIGNED_INT_8_8_8_8_REV; |
| 125 case BufferFormat::UYVY_422: | 127 case BufferFormat::UYVY_422: |
| 126 return GL_UNSIGNED_SHORT_8_8_APPLE; | 128 return GL_UNSIGNED_SHORT_8_8_APPLE; |
| 127 break; | 129 break; |
| 128 case BufferFormat::ATC: | 130 case BufferFormat::ATC: |
| 129 case BufferFormat::ATCIA: | 131 case BufferFormat::ATCIA: |
| 130 case BufferFormat::DXT1: | 132 case BufferFormat::DXT1: |
| 131 case BufferFormat::DXT5: | 133 case BufferFormat::DXT5: |
| 132 case BufferFormat::ETC1: | 134 case BufferFormat::ETC1: |
| 133 case BufferFormat::RGBA_4444: | 135 case BufferFormat::RGBA_4444: |
| 134 case BufferFormat::RGBA_8888: | 136 case BufferFormat::RGBA_8888: |
| 135 case BufferFormat::RGBX_8888: | 137 case BufferFormat::RGBX_8888: |
| 136 case BufferFormat::BGRX_8888: | 138 case BufferFormat::BGRX_8888: |
| 137 case BufferFormat::YUV_420: | 139 case BufferFormat::YUV_420: |
| 140 case BufferFormat::YUV_420_BIPLANAR: | |
| 138 NOTREACHED(); | 141 NOTREACHED(); |
| 139 return 0; | 142 return 0; |
| 140 } | 143 } |
| 141 | 144 |
| 142 NOTREACHED(); | 145 NOTREACHED(); |
| 143 return 0; | 146 return 0; |
| 144 } | 147 } |
| 145 | 148 |
| 146 } // namespace | 149 } // namespace |
| 147 | 150 |
| 151 class GLImageIOSurface::I420vToRGBA { | |
| 152 public: | |
| 153 bool Initialize(); | |
| 154 bool DrawToTexture(const Size& size, | |
| 155 GLuint yuv_planes[2], | |
| 156 GLuint output_texture, | |
| 157 unsigned target); | |
| 158 void Destroy(); | |
| 159 | |
| 160 private: | |
| 161 static const char kVertexShader[]; | |
| 162 static const char kFragmentShader[]; | |
| 163 GLuint framebuffer_object_ = 0; | |
| 164 GLuint vertex_shader_ = 0; | |
| 165 GLuint fragment_shader_ = 0; | |
| 166 GLuint program_object_ = 0; | |
| 167 GLint y_sampler_location_ = -1; | |
| 168 GLint uv_sampler_location_ = -1; | |
| 169 GLint size_location_ = -1; | |
| 170 GLuint vertex_buffer_ = 0; | |
| 171 }; | |
| 172 | |
| 173 // clang-format off | |
| 174 const char GLImageIOSurface::I420vToRGBA::kVertexShader[] = | |
| 175 STRINGIZE( | |
| 176 attribute vec2 a_position; | |
| 177 uniform vec2 a_size; | |
| 178 varying vec2 v_texCoord; | |
| 179 void main() { | |
| 180 gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0); | |
| 181 v_texCoord = (a_position + vec2(1,1)) * 0.5 * a_size; | |
| 182 } | |
| 183 ); | |
| 184 | |
| 185 const char GLImageIOSurface::I420vToRGBA::kFragmentShader[] = | |
| 186 STRINGIZE( | |
| 187 uniform sampler2DRect a_y_texture; | |
| 188 uniform sampler2DRect a_uv_texture; | |
| 189 varying vec2 v_texCoord; | |
| 190 void main() { | |
| 191 vec3 yuv_adj = vec3(-0.0625, -0.5, -0.5); | |
| 192 mat3 yuv_matrix = mat3(vec3(1.164, 1.164, 1.164), | |
| 193 vec3(0.0, -.391, 2.018), | |
| 194 vec3(1.596, -.813, 0.0)); | |
| 195 vec3 yuv = vec3(texture2DRect(a_y_texture, v_texCoord).r, | |
| 196 texture2DRect(a_uv_texture, v_texCoord * 0.5).rg); | |
| 197 gl_FragColor = vec4( yuv_matrix * (yuv + yuv_adj), 1.0); | |
| 198 } | |
| 199 ); | |
| 200 // clang-format on | |
| 201 | |
| 202 bool GLImageIOSurface::I420vToRGBA::Initialize() { | |
| 203 glGenFramebuffersEXT(1, &framebuffer_object_); | |
| 204 DCHECK(framebuffer_object_); | |
| 205 | |
| 206 glGenBuffersARB(1, &vertex_buffer_); | |
| 207 GLint previous_buffer = 0; | |
| 208 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previous_buffer); | |
| 209 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
| 210 | |
| 211 // clang-format off | |
| 212 GLfloat data[] = { | |
| 213 -1.f, -1.f, | |
| 214 1.f, -1.f, | |
| 215 -1.f, 1.f, | |
| 216 1.f, 1.f}; | |
| 217 // clang-format on | |
| 218 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); | |
| 219 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, 0); | |
| 220 glBindBuffer(GL_ARRAY_BUFFER, previous_buffer); | |
| 221 | |
| 222 vertex_shader_ = GLHelper::LoadShader(GL_VERTEX_SHADER, kVertexShader); | |
| 223 fragment_shader_ = GLHelper::LoadShader(GL_FRAGMENT_SHADER, kFragmentShader); | |
| 224 program_object_ = GLHelper::SetupProgram(vertex_shader_, fragment_shader_); | |
| 225 GLint previous_program = 0; | |
| 226 glGetIntegerv(GL_CURRENT_PROGRAM, &previous_program); | |
| 227 glUseProgram(program_object_); | |
| 228 | |
| 229 size_location_ = glGetUniformLocation(program_object_, "a_size"); | |
| 230 DCHECK_NE(-1, size_location_); | |
| 231 y_sampler_location_ = glGetUniformLocation(program_object_, "a_y_texture"); | |
| 232 DCHECK_NE(-1, y_sampler_location_); | |
| 233 uv_sampler_location_ = glGetUniformLocation(program_object_, "a_uv_texture"); | |
| 234 DCHECK_NE(-1, uv_sampler_location_); | |
| 235 | |
| 236 glUniform1i(y_sampler_location_, 0); | |
| 237 glUniform1i(uv_sampler_location_, 1); | |
| 238 glUseProgram(previous_program); | |
| 239 return true; | |
| 240 } | |
| 241 | |
| 242 bool GLImageIOSurface::I420vToRGBA::DrawToTexture(const Size& size, | |
| 243 GLuint yuv_planes[2], | |
| 244 GLuint output_texture, | |
| 245 unsigned target) { | |
| 246 ScopedFrameBufferBinder fb(framebuffer_object_); | |
| 247 glViewport(0, 0, size.width(), size.height()); | |
| 248 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, | |
| 249 output_texture, 0); | |
| 250 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), | |
| 251 glCheckFramebufferStatusEXT(GL_FRAMEBUFFER)); | |
| 252 | |
| 253 GLint previous_active_texture = 0; | |
| 254 glGetIntegerv(GL_ACTIVE_TEXTURE, &previous_active_texture); | |
| 255 glActiveTexture(GL_TEXTURE0); | |
| 256 GLint previous_texture_0 = 0; | |
| 257 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_0); | |
| 258 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_planes[0]); | |
| 259 | |
| 260 glActiveTexture(GL_TEXTURE1); | |
| 261 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, yuv_planes[1]); | |
| 262 GLint previous_texture_1 = 0; | |
| 263 glGetIntegerv(GL_TEXTURE_BINDING_RECTANGLE_ARB, &previous_texture_1); | |
| 264 | |
| 265 GLint previous_program = 0; | |
| 266 glGetIntegerv(GL_CURRENT_PROGRAM, &previous_program); | |
| 267 glUseProgram(program_object_); | |
| 268 glUniform2f(size_location_, size.width(), size.height()); | |
| 269 | |
| 270 GLint vertex_array_enabled = 0; | |
| 271 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vertex_array_enabled); | |
| 272 glEnableVertexAttribArray(0); | |
| 273 GLint previous_buffer = 0; | |
| 274 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &previous_buffer); | |
| 275 glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | |
| 276 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | |
| 277 | |
| 278 // Detach the service texture from the fbo. | |
| 279 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, 0, 0); | |
| 280 // Restore texture bindings and active texture. | |
| 281 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_1); | |
| 282 glActiveTexture(GL_TEXTURE0); | |
| 283 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, previous_texture_0); | |
| 284 glActiveTexture(previous_active_texture); | |
| 285 // Restore program. | |
| 286 glUseProgram(previous_program); | |
| 287 // Restore bound vbuff. | |
| 288 glBindBuffer(GL_ARRAY_BUFFER_BINDING, previous_buffer); | |
| 289 if (!vertex_array_enabled) | |
| 290 glDisableVertexAttribArray(0); | |
| 291 | |
| 292 return true; | |
| 293 } | |
| 294 | |
| 295 void GLImageIOSurface::I420vToRGBA::Destroy() { | |
| 296 glDeleteProgram(program_object_); | |
| 297 glDeleteShader(vertex_shader_); | |
| 298 glDeleteShader(fragment_shader_); | |
| 299 glDeleteBuffersARB(1, &vertex_buffer_); | |
| 300 glDeleteFramebuffersEXT(1, &framebuffer_object_); | |
| 301 } | |
| 302 | |
| 148 GLImageIOSurface::GLImageIOSurface(const Size& size, unsigned internalformat) | 303 GLImageIOSurface::GLImageIOSurface(const Size& size, unsigned internalformat) |
| 149 : size_(size), | 304 : size_(size), |
| 150 internalformat_(internalformat), | 305 internalformat_(internalformat), |
| 151 format_(BufferFormat::RGBA_8888) {} | 306 format_(BufferFormat::RGBA_8888) {} |
| 152 | 307 |
| 153 GLImageIOSurface::~GLImageIOSurface() { | 308 GLImageIOSurface::~GLImageIOSurface() { |
| 154 DCHECK(thread_checker_.CalledOnValidThread()); | 309 DCHECK(thread_checker_.CalledOnValidThread()); |
| 155 DCHECK(!io_surface_); | 310 DCHECK(!io_surface_); |
| 156 } | 311 } |
| 157 | 312 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 172 } | 327 } |
| 173 | 328 |
| 174 format_ = format; | 329 format_ = format; |
| 175 io_surface_.reset(io_surface, base::scoped_policy::RETAIN); | 330 io_surface_.reset(io_surface, base::scoped_policy::RETAIN); |
| 176 io_surface_id_ = io_surface_id; | 331 io_surface_id_ = io_surface_id; |
| 177 return true; | 332 return true; |
| 178 } | 333 } |
| 179 | 334 |
| 180 void GLImageIOSurface::Destroy(bool have_context) { | 335 void GLImageIOSurface::Destroy(bool have_context) { |
| 181 DCHECK(thread_checker_.CalledOnValidThread()); | 336 DCHECK(thread_checker_.CalledOnValidThread()); |
| 337 if (have_context && i420v_to_RGBA_) { | |
| 338 i420v_to_RGBA_->Destroy(); | |
|
reveman
2015/10/27 19:31:54
without looking at what this does, it's confusing
Daniele Castagna
2015/10/29 20:09:04
Removed the class as suggested in the comment belo
| |
| 339 } | |
| 182 io_surface_.reset(); | 340 io_surface_.reset(); |
| 183 } | 341 } |
| 184 | 342 |
| 185 Size GLImageIOSurface::GetSize() { | 343 Size GLImageIOSurface::GetSize() { |
| 186 return size_; | 344 return size_; |
| 187 } | 345 } |
| 188 | 346 |
| 189 unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_; } | 347 unsigned GLImageIOSurface::GetInternalFormat() { return internalformat_; } |
| 190 | 348 |
| 191 bool GLImageIOSurface::BindTexImage(unsigned target) { | 349 bool GLImageIOSurface::BindTexImage(unsigned target) { |
| 192 DCHECK(thread_checker_.CalledOnValidThread()); | 350 DCHECK(thread_checker_.CalledOnValidThread()); |
| 351 | |
| 352 if (format_ == BufferFormat::YUV_420_BIPLANAR) | |
| 353 return false; | |
| 354 | |
| 193 if (target != GL_TEXTURE_RECTANGLE_ARB) { | 355 if (target != GL_TEXTURE_RECTANGLE_ARB) { |
| 194 // This might be supported in the future. For now, perform strict | 356 // This might be supported in the future. For now, perform strict |
| 195 // validation so we know what's going on. | 357 // validation so we know what's going on. |
| 196 LOG(ERROR) << "IOSurface requires TEXTURE_RECTANGLE_ARB target"; | 358 LOG(ERROR) << "IOSurface requires TEXTURE_RECTANGLE_ARB target"; |
| 197 return false; | 359 return false; |
| 198 } | 360 } |
| 199 | 361 |
| 200 CGLContextObj cgl_context = | 362 CGLContextObj cgl_context = |
| 201 static_cast<CGLContextObj>(GLContext::GetCurrent()->GetHandle()); | 363 static_cast<CGLContextObj>(GLContext::GetCurrent()->GetHandle()); |
| 202 | 364 |
| 203 DCHECK(io_surface_); | 365 DCHECK(io_surface_); |
| 204 CGLError cgl_error = | 366 CGLError cgl_error = |
| 205 CGLTexImageIOSurface2D(cgl_context, target, TextureFormat(format_), | 367 CGLTexImageIOSurface2D(cgl_context, target, TextureFormat(format_), |
| 206 size_.width(), size_.height(), DataFormat(format_), | 368 size_.width(), size_.height(), DataFormat(format_), |
| 207 DataType(format_), io_surface_.get(), 0); | 369 DataType(format_), io_surface_.get(), 0); |
| 208 if (cgl_error != kCGLNoError) { | 370 if (cgl_error != kCGLNoError) { |
| 209 LOG(ERROR) << "Error in CGLTexImageIOSurface2D"; | 371 LOG(ERROR) << "Error in CGLTexImageIOSurface2D"; |
| 210 return false; | 372 return false; |
| 211 } | 373 } |
| 212 | 374 |
| 213 return true; | 375 return true; |
| 214 } | 376 } |
| 215 | 377 |
| 216 bool GLImageIOSurface::CopyTexImage(unsigned target) { | 378 bool GLImageIOSurface::CopyTexImage(unsigned target) { |
| 217 return false; | 379 DCHECK(thread_checker_.CalledOnValidThread()); |
| 380 DCHECK(io_surface_); | |
| 381 if (format_ != BufferFormat::YUV_420_BIPLANAR) | |
| 382 return false; | |
| 383 | |
| 384 if (!i420v_to_RGBA_) { | |
|
reveman
2015/10/27 19:31:54
I would prefer to see all this state just part of
Daniele Castagna
2015/10/29 20:09:04
Done.
| |
| 385 i420v_to_RGBA_.reset(new I420vToRGBA()); | |
| 386 if (!i420v_to_RGBA_->Initialize()) { | |
| 387 LOG(ERROR) | |
| 388 << "Can't initialize GL structures for 420v to RGBA conversion"; | |
| 389 return false; | |
| 390 } | |
| 391 } | |
| 392 | |
| 393 DCHECK(target == GL_TEXTURE_2D); | |
|
reveman
2015/10/27 19:31:54
What prevents a client from using a different targ
Daniele Castagna
2015/10/29 20:09:04
Changed that to LOG(ERROR) ... + return false.
| |
| 394 CGLContextObj cgl_context = | |
| 395 static_cast<CGLContextObj>(GLContext::GetCurrent()->GetHandle()); | |
| 396 | |
| 397 GLuint yuv_textures[2]; | |
| 398 glGenTextures(2, yuv_textures); | |
| 399 DCHECK(yuv_textures[0] && yuv_textures[1]); | |
| 400 | |
| 401 GLint service_texture = 0; | |
| 402 glGetIntegerv(GL_TEXTURE_BINDING_2D, &service_texture); | |
| 403 DCHECK(service_texture); | |
| 404 | |
| 405 CGLError cgl_error = kCGLNoError; | |
| 406 { | |
| 407 ScopedTextureBinder b(GL_TEXTURE_RECTANGLE_ARB, yuv_textures[0]); | |
| 408 cgl_error = CGLTexImageIOSurface2D( | |
| 409 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RED, size_.width(), | |
| 410 size_.height(), GL_RED, GL_UNSIGNED_BYTE, io_surface_.get(), 0); | |
| 411 } | |
| 412 if (cgl_error != kCGLNoError) { | |
| 413 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the Y plane. " | |
| 414 << cgl_error; | |
| 415 glDeleteTextures(2, yuv_textures); | |
| 416 return false; | |
| 417 } | |
| 418 | |
| 419 { | |
| 420 ScopedTextureBinder b(GL_TEXTURE_RECTANGLE_ARB, yuv_textures[1]); | |
| 421 cgl_error = CGLTexImageIOSurface2D( | |
| 422 cgl_context, GL_TEXTURE_RECTANGLE_ARB, GL_RG, size_.width() / 2, | |
| 423 size_.height() / 2, GL_RG, GL_UNSIGNED_BYTE, io_surface_.get(), 1); | |
| 424 } | |
| 425 if (cgl_error != kCGLNoError) { | |
| 426 LOG(ERROR) << "Error in CGLTexImageIOSurface2D for the UV plane. " | |
| 427 << cgl_error; | |
| 428 glDeleteTextures(2, yuv_textures); | |
| 429 return false; | |
| 430 } | |
| 431 | |
| 432 if (!i420v_to_RGBA_->DrawToTexture(size_, yuv_textures, service_texture, | |
| 433 target)) { | |
| 434 LOG(ERROR) << "Can't draw 420v IOSurface to RGBA texture."; | |
| 435 glDeleteTextures(2, yuv_textures); | |
| 436 return false; | |
| 437 } | |
| 438 | |
| 439 return true; | |
| 218 } | 440 } |
| 219 | 441 |
| 220 bool GLImageIOSurface::CopyTexSubImage(unsigned target, | 442 bool GLImageIOSurface::CopyTexSubImage(unsigned target, |
| 221 const Point& offset, | 443 const Point& offset, |
| 222 const Rect& rect) { | 444 const Rect& rect) { |
| 223 return false; | 445 return false; |
| 224 } | 446 } |
| 225 | 447 |
| 226 bool GLImageIOSurface::ScheduleOverlayPlane(AcceleratedWidget widget, | 448 bool GLImageIOSurface::ScheduleOverlayPlane(AcceleratedWidget widget, |
| 227 int z_order, | 449 int z_order, |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 258 // static | 480 // static |
| 259 void GLImageIOSurface::SetLayerForWidget(AcceleratedWidget widget, | 481 void GLImageIOSurface::SetLayerForWidget(AcceleratedWidget widget, |
| 260 CALayer* layer) { | 482 CALayer* layer) { |
| 261 if (layer) | 483 if (layer) |
| 262 g_widget_to_layer_map.Pointer()->insert(std::make_pair(widget, layer)); | 484 g_widget_to_layer_map.Pointer()->insert(std::make_pair(widget, layer)); |
| 263 else | 485 else |
| 264 g_widget_to_layer_map.Pointer()->erase(widget); | 486 g_widget_to_layer_map.Pointer()->erase(widget); |
| 265 } | 487 } |
| 266 | 488 |
| 267 } // namespace gfx | 489 } // namespace gfx |
| OLD | NEW |