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 |