OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/browser/renderer_host/compositing_iosurface_transformer_mac.h" | 5 #include "content/browser/renderer_host/compositing_iosurface_transformer_mac.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h" | 12 #include "content/browser/renderer_host/compositing_iosurface_shader_programs_ma c.h" |
13 #include "ui/gfx/rect.h" | 13 #include "ui/gfx/rect.h" |
14 #include "ui/gfx/size.h" | 14 #include "ui/gfx/size.h" |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 // Simple auto-delete scoping support for an owned Framebuffer object. | 20 const GLenum kColorAttachments[] = { |
21 class ScopedFramebuffer { | 21 GL_COLOR_ATTACHMENT0_EXT, |
22 public: | 22 GL_COLOR_ATTACHMENT1_EXT |
23 ScopedFramebuffer() { | |
24 glGenFramebuffersEXT(1, &name_); | |
25 } | |
26 | |
27 ~ScopedFramebuffer() { | |
28 if (name_ != 0u) | |
29 glDeleteFramebuffersEXT(1, &name_); | |
30 } | |
31 | |
32 bool is_valid() const { return name_ != 0u; } | |
33 GLuint name() const { return name_; } | |
34 | |
35 private: | |
36 GLuint name_; | |
37 | |
38 DISALLOW_COPY_AND_ASSIGN(ScopedFramebuffer); | |
39 }; | 23 }; |
40 | 24 |
41 // Simple auto-delete scoping support for an owned texture object. | |
42 class ScopedTexture { | |
43 public: | |
44 ScopedTexture() : name_(0u) {} | |
45 ScopedTexture(GLenum target, const gfx::Size& size); | |
46 | |
47 ~ScopedTexture() { | |
48 if (name_ != 0u) | |
49 glDeleteTextures(1, &name_); | |
50 } | |
51 | |
52 bool is_valid() const { return name_ != 0u; } | |
53 GLuint name() const { return name_; } | |
54 | |
55 void Reset(GLuint texture) { | |
56 if (name_ != 0u) | |
57 glDeleteTextures(1, &name_); | |
58 name_ = texture; | |
59 } | |
60 | |
61 GLuint Release() { | |
62 GLuint ret = name_; | |
63 name_ = 0u; | |
64 return ret; | |
65 } | |
66 | |
67 private: | |
68 GLuint name_; | |
69 | |
70 DISALLOW_COPY_AND_ASSIGN(ScopedTexture); | |
71 }; | |
72 | |
73 ScopedTexture::ScopedTexture(GLenum target, const gfx::Size& size) { | |
74 glGenTextures(1, &name_); | |
75 glBindTexture(target, name_); | |
76 glTexImage2D(target, 0, GL_RGBA, size.width(), size.height(), 0, GL_BGRA, | |
77 GL_UNSIGNED_INT_8_8_8_8_REV, NULL); | |
78 DCHECK(glGetError() == GL_NO_ERROR); | |
79 glBindTexture(target, 0u); | |
80 } | |
81 | |
82 // Set viewport and model/projection matrices for drawing to a framebuffer of | 25 // Set viewport and model/projection matrices for drawing to a framebuffer of |
83 // size dst_size, with coordinates starting at (0, 0). | 26 // size dst_size, with coordinates starting at (0, 0). |
84 void SetTransformationsForOffScreenRendering(const gfx::Size& dst_size) { | 27 void SetTransformationsForOffScreenRendering(const gfx::Size& dst_size) { |
85 glViewport(0, 0, dst_size.width(), dst_size.height()); | 28 glViewport(0, 0, dst_size.width(), dst_size.height()); |
86 glMatrixMode(GL_PROJECTION); | 29 glMatrixMode(GL_PROJECTION); |
87 glLoadIdentity(); | 30 glLoadIdentity(); |
88 glOrtho(0, dst_size.width(), 0, dst_size.height(), -1, 1); | 31 glOrtho(0, dst_size.width(), 0, dst_size.height(), -1, 1); |
89 glMatrixMode(GL_MODELVIEW); | 32 glMatrixMode(GL_MODELVIEW); |
90 glLoadIdentity(); | 33 glLoadIdentity(); |
91 } | 34 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 glDisableClientState(GL_TEXTURE_COORD_ARRAY); | 82 glDisableClientState(GL_TEXTURE_COORD_ARRAY); |
140 } | 83 } |
141 | 84 |
142 } // namespace | 85 } // namespace |
143 | 86 |
144 CompositingIOSurfaceTransformer::CompositingIOSurfaceTransformer( | 87 CompositingIOSurfaceTransformer::CompositingIOSurfaceTransformer( |
145 GLenum texture_target, bool src_texture_needs_y_flip, | 88 GLenum texture_target, bool src_texture_needs_y_flip, |
146 CompositingIOSurfaceShaderPrograms* shader_program_cache) | 89 CompositingIOSurfaceShaderPrograms* shader_program_cache) |
147 : texture_target_(texture_target), | 90 : texture_target_(texture_target), |
148 src_texture_needs_y_flip_(src_texture_needs_y_flip), | 91 src_texture_needs_y_flip_(src_texture_needs_y_flip), |
149 shader_program_cache_(shader_program_cache) { | 92 shader_program_cache_(shader_program_cache), |
93 frame_buffer_(0) { | |
150 DCHECK(texture_target_ == GL_TEXTURE_RECTANGLE_ARB) | 94 DCHECK(texture_target_ == GL_TEXTURE_RECTANGLE_ARB) |
151 << "Fragment shaders currently only support RECTANGLE textures."; | 95 << "Fragment shaders currently only support RECTANGLE textures."; |
152 DCHECK(shader_program_cache_); | 96 DCHECK(shader_program_cache_); |
153 | 97 |
98 memset(textures_, 0, sizeof(textures_)); | |
99 | |
154 // The RGB-to-YV12 transform requires that the driver/hardware supports | 100 // The RGB-to-YV12 transform requires that the driver/hardware supports |
155 // multiple draw buffers. | 101 // multiple draw buffers. |
156 GLint max_draw_buffers = 1; | 102 GLint max_draw_buffers = 1; |
157 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); | 103 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers); |
158 system_supports_multiple_draw_buffers_ = (max_draw_buffers >= 2); | 104 system_supports_multiple_draw_buffers_ = (max_draw_buffers >= 2); |
159 } | 105 } |
160 | 106 |
161 CompositingIOSurfaceTransformer::~CompositingIOSurfaceTransformer() { | 107 CompositingIOSurfaceTransformer::~CompositingIOSurfaceTransformer() { |
108 for (int i = 0; i < NUM_CACHED_TEXTURES; ++i) | |
109 DCHECK_EQ(textures_[i], 0u) << "Failed to call ReleaseCachedGLObjects()."; | |
110 DCHECK_EQ(frame_buffer_, 0u) << "Failed to call ReleaseCachedGLObjects()."; | |
111 } | |
112 | |
113 void CompositingIOSurfaceTransformer::ReleaseCachedGLObjects() { | |
114 for (int i = 0; i < NUM_CACHED_TEXTURES; ++i) { | |
115 if (textures_[i]) { | |
116 glDeleteTextures(1, &textures_[i]); | |
117 textures_[i] = 0; | |
118 texture_sizes_[i] = gfx::Size(); | |
119 } | |
120 } | |
121 if (frame_buffer_) { | |
122 glDeleteFramebuffersEXT(1, &frame_buffer_); | |
123 frame_buffer_ = 0; | |
124 } | |
162 } | 125 } |
163 | 126 |
164 bool CompositingIOSurfaceTransformer::ResizeBilinear( | 127 bool CompositingIOSurfaceTransformer::ResizeBilinear( |
165 GLuint src_texture, const gfx::Rect& src_subrect, const gfx::Size& dst_size, | 128 GLuint src_texture, const gfx::Rect& src_subrect, const gfx::Size& dst_size, |
166 GLuint* texture) { | 129 GLuint* texture) { |
167 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) | 130 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) |
168 return false; | 131 return false; |
169 | 132 |
170 glActiveTexture(GL_TEXTURE0); | 133 glActiveTexture(GL_TEXTURE0); |
171 glDisable(GL_DEPTH_TEST); | 134 glDisable(GL_DEPTH_TEST); |
172 glDisable(GL_BLEND); | 135 glDisable(GL_BLEND); |
173 | 136 |
174 ScopedTexture dst_texture(texture_target_, dst_size); | 137 PrepareTexture(RGBA_OUTPUT, dst_size); |
175 if (!dst_texture.is_valid()) | 138 PrepareFramebuffer(); |
176 return false; | 139 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_); |
177 | |
178 ScopedFramebuffer temp_frame_buffer; | |
179 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, temp_frame_buffer.name()); | |
180 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 140 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
181 texture_target_, dst_texture.name(), 0); | 141 texture_target_, textures_[RGBA_OUTPUT], 0); |
182 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | 142 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == |
183 GL_FRAMEBUFFER_COMPLETE_EXT); | 143 GL_FRAMEBUFFER_COMPLETE_EXT); |
144 glDrawBuffers(1, kColorAttachments); | |
ncarter (slow)
2013/04/15 23:38:19
This seems unnecessary.
miu
2013/04/16 03:51:22
It probably is. I was just playing it safe. Done
| |
184 | 145 |
185 glBindTexture(texture_target_, src_texture); | 146 glBindTexture(texture_target_, src_texture); |
186 SetTextureParameters( | 147 SetTextureParameters( |
187 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, | 148 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, |
188 GL_CLAMP_TO_EDGE); | 149 GL_CLAMP_TO_EDGE); |
189 | 150 |
190 const bool prepared = shader_program_cache_->UseBlitProgram(); | 151 const bool prepared = shader_program_cache_->UseBlitProgram(); |
191 DCHECK(prepared); | 152 DCHECK(prepared); |
192 SetTransformationsForOffScreenRendering(dst_size); | 153 SetTransformationsForOffScreenRendering(dst_size); |
193 DrawQuad(src_subrect.x(), src_subrect.y(), | 154 DrawQuad(src_subrect.x(), src_subrect.y(), |
194 src_subrect.width(), src_subrect.height(), | 155 src_subrect.width(), src_subrect.height(), |
195 src_texture_needs_y_flip_, | 156 src_texture_needs_y_flip_, |
196 dst_size.width(), dst_size.height()); | 157 dst_size.width(), dst_size.height()); |
197 glUseProgram(0); | 158 glUseProgram(0); |
198 glBindTexture(texture_target_, 0u); | |
199 | 159 |
200 *texture = dst_texture.Release(); | 160 glBindTexture(texture_target_, 0); |
161 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); | |
162 | |
163 *texture = textures_[RGBA_OUTPUT]; | |
201 return true; | 164 return true; |
202 } | 165 } |
203 | 166 |
204 bool CompositingIOSurfaceTransformer::TransformRGBToYV12( | 167 bool CompositingIOSurfaceTransformer::TransformRGBToYV12( |
205 GLuint src_texture, | 168 GLuint src_texture, |
206 const gfx::Rect& src_subrect, | 169 const gfx::Rect& src_subrect, |
207 const gfx::Size& dst_size, | 170 const gfx::Size& dst_size, |
208 GLuint* texture_y, | 171 GLuint* texture_y, |
209 GLuint* texture_u, | 172 GLuint* texture_u, |
210 GLuint* texture_v, | 173 GLuint* texture_v, |
211 gfx::Size* packed_y_size, | 174 gfx::Size* packed_y_size, |
212 gfx::Size* packed_uv_size) { | 175 gfx::Size* packed_uv_size) { |
213 if (!system_supports_multiple_draw_buffers_) | 176 if (!system_supports_multiple_draw_buffers_) |
214 return false; | 177 return false; |
215 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) | 178 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) |
216 return false; | 179 return false; |
217 | 180 |
218 TRACE_EVENT0("gpu", "TransformRGBToYV12"); | 181 TRACE_EVENT0("gpu", "TransformRGBToYV12"); |
219 | 182 |
220 glActiveTexture(GL_TEXTURE0); | 183 glActiveTexture(GL_TEXTURE0); |
221 glDisable(GL_DEPTH_TEST); | 184 glDisable(GL_DEPTH_TEST); |
222 glDisable(GL_BLEND); | 185 glDisable(GL_BLEND); |
223 | 186 |
224 // Allocate output textures for each plane, and the temporary one for the UUVV | 187 // Resize output textures for each plane, and for the intermediate UUVV one |
225 // that becomes an input into pass #2. |packed_y_size| is the size of the Y | 188 // that becomes an input into pass #2. |packed_y_size| is the size of the Y |
226 // output texture, where its width is 1/4 the number of Y pixels because 4 Y | 189 // output texture, where its width is 1/4 the number of Y pixels because 4 Y |
227 // pixels are packed into a single quad. |packed_uv_size| is half the size of | 190 // pixels are packed into a single quad. |packed_uv_size| is half the size of |
228 // Y in both dimensions, rounded up. | 191 // Y in both dimensions, rounded up. |
229 *packed_y_size = gfx::Size((dst_size.width() + 3) / 4, dst_size.height()); | 192 *packed_y_size = gfx::Size((dst_size.width() + 3) / 4, dst_size.height()); |
230 *packed_uv_size = gfx::Size((packed_y_size->width() + 1) / 2, | 193 *packed_uv_size = gfx::Size((packed_y_size->width() + 1) / 2, |
231 (packed_y_size->height() + 1) / 2); | 194 (packed_y_size->height() + 1) / 2); |
232 ScopedTexture temp_texture_y(texture_target_, *packed_y_size); | 195 PrepareTexture(Y_PLANE_OUTPUT, *packed_y_size); |
233 if (!temp_texture_y.is_valid()) | 196 PrepareTexture(UUVV_INTERMEDIATE, *packed_y_size); |
234 return false; | 197 PrepareTexture(U_PLANE_OUTPUT, *packed_uv_size); |
235 ScopedTexture temp_texture_u(texture_target_, *packed_uv_size); | 198 PrepareTexture(V_PLANE_OUTPUT, *packed_uv_size); |
236 if (!temp_texture_u.is_valid()) | |
237 return false; | |
238 ScopedTexture temp_texture_v(texture_target_, *packed_uv_size); | |
239 if (!temp_texture_v.is_valid()) | |
240 return false; | |
241 | |
242 // Create a temporary texture for the UUVV that becomes an input into pass #2. | |
243 ScopedTexture temp_texture_uuvv(texture_target_, *packed_y_size); | |
244 if (!temp_texture_uuvv.is_valid()) | |
245 return false; | |
246 | |
247 // Create a temporary FBO for writing to the textures off-screen. | |
248 ScopedFramebuffer temp_frame_buffer; | |
249 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, temp_frame_buffer.name()); | |
250 | 199 |
251 ///////////////////////////////////////// | 200 ///////////////////////////////////////// |
252 // Pass 1: RGB --(scaled)--> YYYY + UUVV | 201 // Pass 1: RGB --(scaled)--> YYYY + UUVV |
202 PrepareFramebuffer(); | |
203 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_); | |
253 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 204 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
254 texture_target_, temp_texture_y.name(), 0); | 205 texture_target_, textures_[Y_PLANE_OUTPUT], 0); |
255 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, | 206 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, |
256 texture_target_, temp_texture_uuvv.name(), 0); | 207 texture_target_, textures_[UUVV_INTERMEDIATE], 0); |
257 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | 208 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == |
258 GL_FRAMEBUFFER_COMPLETE_EXT); | 209 GL_FRAMEBUFFER_COMPLETE_EXT); |
259 static const GLenum kAttachments[] = | 210 glDrawBuffers(2, kColorAttachments); |
260 { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; | |
261 glDrawBuffers(2, kAttachments); | |
262 | 211 |
263 // Read from |src_texture|. Enable bilinear filtering only if scaling is | 212 // Read from |src_texture|. Enable bilinear filtering only if scaling is |
264 // required. The filtering will take place entirely in the first pass. | 213 // required. The filtering will take place entirely in the first pass. |
265 glBindTexture(texture_target_, src_texture); | 214 glBindTexture(texture_target_, src_texture); |
266 SetTextureParameters( | 215 SetTextureParameters( |
267 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, | 216 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, |
268 GL_CLAMP_TO_EDGE); | 217 GL_CLAMP_TO_EDGE); |
269 | 218 |
270 // Use the first-pass shader program and draw the scene. | 219 // Use the first-pass shader program and draw the scene. |
271 const bool prepared_pass_1 = shader_program_cache_->UseRGBToYV12Program( | 220 const bool prepared_pass_1 = shader_program_cache_->UseRGBToYV12Program( |
272 1, | 221 1, |
273 static_cast<float>(src_subrect.width()) / dst_size.width()); | 222 static_cast<float>(src_subrect.width()) / dst_size.width()); |
274 DCHECK(prepared_pass_1); | 223 DCHECK(prepared_pass_1); |
275 SetTransformationsForOffScreenRendering(*packed_y_size); | 224 SetTransformationsForOffScreenRendering(*packed_y_size); |
276 DrawQuad(src_subrect.x(), src_subrect.y(), | 225 DrawQuad(src_subrect.x(), src_subrect.y(), |
277 ((packed_y_size->width() * 4.0f) / dst_size.width()) * | 226 ((packed_y_size->width() * 4.0f) / dst_size.width()) * |
278 src_subrect.width(), | 227 src_subrect.width(), |
279 src_subrect.height(), | 228 src_subrect.height(), |
280 src_texture_needs_y_flip_, | 229 src_texture_needs_y_flip_, |
281 packed_y_size->width(), packed_y_size->height()); | 230 packed_y_size->width(), packed_y_size->height()); |
282 | 231 |
283 ///////////////////////////////////////// | 232 ///////////////////////////////////////// |
284 // Pass 2: UUVV -> UUUU + VVVV | 233 // Pass 2: UUVV -> UUUU + VVVV |
285 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 234 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
286 texture_target_, temp_texture_u.name(), 0); | 235 texture_target_, textures_[U_PLANE_OUTPUT], 0); |
287 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, | 236 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, |
288 texture_target_, temp_texture_v.name(), 0); | 237 texture_target_, textures_[V_PLANE_OUTPUT], 0); |
289 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | 238 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == |
290 GL_FRAMEBUFFER_COMPLETE_EXT); | 239 GL_FRAMEBUFFER_COMPLETE_EXT); |
291 | 240 |
292 // Read from texture_uuvv. The second pass uses bilinear minification to | 241 // Read from the intermediate UUVV texture. The second pass uses bilinear |
293 // achieve vertical scaling, so enable it always. | 242 // minification to achieve vertical scaling, so enable it always. |
294 glBindTexture(texture_target_, temp_texture_uuvv.name()); | 243 glBindTexture(texture_target_, textures_[UUVV_INTERMEDIATE]); |
295 SetTextureParameters(texture_target_, GL_LINEAR, GL_CLAMP_TO_EDGE); | 244 SetTextureParameters(texture_target_, GL_LINEAR, GL_CLAMP_TO_EDGE); |
296 | 245 |
297 // Use the second-pass shader program and draw the scene. | 246 // Use the second-pass shader program and draw the scene. |
298 const bool prepared_pass_2 = | 247 const bool prepared_pass_2 = |
299 shader_program_cache_->UseRGBToYV12Program(2, 1.0f); | 248 shader_program_cache_->UseRGBToYV12Program(2, 1.0f); |
300 DCHECK(prepared_pass_2); | 249 DCHECK(prepared_pass_2); |
301 SetTransformationsForOffScreenRendering(*packed_uv_size); | 250 SetTransformationsForOffScreenRendering(*packed_uv_size); |
302 DrawQuad(0.0f, 0.0f, | 251 DrawQuad(0.0f, 0.0f, |
303 packed_uv_size->width() * 2.0f, | 252 packed_uv_size->width() * 2.0f, |
304 packed_uv_size->height() * 2.0f, | 253 packed_uv_size->height() * 2.0f, |
305 false, | 254 false, |
306 packed_uv_size->width(), packed_uv_size->height()); | 255 packed_uv_size->width(), packed_uv_size->height()); |
307 glUseProgram(0); | 256 glUseProgram(0); |
308 glBindTexture(texture_target_, 0); | |
309 | 257 |
310 // Before leaving, put back to drawing to a single rendering output. | 258 // Before leaving, put back to drawing to a single rendering output. |
311 glDrawBuffers(1, kAttachments); | 259 glDrawBuffers(1, kColorAttachments); |
312 | 260 |
313 *texture_y = temp_texture_y.Release(); | 261 glBindTexture(texture_target_, 0); |
314 *texture_u = temp_texture_u.Release(); | 262 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
315 *texture_v = temp_texture_v.Release(); | 263 |
264 *texture_y = textures_[Y_PLANE_OUTPUT]; | |
265 *texture_u = textures_[U_PLANE_OUTPUT]; | |
266 *texture_v = textures_[V_PLANE_OUTPUT]; | |
316 return true; | 267 return true; |
317 } | 268 } |
318 | 269 |
270 void CompositingIOSurfaceTransformer::PrepareTexture( | |
271 CachedTexture which, const gfx::Size& size) { | |
272 DCHECK_GE(which, 0); | |
273 DCHECK_LT(which, NUM_CACHED_TEXTURES); | |
274 DCHECK(!size.IsEmpty()); | |
275 | |
276 if (!textures_[which]) { | |
277 glGenTextures(1, &textures_[which]); | |
278 DCHECK_NE(textures_[which], 0u); | |
279 texture_sizes_[which] = gfx::Size(); | |
280 } | |
281 | |
282 // Re-allocate the texture if its size has changed since last use. | |
283 if (texture_sizes_[which] != size) { | |
ncarter (slow)
2013/04/15 23:38:19
Might be worth TRACE_EVENTING this since it should
miu
2013/04/16 03:51:22
Done. Good call.
| |
284 glBindTexture(texture_target_, textures_[which]); | |
285 glTexImage2D(texture_target_, 0, GL_RGBA, size.width(), size.height(), 0, | |
286 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); | |
287 DCHECK(glGetError() == GL_NO_ERROR); | |
ncarter (slow)
2013/04/15 23:38:19
Why DCHECK glGetError() here specifically (is this
miu
2013/04/16 03:51:22
Done. Yep. Leftover debugging cruft. I had a pr
| |
288 texture_sizes_[which] = size; | |
289 } | |
290 } | |
291 | |
292 void CompositingIOSurfaceTransformer::PrepareFramebuffer() { | |
293 if (!frame_buffer_) { | |
294 glGenFramebuffersEXT(1, &frame_buffer_); | |
295 DCHECK_NE(frame_buffer_, 0u); | |
296 } | |
297 } | |
298 | |
319 } // namespace content | 299 } // namespace content |
OLD | NEW |