| 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); |
| 184 | 144 |
| 185 glBindTexture(texture_target_, src_texture); | 145 glBindTexture(texture_target_, src_texture); |
| 186 SetTextureParameters( | 146 SetTextureParameters( |
| 187 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, | 147 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, |
| 188 GL_CLAMP_TO_EDGE); | 148 GL_CLAMP_TO_EDGE); |
| 189 | 149 |
| 190 const bool prepared = shader_program_cache_->UseBlitProgram(); | 150 const bool prepared = shader_program_cache_->UseBlitProgram(); |
| 191 DCHECK(prepared); | 151 DCHECK(prepared); |
| 192 SetTransformationsForOffScreenRendering(dst_size); | 152 SetTransformationsForOffScreenRendering(dst_size); |
| 193 DrawQuad(src_subrect.x(), src_subrect.y(), | 153 DrawQuad(src_subrect.x(), src_subrect.y(), |
| 194 src_subrect.width(), src_subrect.height(), | 154 src_subrect.width(), src_subrect.height(), |
| 195 src_texture_needs_y_flip_, | 155 src_texture_needs_y_flip_, |
| 196 dst_size.width(), dst_size.height()); | 156 dst_size.width(), dst_size.height()); |
| 197 glUseProgram(0); | 157 glUseProgram(0); |
| 198 glBindTexture(texture_target_, 0u); | |
| 199 | 158 |
| 200 *texture = dst_texture.Release(); | 159 glBindTexture(texture_target_, 0); |
| 160 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
| 161 |
| 162 *texture = textures_[RGBA_OUTPUT]; |
| 201 return true; | 163 return true; |
| 202 } | 164 } |
| 203 | 165 |
| 204 bool CompositingIOSurfaceTransformer::TransformRGBToYV12( | 166 bool CompositingIOSurfaceTransformer::TransformRGBToYV12( |
| 205 GLuint src_texture, | 167 GLuint src_texture, |
| 206 const gfx::Rect& src_subrect, | 168 const gfx::Rect& src_subrect, |
| 207 const gfx::Size& dst_size, | 169 const gfx::Size& dst_size, |
| 208 GLuint* texture_y, | 170 GLuint* texture_y, |
| 209 GLuint* texture_u, | 171 GLuint* texture_u, |
| 210 GLuint* texture_v, | 172 GLuint* texture_v, |
| 211 gfx::Size* packed_y_size, | 173 gfx::Size* packed_y_size, |
| 212 gfx::Size* packed_uv_size) { | 174 gfx::Size* packed_uv_size) { |
| 213 if (!system_supports_multiple_draw_buffers_) | 175 if (!system_supports_multiple_draw_buffers_) |
| 214 return false; | 176 return false; |
| 215 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) | 177 if (src_subrect.IsEmpty() || dst_size.IsEmpty()) |
| 216 return false; | 178 return false; |
| 217 | 179 |
| 218 TRACE_EVENT0("gpu", "TransformRGBToYV12"); | 180 TRACE_EVENT0("gpu", "TransformRGBToYV12"); |
| 219 | 181 |
| 220 glActiveTexture(GL_TEXTURE0); | 182 glActiveTexture(GL_TEXTURE0); |
| 221 glDisable(GL_DEPTH_TEST); | 183 glDisable(GL_DEPTH_TEST); |
| 222 glDisable(GL_BLEND); | 184 glDisable(GL_BLEND); |
| 223 | 185 |
| 224 // Allocate output textures for each plane, and the temporary one for the UUVV | 186 // 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 | 187 // 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 | 188 // 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 | 189 // pixels are packed into a single quad. |packed_uv_size| is half the size of |
| 228 // Y in both dimensions, rounded up. | 190 // Y in both dimensions, rounded up. |
| 229 *packed_y_size = gfx::Size((dst_size.width() + 3) / 4, dst_size.height()); | 191 *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, | 192 *packed_uv_size = gfx::Size((packed_y_size->width() + 1) / 2, |
| 231 (packed_y_size->height() + 1) / 2); | 193 (packed_y_size->height() + 1) / 2); |
| 232 ScopedTexture temp_texture_y(texture_target_, *packed_y_size); | 194 PrepareTexture(Y_PLANE_OUTPUT, *packed_y_size); |
| 233 if (!temp_texture_y.is_valid()) | 195 PrepareTexture(UUVV_INTERMEDIATE, *packed_y_size); |
| 234 return false; | 196 PrepareTexture(U_PLANE_OUTPUT, *packed_uv_size); |
| 235 ScopedTexture temp_texture_u(texture_target_, *packed_uv_size); | 197 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 | 198 |
| 251 ///////////////////////////////////////// | 199 ///////////////////////////////////////// |
| 252 // Pass 1: RGB --(scaled)--> YYYY + UUVV | 200 // Pass 1: RGB --(scaled)--> YYYY + UUVV |
| 201 PrepareFramebuffer(); |
| 202 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer_); |
| 253 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 203 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
| 254 texture_target_, temp_texture_y.name(), 0); | 204 texture_target_, textures_[Y_PLANE_OUTPUT], 0); |
| 255 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, | 205 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, |
| 256 texture_target_, temp_texture_uuvv.name(), 0); | 206 texture_target_, textures_[UUVV_INTERMEDIATE], 0); |
| 257 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | 207 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == |
| 258 GL_FRAMEBUFFER_COMPLETE_EXT); | 208 GL_FRAMEBUFFER_COMPLETE_EXT); |
| 259 static const GLenum kAttachments[] = | 209 glDrawBuffers(2, kColorAttachments); |
| 260 { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT }; | |
| 261 glDrawBuffers(2, kAttachments); | |
| 262 | 210 |
| 263 // Read from |src_texture|. Enable bilinear filtering only if scaling is | 211 // Read from |src_texture|. Enable bilinear filtering only if scaling is |
| 264 // required. The filtering will take place entirely in the first pass. | 212 // required. The filtering will take place entirely in the first pass. |
| 265 glBindTexture(texture_target_, src_texture); | 213 glBindTexture(texture_target_, src_texture); |
| 266 SetTextureParameters( | 214 SetTextureParameters( |
| 267 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, | 215 texture_target_, src_subrect.size() == dst_size ? GL_NEAREST : GL_LINEAR, |
| 268 GL_CLAMP_TO_EDGE); | 216 GL_CLAMP_TO_EDGE); |
| 269 | 217 |
| 270 // Use the first-pass shader program and draw the scene. | 218 // Use the first-pass shader program and draw the scene. |
| 271 const bool prepared_pass_1 = shader_program_cache_->UseRGBToYV12Program( | 219 const bool prepared_pass_1 = shader_program_cache_->UseRGBToYV12Program( |
| 272 1, | 220 1, |
| 273 static_cast<float>(src_subrect.width()) / dst_size.width()); | 221 static_cast<float>(src_subrect.width()) / dst_size.width()); |
| 274 DCHECK(prepared_pass_1); | 222 DCHECK(prepared_pass_1); |
| 275 SetTransformationsForOffScreenRendering(*packed_y_size); | 223 SetTransformationsForOffScreenRendering(*packed_y_size); |
| 276 DrawQuad(src_subrect.x(), src_subrect.y(), | 224 DrawQuad(src_subrect.x(), src_subrect.y(), |
| 277 ((packed_y_size->width() * 4.0f) / dst_size.width()) * | 225 ((packed_y_size->width() * 4.0f) / dst_size.width()) * |
| 278 src_subrect.width(), | 226 src_subrect.width(), |
| 279 src_subrect.height(), | 227 src_subrect.height(), |
| 280 src_texture_needs_y_flip_, | 228 src_texture_needs_y_flip_, |
| 281 packed_y_size->width(), packed_y_size->height()); | 229 packed_y_size->width(), packed_y_size->height()); |
| 282 | 230 |
| 283 ///////////////////////////////////////// | 231 ///////////////////////////////////////// |
| 284 // Pass 2: UUVV -> UUUU + VVVV | 232 // Pass 2: UUVV -> UUUU + VVVV |
| 285 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, | 233 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, |
| 286 texture_target_, temp_texture_u.name(), 0); | 234 texture_target_, textures_[U_PLANE_OUTPUT], 0); |
| 287 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, | 235 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, |
| 288 texture_target_, temp_texture_v.name(), 0); | 236 texture_target_, textures_[V_PLANE_OUTPUT], 0); |
| 289 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == | 237 DCHECK(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == |
| 290 GL_FRAMEBUFFER_COMPLETE_EXT); | 238 GL_FRAMEBUFFER_COMPLETE_EXT); |
| 291 | 239 |
| 292 // Read from texture_uuvv. The second pass uses bilinear minification to | 240 // Read from the intermediate UUVV texture. The second pass uses bilinear |
| 293 // achieve vertical scaling, so enable it always. | 241 // minification to achieve vertical scaling, so enable it always. |
| 294 glBindTexture(texture_target_, temp_texture_uuvv.name()); | 242 glBindTexture(texture_target_, textures_[UUVV_INTERMEDIATE]); |
| 295 SetTextureParameters(texture_target_, GL_LINEAR, GL_CLAMP_TO_EDGE); | 243 SetTextureParameters(texture_target_, GL_LINEAR, GL_CLAMP_TO_EDGE); |
| 296 | 244 |
| 297 // Use the second-pass shader program and draw the scene. | 245 // Use the second-pass shader program and draw the scene. |
| 298 const bool prepared_pass_2 = | 246 const bool prepared_pass_2 = |
| 299 shader_program_cache_->UseRGBToYV12Program(2, 1.0f); | 247 shader_program_cache_->UseRGBToYV12Program(2, 1.0f); |
| 300 DCHECK(prepared_pass_2); | 248 DCHECK(prepared_pass_2); |
| 301 SetTransformationsForOffScreenRendering(*packed_uv_size); | 249 SetTransformationsForOffScreenRendering(*packed_uv_size); |
| 302 DrawQuad(0.0f, 0.0f, | 250 DrawQuad(0.0f, 0.0f, |
| 303 packed_uv_size->width() * 2.0f, | 251 packed_uv_size->width() * 2.0f, |
| 304 packed_uv_size->height() * 2.0f, | 252 packed_uv_size->height() * 2.0f, |
| 305 false, | 253 false, |
| 306 packed_uv_size->width(), packed_uv_size->height()); | 254 packed_uv_size->width(), packed_uv_size->height()); |
| 307 glUseProgram(0); | 255 glUseProgram(0); |
| 308 glBindTexture(texture_target_, 0); | |
| 309 | 256 |
| 310 // Before leaving, put back to drawing to a single rendering output. | 257 // Before leaving, put back to drawing to a single rendering output. |
| 311 glDrawBuffers(1, kAttachments); | 258 glDrawBuffers(1, kColorAttachments); |
| 312 | 259 |
| 313 *texture_y = temp_texture_y.Release(); | 260 glBindTexture(texture_target_, 0); |
| 314 *texture_u = temp_texture_u.Release(); | 261 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); |
| 315 *texture_v = temp_texture_v.Release(); | 262 |
| 263 *texture_y = textures_[Y_PLANE_OUTPUT]; |
| 264 *texture_u = textures_[U_PLANE_OUTPUT]; |
| 265 *texture_v = textures_[V_PLANE_OUTPUT]; |
| 316 return true; | 266 return true; |
| 317 } | 267 } |
| 318 | 268 |
| 269 void CompositingIOSurfaceTransformer::PrepareTexture( |
| 270 CachedTexture which, const gfx::Size& size) { |
| 271 DCHECK_GE(which, 0); |
| 272 DCHECK_LT(which, NUM_CACHED_TEXTURES); |
| 273 DCHECK(!size.IsEmpty()); |
| 274 |
| 275 if (!textures_[which]) { |
| 276 glGenTextures(1, &textures_[which]); |
| 277 DCHECK_NE(textures_[which], 0u); |
| 278 texture_sizes_[which] = gfx::Size(); |
| 279 } |
| 280 |
| 281 // Re-allocate the texture if its size has changed since last use. |
| 282 if (texture_sizes_[which] != size) { |
| 283 TRACE_EVENT2("gpu", "Resize Texture", |
| 284 "which", which, |
| 285 "new_size", size.ToString()); |
| 286 glBindTexture(texture_target_, textures_[which]); |
| 287 glTexImage2D(texture_target_, 0, GL_RGBA, size.width(), size.height(), 0, |
| 288 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL); |
| 289 texture_sizes_[which] = size; |
| 290 } |
| 291 } |
| 292 |
| 293 void CompositingIOSurfaceTransformer::PrepareFramebuffer() { |
| 294 if (!frame_buffer_) { |
| 295 glGenFramebuffersEXT(1, &frame_buffer_); |
| 296 DCHECK_NE(frame_buffer_, 0u); |
| 297 } |
| 298 } |
| 299 |
| 319 } // namespace content | 300 } // namespace content |
| OLD | NEW |