Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/common/gpu/client/gl_helper.h" | 5 #include "content/common/gpu/client/gl_helper.h" |
| 6 | 6 |
| 7 #include <queue> | 7 #include <queue> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/debug/trace_event.h" | 11 #include "base/debug/trace_event.h" |
| 12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
| 17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
| 18 #include "content/common/gpu/client/gl_helper_scaling.h" | 18 #include "content/common/gpu/client/gl_helper_scaling.h" |
| 19 #include "gpu/GLES2/gl2extchromium.h" | |
| 19 #include "gpu/command_buffer/client/context_support.h" | 20 #include "gpu/command_buffer/client/context_support.h" |
| 20 #include "gpu/command_buffer/common/mailbox.h" | 21 #include "gpu/command_buffer/common/mailbox.h" |
| 21 #include "media/base/video_frame.h" | 22 #include "media/base/video_frame.h" |
| 22 #include "media/base/video_util.h" | 23 #include "media/base/video_util.h" |
| 23 #include "third_party/WebKit/public/platform/WebCString.h" | |
| 24 #include "third_party/skia/include/core/SkRegion.h" | 24 #include "third_party/skia/include/core/SkRegion.h" |
| 25 #include "ui/gfx/rect.h" | 25 #include "ui/gfx/rect.h" |
| 26 #include "ui/gfx/size.h" | 26 #include "ui/gfx/size.h" |
| 27 #include "ui/gl/gl_bindings.h" | |
| 28 | 27 |
| 29 using blink::WebGLId; | 28 using gpu::gles2::GLES2Interface; |
| 30 using blink::WebGraphicsContext3D; | |
| 31 | 29 |
| 32 namespace { | 30 namespace { |
| 33 | 31 |
| 34 // Helper class for allocating and holding an RGBA texture of a given | 32 // Helper class for allocating and holding an RGBA texture of a given |
| 35 // size and an associated framebuffer. | 33 // size and an associated framebuffer. |
| 36 class TextureFrameBufferPair { | 34 class TextureFrameBufferPair { |
| 37 public: | 35 public: |
| 38 TextureFrameBufferPair(WebGraphicsContext3D* context, | 36 TextureFrameBufferPair(GLES2Interface* gl, gfx::Size size) |
| 39 gfx::Size size) | 37 : texture_(gl), framebuffer_(gl), size_(size) { |
| 40 : texture_(context, context->createTexture()), | 38 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_); |
| 41 framebuffer_(context, context->createFramebuffer()), | 39 gl->TexImage2D(GL_TEXTURE_2D, |
| 42 size_(size) { | 40 0, |
| 43 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context, | 41 GL_RGBA, |
| 44 texture_); | 42 size.width(), |
| 45 context->texImage2D(GL_TEXTURE_2D, | 43 size.height(), |
| 46 0, | 44 0, |
| 47 GL_RGBA, | 45 GL_RGBA, |
| 48 size.width(), | 46 GL_UNSIGNED_BYTE, |
| 49 size.height(), | 47 NULL); |
| 50 0, | |
| 51 GL_RGBA, | |
| 52 GL_UNSIGNED_BYTE, | |
| 53 NULL); | |
| 54 content::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 48 content::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( |
| 55 context, | 49 gl, framebuffer_); |
| 56 framebuffer_); | 50 gl->FramebufferTexture2D( |
| 57 context->framebufferTexture2D(GL_FRAMEBUFFER, | 51 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0); |
| 58 GL_COLOR_ATTACHMENT0, | |
| 59 GL_TEXTURE_2D, | |
| 60 texture_, | |
| 61 0); | |
| 62 } | 52 } |
| 63 | 53 |
| 64 WebGLId texture() const { return texture_.id(); } | 54 GLuint texture() const { return texture_.id(); } |
| 65 WebGLId framebuffer() const { return framebuffer_.id(); } | 55 GLuint framebuffer() const { return framebuffer_.id(); } |
| 66 gfx::Size size() const { return size_; } | 56 gfx::Size size() const { return size_; } |
| 67 | 57 |
| 68 private: | 58 private: |
| 69 content::ScopedTexture texture_; | 59 content::ScopedTexture texture_; |
| 70 content::ScopedFramebuffer framebuffer_; | 60 content::ScopedFramebuffer framebuffer_; |
| 71 gfx::Size size_; | 61 gfx::Size size_; |
| 72 | 62 |
| 73 DISALLOW_COPY_AND_ASSIGN(TextureFrameBufferPair); | 63 DISALLOW_COPY_AND_ASSIGN(TextureFrameBufferPair); |
| 74 }; | 64 }; |
| 75 | 65 |
| 76 // Helper class for holding a scaler, a texture for the output of that | 66 // Helper class for holding a scaler, a texture for the output of that |
| 77 // scaler and an associated frame buffer. This is inteded to be used | 67 // scaler and an associated frame buffer. This is inteded to be used |
| 78 // when the output of a scaler is to be sent to a readback. | 68 // when the output of a scaler is to be sent to a readback. |
| 79 class ScalerHolder { | 69 class ScalerHolder { |
| 80 public: | 70 public: |
| 81 ScalerHolder(WebGraphicsContext3D* context, | 71 ScalerHolder(GLES2Interface* gl, content::GLHelper::ScalerInterface* scaler) |
| 82 content::GLHelper::ScalerInterface *scaler) | 72 : texture_and_framebuffer_(gl, scaler->DstSize()), scaler_(scaler) {} |
| 83 : texture_and_framebuffer_(context, scaler->DstSize()), | |
| 84 scaler_(scaler) { | |
| 85 } | |
| 86 | 73 |
| 87 void Scale(blink::WebGLId src_texture) { | 74 void Scale(GLuint src_texture) { |
| 88 scaler_->Scale(src_texture, texture_and_framebuffer_.texture()); | 75 scaler_->Scale(src_texture, texture_and_framebuffer_.texture()); |
| 89 } | 76 } |
| 90 | 77 |
| 91 content::GLHelper::ScalerInterface* scaler() const { return scaler_.get(); } | 78 content::GLHelper::ScalerInterface* scaler() const { return scaler_.get(); } |
| 92 TextureFrameBufferPair *texture_and_framebuffer() { | 79 TextureFrameBufferPair* texture_and_framebuffer() { |
| 93 return &texture_and_framebuffer_; | 80 return &texture_and_framebuffer_; |
| 94 } | 81 } |
| 95 WebGLId texture() const { return texture_and_framebuffer_.texture(); } | 82 GLuint texture() const { return texture_and_framebuffer_.texture(); } |
| 96 | 83 |
| 97 private: | 84 private: |
| 98 TextureFrameBufferPair texture_and_framebuffer_; | 85 TextureFrameBufferPair texture_and_framebuffer_; |
| 99 scoped_ptr<content::GLHelper::ScalerInterface> scaler_; | 86 scoped_ptr<content::GLHelper::ScalerInterface> scaler_; |
| 100 | 87 |
| 101 DISALLOW_COPY_AND_ASSIGN(ScalerHolder); | 88 DISALLOW_COPY_AND_ASSIGN(ScalerHolder); |
| 102 }; | 89 }; |
| 103 | 90 |
| 104 } // namespace | 91 } // namespace |
| 105 | 92 |
| 106 namespace content { | 93 namespace content { |
| 107 | 94 |
| 108 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates | 95 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates |
| 109 // the data needed for it. | 96 // the data needed for it. |
| 110 class GLHelper::CopyTextureToImpl : | 97 class GLHelper::CopyTextureToImpl |
| 111 public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> { | 98 : public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> { |
| 112 public: | 99 public: |
| 113 CopyTextureToImpl(WebGraphicsContext3D* context, | 100 CopyTextureToImpl(GLES2Interface* gl, |
| 114 gpu::ContextSupport* context_support, | 101 gpu::ContextSupport* context_support, |
| 115 GLHelper* helper) | 102 GLHelper* helper) |
| 116 : context_(context), | 103 : gl_(gl), |
| 117 context_support_(context_support), | 104 context_support_(context_support), |
| 118 helper_(helper), | 105 helper_(helper), |
| 119 flush_(context), | 106 flush_(gl), |
| 120 max_draw_buffers_(0) { | 107 max_draw_buffers_(0) { |
| 121 std::string extensions_string = " " + | 108 const GLubyte* extensions = gl_->GetString(GL_EXTENSIONS); |
| 122 UTF16ToASCII(context_->getString(GL_EXTENSIONS)) + " "; | 109 std::string extensions_string = |
| 110 " " + std::string(reinterpret_cast<const char*>(extensions)) + " "; | |
|
danakj
2013/12/19 23:40:45
Should this be on ContextProvider::Capabilities? I
jamesr
2013/12/19 23:47:07
It probably should be. Good fodder for a follow-u
| |
| 123 if (extensions_string.find(" GL_EXT_draw_buffers ") != std::string::npos) { | 111 if (extensions_string.find(" GL_EXT_draw_buffers ") != std::string::npos) { |
| 124 context_->getIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers_); | 112 gl_->GetIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &max_draw_buffers_); |
| 125 } | 113 } |
| 126 } | 114 } |
| 127 ~CopyTextureToImpl() { | 115 ~CopyTextureToImpl() { CancelRequests(); } |
| 128 CancelRequests(); | |
| 129 } | |
| 130 | 116 |
| 131 WebGLId ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, | 117 GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, |
| 132 uint32 sync_point) { | 118 uint32 sync_point) { |
| 133 return helper_->ConsumeMailboxToTexture(mailbox, sync_point); | 119 return helper_->ConsumeMailboxToTexture(mailbox, sync_point); |
| 134 } | 120 } |
| 135 | 121 |
| 136 void CropScaleReadbackAndCleanTexture( | 122 void CropScaleReadbackAndCleanTexture( |
| 137 WebGLId src_texture, | 123 GLuint src_texture, |
| 138 const gfx::Size& src_size, | 124 const gfx::Size& src_size, |
| 139 const gfx::Rect& src_subrect, | 125 const gfx::Rect& src_subrect, |
| 140 const gfx::Size& dst_size, | 126 const gfx::Size& dst_size, |
| 141 unsigned char* out, | 127 unsigned char* out, |
| 142 const base::Callback<void(bool)>& callback, | 128 const base::Callback<void(bool)>& callback, |
| 143 GLHelper::ScalerQuality quality); | 129 GLHelper::ScalerQuality quality); |
| 144 | 130 |
| 145 void ReadbackTextureSync(WebGLId texture, | 131 void ReadbackTextureSync(GLuint texture, |
| 146 const gfx::Rect& src_rect, | 132 const gfx::Rect& src_rect, |
| 147 unsigned char* out); | 133 unsigned char* out); |
| 148 | 134 |
| 149 // Reads back bytes from the currently bound frame buffer. | 135 // Reads back bytes from the currently bound frame buffer. |
| 150 // Note that dst_size is specified in bytes, not pixels. | 136 // Note that dst_size is specified in bytes, not pixels. |
| 151 void ReadbackAsync( | 137 void ReadbackAsync(const gfx::Size& dst_size, |
| 152 const gfx::Size& dst_size, | 138 int32 bytes_per_row, // generally dst_size.width() * 4 |
| 153 int32 bytes_per_row, // generally dst_size.width() * 4 | 139 int32 row_stride_bytes, // generally dst_size.width() * 4 |
| 154 int32 row_stride_bytes, // generally dst_size.width() * 4 | 140 unsigned char* out, |
| 155 unsigned char* out, | 141 const base::Callback<void(bool)>& callback); |
| 156 const base::Callback<void(bool)>& callback); | |
| 157 | 142 |
| 158 void ReadbackPlane(TextureFrameBufferPair* source, | 143 void ReadbackPlane(TextureFrameBufferPair* source, |
| 159 const scoped_refptr<media::VideoFrame>& target, | 144 const scoped_refptr<media::VideoFrame>& target, |
| 160 int plane, | 145 int plane, |
| 161 int size_shift, | 146 int size_shift, |
| 162 const gfx::Rect& dst_subrect, | 147 const gfx::Rect& dst_subrect, |
| 163 const base::Callback<void(bool)>& callback); | 148 const base::Callback<void(bool)>& callback); |
| 164 | 149 |
| 165 blink::WebGLId CopyAndScaleTexture(WebGLId texture, | 150 GLuint CopyAndScaleTexture(GLuint texture, |
| 166 const gfx::Size& src_size, | 151 const gfx::Size& src_size, |
| 167 const gfx::Size& dst_size, | 152 const gfx::Size& dst_size, |
| 168 bool vertically_flip_texture, | 153 bool vertically_flip_texture, |
| 169 GLHelper::ScalerQuality quality); | 154 GLHelper::ScalerQuality quality); |
| 170 | 155 |
| 171 ReadbackYUVInterface* CreateReadbackPipelineYUV( | 156 ReadbackYUVInterface* CreateReadbackPipelineYUV( |
| 172 GLHelper::ScalerQuality quality, | 157 GLHelper::ScalerQuality quality, |
| 173 const gfx::Size& src_size, | 158 const gfx::Size& src_size, |
| 174 const gfx::Rect& src_subrect, | 159 const gfx::Rect& src_subrect, |
| 175 const gfx::Size& dst_size, | 160 const gfx::Size& dst_size, |
| 176 const gfx::Rect& dst_subrect, | 161 const gfx::Rect& dst_subrect, |
| 177 bool flip_vertically, | 162 bool flip_vertically, |
| 178 bool use_mrt); | 163 bool use_mrt); |
| 179 | 164 |
| 180 // Returns the maximum number of draw buffers available, | 165 // Returns the maximum number of draw buffers available, |
| 181 // 0 if GL_EXT_draw_buffers is not available. | 166 // 0 if GL_EXT_draw_buffers is not available. |
| 182 blink::WGC3Dint MaxDrawBuffers() const { | 167 GLint MaxDrawBuffers() const { return max_draw_buffers_; } |
| 183 return max_draw_buffers_; | |
| 184 } | |
| 185 | 168 |
| 186 private: | 169 private: |
| 187 // A single request to CropScaleReadbackAndCleanTexture. | 170 // A single request to CropScaleReadbackAndCleanTexture. |
| 188 // The main thread can cancel the request, before it's handled by the helper | 171 // The main thread can cancel the request, before it's handled by the helper |
| 189 // thread, by resetting the texture and pixels fields. Alternatively, the | 172 // thread, by resetting the texture and pixels fields. Alternatively, the |
| 190 // thread marks that it handles the request by resetting the pixels field | 173 // thread marks that it handles the request by resetting the pixels field |
| 191 // (meaning it guarantees that the callback with be called). | 174 // (meaning it guarantees that the callback with be called). |
| 192 // In either case, the callback must be called exactly once, and the texture | 175 // In either case, the callback must be called exactly once, and the texture |
| 193 // must be deleted by the main thread context. | 176 // must be deleted by the main thread gl. |
| 194 struct Request { | 177 struct Request { |
| 195 Request(const gfx::Size& size_, | 178 Request(const gfx::Size& size_, |
| 196 int32 bytes_per_row_, | 179 int32 bytes_per_row_, |
| 197 int32 row_stride_bytes_, | 180 int32 row_stride_bytes_, |
| 198 unsigned char* pixels_, | 181 unsigned char* pixels_, |
| 199 const base::Callback<void(bool)>& callback_) | 182 const base::Callback<void(bool)>& callback_) |
| 200 : done(false), | 183 : done(false), |
| 201 size(size_), | 184 size(size_), |
| 202 bytes_per_row(bytes_per_row_), | 185 bytes_per_row(bytes_per_row_), |
| 203 row_stride_bytes(row_stride_bytes_), | 186 row_stride_bytes(row_stride_bytes_), |
| 204 pixels(pixels_), | 187 pixels(pixels_), |
| 205 callback(callback_), | 188 callback(callback_), |
| 206 buffer(0), | 189 buffer(0), |
| 207 query(0) { | 190 query(0) {} |
| 208 } | |
| 209 | 191 |
| 210 bool done; | 192 bool done; |
| 211 gfx::Size size; | 193 gfx::Size size; |
| 212 int bytes_per_row; | 194 int bytes_per_row; |
| 213 int row_stride_bytes; | 195 int row_stride_bytes; |
| 214 unsigned char* pixels; | 196 unsigned char* pixels; |
| 215 base::Callback<void(bool)> callback; | 197 base::Callback<void(bool)> callback; |
| 216 GLuint buffer; | 198 GLuint buffer; |
| 217 blink::WebGLId query; | 199 GLuint query; |
| 218 }; | 200 }; |
| 219 | 201 |
| 220 // A readback pipeline that also converts the data to YUV before | 202 // A readback pipeline that also converts the data to YUV before |
| 221 // reading it back. | 203 // reading it back. |
| 222 class ReadbackYUVImpl : public ReadbackYUVInterface { | 204 class ReadbackYUVImpl : public ReadbackYUVInterface { |
| 223 public: | 205 public: |
| 224 ReadbackYUVImpl(WebGraphicsContext3D* context, | 206 ReadbackYUVImpl(GLES2Interface* gl, |
| 225 CopyTextureToImpl* copy_impl, | 207 CopyTextureToImpl* copy_impl, |
| 226 GLHelperScaling* scaler_impl, | 208 GLHelperScaling* scaler_impl, |
| 227 GLHelper::ScalerQuality quality, | 209 GLHelper::ScalerQuality quality, |
| 228 const gfx::Size& src_size, | 210 const gfx::Size& src_size, |
| 229 const gfx::Rect& src_subrect, | 211 const gfx::Rect& src_subrect, |
| 230 const gfx::Size& dst_size, | 212 const gfx::Size& dst_size, |
| 231 const gfx::Rect& dst_subrect, | 213 const gfx::Rect& dst_subrect, |
| 232 bool flip_vertically); | 214 bool flip_vertically); |
| 233 | 215 |
| 234 virtual void ReadbackYUV( | 216 virtual void ReadbackYUV(const gpu::Mailbox& mailbox, |
| 235 const gpu::Mailbox& mailbox, | 217 uint32 sync_point, |
| 236 uint32 sync_point, | 218 const scoped_refptr<media::VideoFrame>& target, |
| 237 const scoped_refptr<media::VideoFrame>& target, | 219 const base::Callback<void(bool)>& callback) |
| 238 const base::Callback<void(bool)>& callback) OVERRIDE; | 220 OVERRIDE; |
| 239 | 221 |
| 240 virtual ScalerInterface* scaler() OVERRIDE { | 222 virtual ScalerInterface* scaler() OVERRIDE { return scaler_.scaler(); } |
| 241 return scaler_.scaler(); | |
| 242 } | |
| 243 | 223 |
| 244 private: | 224 private: |
| 245 WebGraphicsContext3D* context_; | 225 GLES2Interface* gl_; |
| 246 CopyTextureToImpl* copy_impl_; | 226 CopyTextureToImpl* copy_impl_; |
| 247 gfx::Size dst_size_; | 227 gfx::Size dst_size_; |
| 248 gfx::Rect dst_subrect_; | 228 gfx::Rect dst_subrect_; |
| 249 ScalerHolder scaler_; | 229 ScalerHolder scaler_; |
| 250 ScalerHolder y_; | 230 ScalerHolder y_; |
| 251 ScalerHolder u_; | 231 ScalerHolder u_; |
| 252 ScalerHolder v_; | 232 ScalerHolder v_; |
| 253 | 233 |
| 254 DISALLOW_COPY_AND_ASSIGN(ReadbackYUVImpl); | 234 DISALLOW_COPY_AND_ASSIGN(ReadbackYUVImpl); |
| 255 }; | 235 }; |
| 256 | 236 |
| 257 // A readback pipeline that also converts the data to YUV before | 237 // A readback pipeline that also converts the data to YUV before |
| 258 // reading it back. This one uses Multiple Render Targets, which | 238 // reading it back. This one uses Multiple Render Targets, which |
| 259 // may not be supported on all platforms. | 239 // may not be supported on all platforms. |
| 260 class ReadbackYUV_MRT : public ReadbackYUVInterface { | 240 class ReadbackYUV_MRT : public ReadbackYUVInterface { |
| 261 public: | 241 public: |
| 262 ReadbackYUV_MRT(WebGraphicsContext3D* context, | 242 ReadbackYUV_MRT(GLES2Interface* gl, |
| 263 CopyTextureToImpl* copy_impl, | 243 CopyTextureToImpl* copy_impl, |
| 264 GLHelperScaling* scaler_impl, | 244 GLHelperScaling* scaler_impl, |
| 265 GLHelper::ScalerQuality quality, | 245 GLHelper::ScalerQuality quality, |
| 266 const gfx::Size& src_size, | 246 const gfx::Size& src_size, |
| 267 const gfx::Rect& src_subrect, | 247 const gfx::Rect& src_subrect, |
| 268 const gfx::Size& dst_size, | 248 const gfx::Size& dst_size, |
| 269 const gfx::Rect& dst_subrect, | 249 const gfx::Rect& dst_subrect, |
| 270 bool flip_vertically); | 250 bool flip_vertically); |
| 271 | 251 |
| 272 virtual void ReadbackYUV( | 252 virtual void ReadbackYUV(const gpu::Mailbox& mailbox, |
| 273 const gpu::Mailbox& mailbox, | 253 uint32 sync_point, |
| 274 uint32 sync_point, | 254 const scoped_refptr<media::VideoFrame>& target, |
| 275 const scoped_refptr<media::VideoFrame>& target, | 255 const base::Callback<void(bool)>& callback) |
| 276 const base::Callback<void(bool)>& callback) OVERRIDE; | 256 OVERRIDE; |
| 277 | 257 |
| 278 virtual ScalerInterface* scaler() OVERRIDE { | 258 virtual ScalerInterface* scaler() OVERRIDE { return scaler_.scaler(); } |
| 279 return scaler_.scaler(); | |
| 280 } | |
| 281 | 259 |
| 282 private: | 260 private: |
| 283 WebGraphicsContext3D* context_; | 261 GLES2Interface* gl_; |
| 284 CopyTextureToImpl* copy_impl_; | 262 CopyTextureToImpl* copy_impl_; |
| 285 gfx::Size dst_size_; | 263 gfx::Size dst_size_; |
| 286 gfx::Rect dst_subrect_; | 264 gfx::Rect dst_subrect_; |
| 287 GLHelper::ScalerQuality quality_; | 265 GLHelper::ScalerQuality quality_; |
| 288 ScalerHolder scaler_; | 266 ScalerHolder scaler_; |
| 289 scoped_ptr<content::GLHelperScaling::ShaderInterface> pass1_shader_; | 267 scoped_ptr<content::GLHelperScaling::ShaderInterface> pass1_shader_; |
| 290 scoped_ptr<content::GLHelperScaling::ShaderInterface> pass2_shader_; | 268 scoped_ptr<content::GLHelperScaling::ShaderInterface> pass2_shader_; |
| 291 TextureFrameBufferPair y_; | 269 TextureFrameBufferPair y_; |
| 292 ScopedTexture uv_; | 270 ScopedTexture uv_; |
| 293 TextureFrameBufferPair u_; | 271 TextureFrameBufferPair u_; |
| 294 TextureFrameBufferPair v_; | 272 TextureFrameBufferPair v_; |
| 295 | 273 |
| 296 DISALLOW_COPY_AND_ASSIGN(ReadbackYUV_MRT); | 274 DISALLOW_COPY_AND_ASSIGN(ReadbackYUV_MRT); |
| 297 }; | 275 }; |
| 298 | 276 |
| 299 // Copies the block of pixels specified with |src_subrect| from |src_texture|, | 277 // Copies the block of pixels specified with |src_subrect| from |src_texture|, |
| 300 // scales it to |dst_size|, writes it into a texture, and returns its ID. | 278 // scales it to |dst_size|, writes it into a texture, and returns its ID. |
| 301 // |src_size| is the size of |src_texture|. | 279 // |src_size| is the size of |src_texture|. |
| 302 WebGLId ScaleTexture(WebGLId src_texture, | 280 GLuint ScaleTexture(GLuint src_texture, |
| 303 const gfx::Size& src_size, | 281 const gfx::Size& src_size, |
| 304 const gfx::Rect& src_subrect, | 282 const gfx::Rect& src_subrect, |
| 305 const gfx::Size& dst_size, | 283 const gfx::Size& dst_size, |
| 306 bool vertically_flip_texture, | 284 bool vertically_flip_texture, |
| 307 bool swizzle, | 285 bool swizzle, |
| 308 GLHelper::ScalerQuality quality); | 286 GLHelper::ScalerQuality quality); |
| 309 | 287 |
| 310 static void nullcallback(bool success) {} | 288 static void nullcallback(bool success) {} |
| 311 void ReadbackDone(Request *request); | 289 void ReadbackDone(Request* request); |
| 312 void FinishRequest(Request* request, bool result); | 290 void FinishRequest(Request* request, bool result); |
| 313 void CancelRequests(); | 291 void CancelRequests(); |
| 314 | 292 |
| 315 static const float kRGBtoYColorWeights[]; | 293 static const float kRGBtoYColorWeights[]; |
| 316 static const float kRGBtoUColorWeights[]; | 294 static const float kRGBtoUColorWeights[]; |
| 317 static const float kRGBtoVColorWeights[]; | 295 static const float kRGBtoVColorWeights[]; |
| 318 | 296 |
| 319 WebGraphicsContext3D* context_; | 297 GLES2Interface* gl_; |
| 320 gpu::ContextSupport* context_support_; | 298 gpu::ContextSupport* context_support_; |
| 321 GLHelper* helper_; | 299 GLHelper* helper_; |
| 322 | 300 |
| 323 // A scoped flush that will ensure all resource deletions are flushed when | 301 // A scoped flush that will ensure all resource deletions are flushed when |
| 324 // this object is destroyed. Must be declared before other Scoped* fields. | 302 // this object is destroyed. Must be declared before other Scoped* fields. |
| 325 ScopedFlush flush_; | 303 ScopedFlush flush_; |
| 326 | 304 |
| 327 std::queue<Request*> request_queue_; | 305 std::queue<Request*> request_queue_; |
| 328 blink::WGC3Dint max_draw_buffers_; | 306 GLint max_draw_buffers_; |
| 329 }; | 307 }; |
| 330 | 308 |
| 331 GLHelper::ScalerInterface* GLHelper::CreateScaler( | 309 GLHelper::ScalerInterface* GLHelper::CreateScaler(ScalerQuality quality, |
| 332 ScalerQuality quality, | 310 const gfx::Size& src_size, |
| 333 const gfx::Size& src_size, | 311 const gfx::Rect& src_subrect, |
| 334 const gfx::Rect& src_subrect, | 312 const gfx::Size& dst_size, |
| 335 const gfx::Size& dst_size, | 313 bool vertically_flip_texture, |
| 336 bool vertically_flip_texture, | 314 bool swizzle) { |
| 337 bool swizzle) { | |
| 338 InitScalerImpl(); | 315 InitScalerImpl(); |
| 339 return scaler_impl_->CreateScaler(quality, | 316 return scaler_impl_->CreateScaler(quality, |
| 340 src_size, | 317 src_size, |
| 341 src_subrect, | 318 src_subrect, |
| 342 dst_size, | 319 dst_size, |
| 343 vertically_flip_texture, | 320 vertically_flip_texture, |
| 344 swizzle); | 321 swizzle); |
| 345 } | 322 } |
| 346 | 323 |
| 347 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( | 324 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
| 348 WebGLId src_texture, | 325 GLuint src_texture, |
| 349 const gfx::Size& src_size, | 326 const gfx::Size& src_size, |
| 350 const gfx::Rect& src_subrect, | 327 const gfx::Rect& src_subrect, |
| 351 const gfx::Size& dst_size, | 328 const gfx::Size& dst_size, |
| 352 bool vertically_flip_texture, | 329 bool vertically_flip_texture, |
| 353 bool swizzle, | 330 bool swizzle, |
| 354 GLHelper::ScalerQuality quality) { | 331 GLHelper::ScalerQuality quality) { |
| 355 scoped_ptr<ScalerInterface> scaler( | 332 scoped_ptr<ScalerInterface> scaler( |
| 356 helper_->CreateScaler(quality, | 333 helper_->CreateScaler(quality, |
| 357 src_size, | 334 src_size, |
| 358 src_subrect, | 335 src_subrect, |
| 359 dst_size, | 336 dst_size, |
| 360 vertically_flip_texture, | 337 vertically_flip_texture, |
| 361 swizzle)); | 338 swizzle)); |
| 362 | 339 |
| 363 WebGLId dst_texture = context_->createTexture(); | 340 GLuint dst_texture = 0u; |
| 341 gl_->GenTextures(1, &dst_texture); | |
| 364 { | 342 { |
| 365 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, dst_texture); | 343 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| 366 context_->texImage2D(GL_TEXTURE_2D, | 344 gl_->TexImage2D(GL_TEXTURE_2D, |
| 367 0, | 345 0, |
| 368 GL_RGBA, | 346 GL_RGBA, |
| 369 dst_size.width(), | 347 dst_size.width(), |
| 370 dst_size.height(), | 348 dst_size.height(), |
| 371 0, | 349 0, |
| 372 GL_RGBA, | 350 GL_RGBA, |
| 373 GL_UNSIGNED_BYTE, | 351 GL_UNSIGNED_BYTE, |
| 374 NULL); | 352 NULL); |
| 375 } | 353 } |
| 376 scaler->Scale(src_texture, dst_texture); | 354 scaler->Scale(src_texture, dst_texture); |
| 377 return dst_texture; | 355 return dst_texture; |
| 378 } | 356 } |
| 379 | 357 |
| 380 void GLHelper::CopyTextureToImpl::ReadbackAsync( | 358 void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| 381 const gfx::Size& dst_size, | 359 const gfx::Size& dst_size, |
| 382 int32 bytes_per_row, | 360 int32 bytes_per_row, |
| 383 int32 row_stride_bytes, | 361 int32 row_stride_bytes, |
| 384 unsigned char* out, | 362 unsigned char* out, |
| 385 const base::Callback<void(bool)>& callback) { | 363 const base::Callback<void(bool)>& callback) { |
| 386 Request* request = new Request(dst_size, | 364 Request* request = |
| 387 bytes_per_row, | 365 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
| 388 row_stride_bytes, | |
| 389 out, | |
| 390 callback); | |
| 391 request_queue_.push(request); | 366 request_queue_.push(request); |
| 392 request->buffer = context_->createBuffer(); | 367 request->buffer = 0u; |
| 393 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 368 gl_->GenBuffers(1, &request->buffer); |
| 394 request->buffer); | 369 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
| 395 context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 370 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 396 4 * dst_size.GetArea(), | 371 4 * dst_size.GetArea(), |
| 397 NULL, | 372 NULL, |
| 398 GL_STREAM_READ); | 373 GL_STREAM_READ); |
| 399 | 374 |
| 400 request->query = context_->createQueryEXT(); | 375 request->query = 0u; |
| 401 context_->beginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, | 376 gl_->GenQueriesEXT(1, &request->query); |
| 402 request->query); | 377 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
| 403 context_->readPixels(0, 0, dst_size.width(), dst_size.height(), | 378 gl_->ReadPixels(0, |
| 404 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 379 0, |
| 405 context_->endQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); | 380 dst_size.width(), |
| 406 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | 381 dst_size.height(), |
| 382 GL_RGBA, | |
| 383 GL_UNSIGNED_BYTE, | |
| 384 NULL); | |
| 385 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); | |
| 386 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | |
| 407 context_support_->SignalQuery( | 387 context_support_->SignalQuery( |
| 408 request->query, | 388 request->query, |
| 409 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request)); | 389 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request)); |
| 410 } | 390 } |
| 411 | 391 |
| 412 | |
| 413 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 392 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| 414 WebGLId src_texture, | 393 GLuint src_texture, |
| 415 const gfx::Size& src_size, | 394 const gfx::Size& src_size, |
| 416 const gfx::Rect& src_subrect, | 395 const gfx::Rect& src_subrect, |
| 417 const gfx::Size& dst_size, | 396 const gfx::Size& dst_size, |
| 418 unsigned char* out, | 397 unsigned char* out, |
| 419 const base::Callback<void(bool)>& callback, | 398 const base::Callback<void(bool)>& callback, |
| 420 GLHelper::ScalerQuality quality) { | 399 GLHelper::ScalerQuality quality) { |
| 421 WebGLId texture = ScaleTexture(src_texture, | 400 GLuint texture = ScaleTexture(src_texture, |
| 422 src_size, | 401 src_size, |
| 423 src_subrect, | 402 src_subrect, |
| 424 dst_size, | 403 dst_size, |
| 425 true, | 404 true, |
| 426 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 405 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| 427 true, | 406 true, |
| 428 #else | 407 #else |
| 429 false, | 408 false, |
| 430 #endif | 409 #endif |
| 431 quality); | 410 quality); |
| 432 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 411 ScopedFramebuffer dst_framebuffer(gl_); |
| 433 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_, | 412 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 434 dst_framebuffer); | 413 dst_framebuffer); |
| 435 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 414 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 436 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 415 gl_->FramebufferTexture2D( |
| 437 GL_COLOR_ATTACHMENT0, | 416 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
| 438 GL_TEXTURE_2D, | 417 ReadbackAsync( |
| 439 texture, | 418 dst_size, dst_size.width() * 4, dst_size.width() * 4, out, callback); |
| 440 0); | 419 gl_->DeleteTextures(1, &texture); |
| 441 ReadbackAsync(dst_size, | |
| 442 dst_size.width() * 4, | |
| 443 dst_size.width() * 4, | |
| 444 out, | |
| 445 callback); | |
| 446 context_->deleteTexture(texture); | |
| 447 } | 420 } |
| 448 | 421 |
| 449 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( | 422 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(GLuint texture, |
| 450 WebGLId texture, | 423 const gfx::Rect& src_rect, |
| 451 const gfx::Rect& src_rect, | 424 unsigned char* out) { |
| 452 unsigned char* out) { | 425 ScopedFramebuffer dst_framebuffer(gl_); |
| 453 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 426 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 454 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_, | |
| 455 dst_framebuffer); | 427 dst_framebuffer); |
| 456 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 428 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 457 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 429 gl_->FramebufferTexture2D( |
| 458 GL_COLOR_ATTACHMENT0, | 430 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
| 459 GL_TEXTURE_2D, | 431 gl_->ReadPixels(src_rect.x(), |
| 460 texture, | 432 src_rect.y(), |
| 461 0); | 433 src_rect.width(), |
| 462 context_->readPixels(src_rect.x(), | 434 src_rect.height(), |
| 463 src_rect.y(), | 435 GL_RGBA, |
| 464 src_rect.width(), | 436 GL_UNSIGNED_BYTE, |
| 465 src_rect.height(), | 437 out); |
| 466 GL_RGBA, | |
| 467 GL_UNSIGNED_BYTE, | |
| 468 out); | |
| 469 } | 438 } |
| 470 | 439 |
| 471 blink::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 440 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
| 472 WebGLId src_texture, | 441 GLuint src_texture, |
| 473 const gfx::Size& src_size, | 442 const gfx::Size& src_size, |
| 474 const gfx::Size& dst_size, | 443 const gfx::Size& dst_size, |
| 475 bool vertically_flip_texture, | 444 bool vertically_flip_texture, |
| 476 GLHelper::ScalerQuality quality) { | 445 GLHelper::ScalerQuality quality) { |
| 477 return ScaleTexture(src_texture, | 446 return ScaleTexture(src_texture, |
| 478 src_size, | 447 src_size, |
| 479 gfx::Rect(src_size), | 448 gfx::Rect(src_size), |
| 480 dst_size, | 449 dst_size, |
| 481 vertically_flip_texture, | 450 vertically_flip_texture, |
| 482 false, | 451 false, |
| 483 quality); | 452 quality); |
| 484 } | 453 } |
| 485 | 454 |
| 486 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) { | 455 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) { |
| 487 TRACE_EVENT0("mirror", | 456 TRACE_EVENT0("mirror", |
| 488 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); | 457 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); |
| 489 finished_request->done = true; | 458 finished_request->done = true; |
| 490 | 459 |
| 491 // We process transfer requests in the order they were received, regardless | 460 // We process transfer requests in the order they were received, regardless |
| 492 // of the order we get the callbacks in. | 461 // of the order we get the callbacks in. |
| 493 while (!request_queue_.empty()) { | 462 while (!request_queue_.empty()) { |
| 494 Request* request = request_queue_.front(); | 463 Request* request = request_queue_.front(); |
| 495 if (!request->done) { | 464 if (!request->done) { |
| 496 break; | 465 break; |
| 497 } | 466 } |
| 498 | 467 |
| 499 bool result = false; | 468 bool result = false; |
| 500 if (request->buffer != 0) { | 469 if (request->buffer != 0) { |
| 501 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 470 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
| 502 request->buffer); | 471 unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM( |
| 503 unsigned char* data = static_cast<unsigned char *>( | 472 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
| 504 context_->mapBufferCHROMIUM( | |
| 505 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); | |
| 506 if (data) { | 473 if (data) { |
| 507 result = true; | 474 result = true; |
| 508 if (request->bytes_per_row == request->size.width() * 4 && | 475 if (request->bytes_per_row == request->size.width() * 4 && |
| 509 request->bytes_per_row == request->row_stride_bytes) { | 476 request->bytes_per_row == request->row_stride_bytes) { |
| 510 memcpy(request->pixels, data, request->size.GetArea() * 4); | 477 memcpy(request->pixels, data, request->size.GetArea() * 4); |
| 511 } else { | 478 } else { |
| 512 unsigned char* out = request->pixels; | 479 unsigned char* out = request->pixels; |
| 513 for (int y = 0; y < request->size.height(); y++) { | 480 for (int y = 0; y < request->size.height(); y++) { |
| 514 memcpy(out, data, request->bytes_per_row); | 481 memcpy(out, data, request->bytes_per_row); |
| 515 out += request->row_stride_bytes; | 482 out += request->row_stride_bytes; |
| 516 data += request->size.width() * 4; | 483 data += request->size.width() * 4; |
| 517 } | 484 } |
| 518 } | 485 } |
| 519 context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); | 486 gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
| 520 } | 487 } |
| 521 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | 488 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| 522 } | 489 } |
| 523 | 490 |
| 524 FinishRequest(request, result); | 491 FinishRequest(request, result); |
| 525 } | 492 } |
| 526 } | 493 } |
| 527 | 494 |
| 528 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, | 495 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) { |
| 529 bool result) { | |
| 530 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest"); | 496 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest"); |
| 531 DCHECK(request_queue_.front() == request); | 497 DCHECK(request_queue_.front() == request); |
| 532 request_queue_.pop(); | 498 request_queue_.pop(); |
| 533 request->callback.Run(result); | 499 request->callback.Run(result); |
| 534 ScopedFlush flush(context_); | 500 ScopedFlush flush(gl_); |
| 535 if (request->query != 0) { | 501 if (request->query != 0) { |
| 536 context_->deleteQueryEXT(request->query); | 502 gl_->DeleteQueriesEXT(1, &request->query); |
| 537 request->query = 0; | 503 request->query = 0; |
| 538 } | 504 } |
| 539 if (request->buffer != 0) { | 505 if (request->buffer != 0) { |
| 540 context_->deleteBuffer(request->buffer); | 506 gl_->DeleteBuffers(1, &request->buffer); |
| 541 request->buffer = 0; | 507 request->buffer = 0; |
| 542 } | 508 } |
| 543 delete request; | 509 delete request; |
| 544 } | 510 } |
| 545 | 511 |
| 546 void GLHelper::CopyTextureToImpl::CancelRequests() { | 512 void GLHelper::CopyTextureToImpl::CancelRequests() { |
| 547 while (!request_queue_.empty()) { | 513 while (!request_queue_.empty()) { |
| 548 Request* request = request_queue_.front(); | 514 Request* request = request_queue_.front(); |
| 549 FinishRequest(request, false); | 515 FinishRequest(request, false); |
| 550 } | 516 } |
| 551 } | 517 } |
| 552 | 518 |
| 553 GLHelper::GLHelper(blink::WebGraphicsContext3D* context, | 519 GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) |
| 554 gpu::ContextSupport* context_support) | 520 : gl_(gl), context_support_(context_support) {} |
| 555 : context_(context), | |
| 556 context_support_(context_support) { | |
| 557 } | |
| 558 | 521 |
| 559 GLHelper::~GLHelper() { | 522 GLHelper::~GLHelper() {} |
| 560 } | |
| 561 | 523 |
| 562 void GLHelper::CropScaleReadbackAndCleanTexture( | 524 void GLHelper::CropScaleReadbackAndCleanTexture( |
| 563 WebGLId src_texture, | 525 GLuint src_texture, |
| 564 const gfx::Size& src_size, | 526 const gfx::Size& src_size, |
| 565 const gfx::Rect& src_subrect, | 527 const gfx::Rect& src_subrect, |
| 566 const gfx::Size& dst_size, | 528 const gfx::Size& dst_size, |
| 567 unsigned char* out, | 529 unsigned char* out, |
| 568 const base::Callback<void(bool)>& callback) { | 530 const base::Callback<void(bool)>& callback) { |
| 569 InitCopyTextToImpl(); | 531 InitCopyTextToImpl(); |
| 570 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( | 532 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( |
| 571 src_texture, | 533 src_texture, |
| 572 src_size, | 534 src_size, |
| 573 src_subrect, | 535 src_subrect, |
| 574 dst_size, | 536 dst_size, |
| 575 out, | 537 out, |
| 576 callback, | 538 callback, |
| 577 GLHelper::SCALER_QUALITY_FAST); | 539 GLHelper::SCALER_QUALITY_FAST); |
| 578 } | 540 } |
| 579 | 541 |
| 580 void GLHelper::CropScaleReadbackAndCleanMailbox( | 542 void GLHelper::CropScaleReadbackAndCleanMailbox( |
| 581 const gpu::Mailbox& src_mailbox, | 543 const gpu::Mailbox& src_mailbox, |
| 582 uint32 sync_point, | 544 uint32 sync_point, |
| 583 const gfx::Size& src_size, | 545 const gfx::Size& src_size, |
| 584 const gfx::Rect& src_subrect, | 546 const gfx::Rect& src_subrect, |
| 585 const gfx::Size& dst_size, | 547 const gfx::Size& dst_size, |
| 586 unsigned char* out, | 548 unsigned char* out, |
| 587 const base::Callback<void(bool)>& callback) { | 549 const base::Callback<void(bool)>& callback) { |
| 588 WebGLId mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); | 550 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); |
| 589 CropScaleReadbackAndCleanTexture( | 551 CropScaleReadbackAndCleanTexture( |
| 590 mailbox_texture, src_size, src_subrect, dst_size, out, callback); | 552 mailbox_texture, src_size, src_subrect, dst_size, out, callback); |
| 591 context_->deleteTexture(mailbox_texture); | 553 gl_->DeleteTextures(1, &mailbox_texture); |
| 592 } | 554 } |
| 593 | 555 |
| 594 void GLHelper::ReadbackTextureSync(blink::WebGLId texture, | 556 void GLHelper::ReadbackTextureSync(GLuint texture, |
| 595 const gfx::Rect& src_rect, | 557 const gfx::Rect& src_rect, |
| 596 unsigned char* out) { | 558 unsigned char* out) { |
| 597 InitCopyTextToImpl(); | 559 InitCopyTextToImpl(); |
| 598 copy_texture_to_impl_->ReadbackTextureSync(texture, | 560 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out); |
| 599 src_rect, | |
| 600 out); | |
| 601 } | 561 } |
| 602 | 562 |
| 603 blink::WebGLId GLHelper::CopyTexture(blink::WebGLId texture, | 563 GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) { |
| 604 const gfx::Size& size) { | |
| 605 InitCopyTextToImpl(); | 564 InitCopyTextToImpl(); |
| 606 return copy_texture_to_impl_->CopyAndScaleTexture( | 565 return copy_texture_to_impl_->CopyAndScaleTexture( |
| 607 texture, | 566 texture, size, size, false, GLHelper::SCALER_QUALITY_FAST); |
| 608 size, | |
| 609 size, | |
| 610 false, | |
| 611 GLHelper::SCALER_QUALITY_FAST); | |
| 612 } | 567 } |
| 613 | 568 |
| 614 blink::WebGLId GLHelper::CopyAndScaleTexture( | 569 GLuint GLHelper::CopyAndScaleTexture(GLuint texture, |
| 615 blink::WebGLId texture, | 570 const gfx::Size& src_size, |
| 616 const gfx::Size& src_size, | 571 const gfx::Size& dst_size, |
| 617 const gfx::Size& dst_size, | 572 bool vertically_flip_texture, |
| 618 bool vertically_flip_texture, | 573 ScalerQuality quality) { |
| 619 ScalerQuality quality) { | |
| 620 InitCopyTextToImpl(); | 574 InitCopyTextToImpl(); |
| 621 return copy_texture_to_impl_->CopyAndScaleTexture(texture, | 575 return copy_texture_to_impl_->CopyAndScaleTexture( |
| 622 src_size, | 576 texture, src_size, dst_size, vertically_flip_texture, quality); |
| 623 dst_size, | |
| 624 vertically_flip_texture, | |
| 625 quality); | |
| 626 } | 577 } |
| 627 | 578 |
| 628 WebGLId GLHelper::CompileShaderFromSource( | 579 GLuint GLHelper::CompileShaderFromSource(const GLchar* source, GLenum type) { |
| 629 const blink::WGC3Dchar* source, | 580 GLuint shader = gl_->CreateShader(type); |
|
danakj
2013/12/19 23:40:45
I see you removed ScopedShader. If this was the on
| |
| 630 blink::WGC3Denum type) { | 581 GLint length = strlen(source); |
| 631 ScopedShader shader(context_, context_->createShader(type)); | 582 gl_->ShaderSource(shader, 1, &source, &length); |
| 632 context_->shaderSource(shader, source); | 583 gl_->CompileShader(shader); |
| 633 context_->compileShader(shader); | 584 GLint compile_status = 0; |
| 634 blink::WGC3Dint compile_status = 0; | 585 gl_->GetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
| 635 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | |
| 636 if (!compile_status) { | 586 if (!compile_status) { |
| 637 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); | 587 // LOG(ERROR) << std::string(gl_->getShaderInfoLog(shader)); |
|
danakj
2013/12/19 23:40:45
I doubt this was meant to be left as a comment?
jamesr
2013/12/20 23:38:17
Added back - it just takes a lot of lines to actua
| |
| 588 gl_->DeleteShader(shader); | |
| 638 return 0; | 589 return 0; |
| 639 } | 590 } |
| 640 return shader.Detach(); | 591 return shader; |
| 641 } | 592 } |
| 642 | 593 |
| 643 void GLHelper::InitCopyTextToImpl() { | 594 void GLHelper::InitCopyTextToImpl() { |
| 644 // Lazily initialize |copy_texture_to_impl_| | 595 // Lazily initialize |copy_texture_to_impl_| |
| 645 if (!copy_texture_to_impl_) | 596 if (!copy_texture_to_impl_) |
| 646 copy_texture_to_impl_.reset( | 597 copy_texture_to_impl_.reset( |
| 647 new CopyTextureToImpl(context_, context_support_, this)); | 598 new CopyTextureToImpl(gl_, context_support_, this)); |
| 648 } | 599 } |
| 649 | 600 |
| 650 void GLHelper::InitScalerImpl() { | 601 void GLHelper::InitScalerImpl() { |
| 651 // Lazily initialize |scaler_impl_| | 602 // Lazily initialize |scaler_impl_| |
| 652 if (!scaler_impl_) | 603 if (!scaler_impl_) |
| 653 scaler_impl_.reset(new GLHelperScaling(context_, this)); | 604 scaler_impl_.reset(new GLHelperScaling(gl_, this)); |
| 654 } | 605 } |
| 655 | 606 |
| 656 blink::WGC3Dint GLHelper::MaxDrawBuffers() { | 607 GLint GLHelper::MaxDrawBuffers() { |
| 657 InitCopyTextToImpl(); | 608 InitCopyTextToImpl(); |
| 658 return copy_texture_to_impl_->MaxDrawBuffers(); | 609 return copy_texture_to_impl_->MaxDrawBuffers(); |
| 659 } | 610 } |
| 660 | 611 |
| 661 void GLHelper::CopySubBufferDamage(blink::WebGLId texture, | 612 void GLHelper::CopySubBufferDamage(GLuint texture, |
| 662 blink::WebGLId previous_texture, | 613 GLuint previous_texture, |
| 663 const SkRegion& new_damage, | 614 const SkRegion& new_damage, |
| 664 const SkRegion& old_damage) { | 615 const SkRegion& old_damage) { |
| 665 SkRegion region(old_damage); | 616 SkRegion region(old_damage); |
| 666 if (region.op(new_damage, SkRegion::kDifference_Op)) { | 617 if (region.op(new_damage, SkRegion::kDifference_Op)) { |
| 667 ScopedFramebuffer dst_framebuffer(context_, | 618 ScopedFramebuffer dst_framebuffer(gl_); |
| 668 context_->createFramebuffer()); | 619 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 669 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_, | |
| 670 dst_framebuffer); | 620 dst_framebuffer); |
| 671 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 621 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 672 context_->framebufferTexture2D(GL_FRAMEBUFFER, | 622 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| 673 GL_COLOR_ATTACHMENT0, | 623 GL_COLOR_ATTACHMENT0, |
| 674 GL_TEXTURE_2D, | 624 GL_TEXTURE_2D, |
| 675 previous_texture, | 625 previous_texture, |
| 676 0); | 626 0); |
| 677 for (SkRegion::Iterator it(region); !it.done(); it.next()) { | 627 for (SkRegion::Iterator it(region); !it.done(); it.next()) { |
| 678 const SkIRect& rect = it.rect(); | 628 const SkIRect& rect = it.rect(); |
| 679 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0, | 629 gl_->CopyTexSubImage2D(GL_TEXTURE_2D, |
| 680 rect.x(), rect.y(), | 630 0, |
| 681 rect.x(), rect.y(), | 631 rect.x(), |
| 682 rect.width(), rect.height()); | 632 rect.y(), |
| 633 rect.x(), | |
| 634 rect.y(), | |
| 635 rect.width(), | |
| 636 rect.height()); | |
| 683 } | 637 } |
| 684 context_->flush(); | 638 gl_->Flush(); |
| 685 } | 639 } |
| 686 } | 640 } |
| 687 | 641 |
| 688 blink::WebGLId GLHelper::CreateTexture() { | 642 GLuint GLHelper::CreateTexture() { |
| 689 blink::WebGLId texture = context_->createTexture(); | 643 GLuint texture = 0u; |
| 690 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, | 644 gl_->GenTextures(1, &texture); |
| 691 texture); | 645 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 692 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 646 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 693 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 647 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 694 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 648 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 695 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 649 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 696 return texture; | 650 return texture; |
| 697 } | 651 } |
| 698 | 652 |
| 699 void GLHelper::DeleteTexture(blink::WebGLId texture_id) { | 653 void GLHelper::DeleteTexture(GLuint texture_id) { |
| 700 context_->deleteTexture(texture_id); | 654 gl_->DeleteTextures(1, &texture_id); |
| 701 } | 655 } |
| 702 | 656 |
| 703 uint32 GLHelper::InsertSyncPoint() { return context_->insertSyncPoint(); } | 657 uint32 GLHelper::InsertSyncPoint() { return gl_->InsertSyncPointCHROMIUM(); } |
| 704 | 658 |
| 705 void GLHelper::WaitSyncPoint(uint32 sync_point) { | 659 void GLHelper::WaitSyncPoint(uint32 sync_point) { |
| 706 context_->waitSyncPoint(sync_point); | 660 gl_->WaitSyncPointCHROMIUM(sync_point); |
| 707 } | 661 } |
| 708 | 662 |
| 709 gpu::Mailbox GLHelper::ProduceMailboxFromTexture(blink::WebGLId texture_id, | 663 gpu::Mailbox GLHelper::ProduceMailboxFromTexture(GLuint texture_id, |
| 710 uint32* sync_point) { | 664 uint32* sync_point) { |
| 711 gpu::Mailbox mailbox; | 665 gpu::Mailbox mailbox; |
| 712 context_->genMailboxCHROMIUM(mailbox.name); | 666 gl_->GenMailboxCHROMIUM(mailbox.name); |
| 713 if (mailbox.IsZero()) { | 667 if (mailbox.IsZero()) { |
| 714 *sync_point = 0; | 668 *sync_point = 0; |
| 715 return mailbox; | 669 return mailbox; |
| 716 } | 670 } |
| 717 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, | 671 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture_id); |
| 718 texture_id); | 672 gl_->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
| 719 context_->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | 673 *sync_point = InsertSyncPoint(); |
| 720 *sync_point = context_->insertSyncPoint(); | |
| 721 return mailbox; | 674 return mailbox; |
| 722 } | 675 } |
| 723 | 676 |
| 724 blink::WebGLId GLHelper::ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, | 677 GLuint GLHelper::ConsumeMailboxToTexture(const gpu::Mailbox& mailbox, |
| 725 uint32 sync_point) { | 678 uint32 sync_point) { |
| 726 if (mailbox.IsZero()) | 679 if (mailbox.IsZero()) |
| 727 return 0; | 680 return 0; |
| 728 if (sync_point) | 681 if (sync_point) |
| 729 context_->waitSyncPoint(sync_point); | 682 WaitSyncPoint(sync_point); |
| 730 blink::WebGLId texture = CreateTexture(); | 683 GLuint texture = CreateTexture(); |
| 731 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, | 684 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 732 texture); | 685 gl_->ConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
| 733 context_->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | |
| 734 return texture; | 686 return texture; |
| 735 } | 687 } |
| 736 | 688 |
| 737 void GLHelper::ResizeTexture(blink::WebGLId texture, const gfx::Size& size) { | 689 void GLHelper::ResizeTexture(GLuint texture, const gfx::Size& size) { |
| 738 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 690 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 739 context_->texImage2D(GL_TEXTURE_2D, 0, GL_RGB, | 691 gl_->TexImage2D(GL_TEXTURE_2D, |
| 740 size.width(), size.height(), 0, | 692 0, |
| 741 GL_RGB, GL_UNSIGNED_BYTE, NULL); | 693 GL_RGB, |
| 694 size.width(), | |
| 695 size.height(), | |
| 696 0, | |
| 697 GL_RGB, | |
| 698 GL_UNSIGNED_BYTE, | |
| 699 NULL); | |
| 742 } | 700 } |
| 743 | 701 |
| 744 void GLHelper::CopyTextureSubImage(blink::WebGLId texture, | 702 void GLHelper::CopyTextureSubImage(GLuint texture, const gfx::Rect& rect) { |
| 745 const gfx::Rect& rect) { | 703 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 746 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 704 gl_->CopyTexSubImage2D(GL_TEXTURE_2D, |
| 747 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0, | 705 0, |
| 748 rect.x(), rect.y(), | 706 rect.x(), |
| 749 rect.x(), rect.y(), rect.width(), rect.height()); | 707 rect.y(), |
| 708 rect.x(), | |
| 709 rect.y(), | |
| 710 rect.width(), | |
| 711 rect.height()); | |
| 750 } | 712 } |
| 751 | 713 |
| 752 void GLHelper::CopyTextureFullImage(blink::WebGLId texture, | 714 void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { |
| 753 const gfx::Size& size) { | 715 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 754 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); | 716 gl_->CopyTexImage2D( |
| 755 context_->copyTexImage2D(GL_TEXTURE_2D, 0, | 717 GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0); |
| 756 GL_RGB, | |
| 757 0, 0, | |
| 758 size.width(), size.height(), 0); | |
| 759 } | 718 } |
| 760 | 719 |
| 761 void GLHelper::CopyTextureToImpl::ReadbackPlane( | 720 void GLHelper::CopyTextureToImpl::ReadbackPlane( |
| 762 TextureFrameBufferPair* source, | 721 TextureFrameBufferPair* source, |
| 763 const scoped_refptr<media::VideoFrame>& target, | 722 const scoped_refptr<media::VideoFrame>& target, |
| 764 int plane, | 723 int plane, |
| 765 int size_shift, | 724 int size_shift, |
| 766 const gfx::Rect& dst_subrect, | 725 const gfx::Rect& dst_subrect, |
| 767 const base::Callback<void(bool)>& callback) { | 726 const base::Callback<void(bool)>& callback) { |
| 768 context_->bindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); | 727 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); |
| 769 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + | 728 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + |
| 770 (dst_subrect.x() >> size_shift); | 729 (dst_subrect.x() >> size_shift); |
| 771 ReadbackAsync( | 730 ReadbackAsync(source->size(), |
| 772 source->size(), | 731 dst_subrect.width() >> size_shift, |
| 773 dst_subrect.width() >> size_shift, | 732 target->stride(plane), |
| 774 target->stride(plane), | 733 target->data(plane) + offset, |
| 775 target->data(plane) + offset, | 734 callback); |
| 776 callback); | |
| 777 } | 735 } |
| 778 | 736 |
| 779 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { | 737 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { |
| 780 0.257f, 0.504f, 0.098f, 0.0625f | 738 0.257f, 0.504f, 0.098f, 0.0625f}; |
| 781 }; | |
| 782 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { | 739 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
| 783 -0.148f, -0.291f, 0.439f, 0.5f | 740 -0.148f, -0.291f, 0.439f, 0.5f}; |
| 784 }; | |
| 785 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { | 741 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
| 786 0.439f, -0.368f, -0.071f, 0.5f | 742 0.439f, -0.368f, -0.071f, 0.5f}; |
| 787 }; | |
| 788 | 743 |
| 789 // YUV readback constructors. Initiates the main scaler pipeline and | 744 // YUV readback constructors. Initiates the main scaler pipeline and |
| 790 // one planar scaler for each of the Y, U and V planes. | 745 // one planar scaler for each of the Y, U and V planes. |
| 791 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl( | 746 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl( |
| 792 WebGraphicsContext3D* context, | 747 GLES2Interface* gl, |
| 793 CopyTextureToImpl* copy_impl, | 748 CopyTextureToImpl* copy_impl, |
| 794 GLHelperScaling* scaler_impl, | 749 GLHelperScaling* scaler_impl, |
| 795 GLHelper::ScalerQuality quality, | 750 GLHelper::ScalerQuality quality, |
| 796 const gfx::Size& src_size, | 751 const gfx::Size& src_size, |
| 797 const gfx::Rect& src_subrect, | 752 const gfx::Rect& src_subrect, |
| 798 const gfx::Size& dst_size, | 753 const gfx::Size& dst_size, |
| 799 const gfx::Rect& dst_subrect, | 754 const gfx::Rect& dst_subrect, |
| 800 bool flip_vertically) | 755 bool flip_vertically) |
| 801 : context_(context), | 756 : gl_(gl), |
| 802 copy_impl_(copy_impl), | 757 copy_impl_(copy_impl), |
| 803 dst_size_(dst_size), | 758 dst_size_(dst_size), |
| 804 dst_subrect_(dst_subrect), | 759 dst_subrect_(dst_subrect), |
| 805 scaler_(context, scaler_impl->CreateScaler( | 760 scaler_(gl, |
| 806 quality, | 761 scaler_impl->CreateScaler(quality, |
| 807 src_size, | 762 src_size, |
| 808 src_subrect, | 763 src_subrect, |
| 809 dst_subrect.size(), | 764 dst_subrect.size(), |
| 810 flip_vertically, | 765 flip_vertically, |
| 811 false)), | 766 false)), |
| 812 y_(context, scaler_impl->CreatePlanarScaler( | 767 y_(gl, |
| 813 dst_subrect.size(), | 768 scaler_impl->CreatePlanarScaler( |
| 814 gfx::Rect(0, 0, | 769 dst_subrect.size(), |
| 815 (dst_subrect.width() + 3) & ~3, | 770 gfx::Rect(0, |
| 816 dst_subrect.height()), | 771 0, |
| 817 gfx::Size((dst_subrect.width() + 3) / 4, | 772 (dst_subrect.width() + 3) & ~3, |
| 818 dst_subrect.height()), | 773 dst_subrect.height()), |
| 819 false, | 774 gfx::Size((dst_subrect.width() + 3) / 4, dst_subrect.height()), |
| 820 kRGBtoYColorWeights)), | 775 false, |
| 821 u_(context, scaler_impl->CreatePlanarScaler( | 776 kRGBtoYColorWeights)), |
| 822 dst_subrect.size(), | 777 u_(gl, |
| 823 gfx::Rect(0, 0, | 778 scaler_impl->CreatePlanarScaler( |
| 824 (dst_subrect.width() + 7) & ~7, | 779 dst_subrect.size(), |
| 825 (dst_subrect.height() + 1) & ~1), | 780 gfx::Rect(0, |
| 826 gfx::Size((dst_subrect.width() + 7) / 8, | 781 0, |
| 827 (dst_subrect.height() + 1) / 2), | 782 (dst_subrect.width() + 7) & ~7, |
| 828 false, | 783 (dst_subrect.height() + 1) & ~1), |
| 829 kRGBtoUColorWeights)), | 784 gfx::Size((dst_subrect.width() + 7) / 8, |
| 830 v_(context, scaler_impl->CreatePlanarScaler( | 785 (dst_subrect.height() + 1) / 2), |
| 831 dst_subrect.size(), | 786 false, |
| 832 gfx::Rect(0, 0, | 787 kRGBtoUColorWeights)), |
| 833 (dst_subrect.width() + 7) & ~7, | 788 v_(gl, |
| 834 (dst_subrect.height() + 1) & ~1), | 789 scaler_impl->CreatePlanarScaler( |
| 835 gfx::Size((dst_subrect.width() + 7) / 8, | 790 dst_subrect.size(), |
| 836 (dst_subrect.height() + 1) / 2), | 791 gfx::Rect(0, |
| 837 false, | 792 0, |
| 838 kRGBtoVColorWeights)) { | 793 (dst_subrect.width() + 7) & ~7, |
| 794 (dst_subrect.height() + 1) & ~1), | |
| 795 gfx::Size((dst_subrect.width() + 7) / 8, | |
| 796 (dst_subrect.height() + 1) / 2), | |
| 797 false, | |
| 798 kRGBtoVColorWeights)) { | |
| 839 DCHECK(!(dst_size.width() & 1)); | 799 DCHECK(!(dst_size.width() & 1)); |
| 840 DCHECK(!(dst_size.height() & 1)); | 800 DCHECK(!(dst_size.height() & 1)); |
| 841 DCHECK(!(dst_subrect.width() & 1)); | 801 DCHECK(!(dst_subrect.width() & 1)); |
| 842 DCHECK(!(dst_subrect.height() & 1)); | 802 DCHECK(!(dst_subrect.height() & 1)); |
| 843 DCHECK(!(dst_subrect.x() & 1)); | 803 DCHECK(!(dst_subrect.x() & 1)); |
| 844 DCHECK(!(dst_subrect.y() & 1)); | 804 DCHECK(!(dst_subrect.y() & 1)); |
| 845 } | 805 } |
| 846 | 806 |
| 847 static void CallbackKeepingVideoFrameAlive( | 807 static void CallbackKeepingVideoFrameAlive( |
| 848 scoped_refptr<media::VideoFrame> video_frame, | 808 scoped_refptr<media::VideoFrame> video_frame, |
| 849 const base::Callback<void(bool)>& callback, | 809 const base::Callback<void(bool)>& callback, |
| 850 bool success) { | 810 bool success) { |
| 851 callback.Run(success); | 811 callback.Run(success); |
| 852 } | 812 } |
| 853 | 813 |
| 854 void GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUV( | 814 void GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUV( |
| 855 const gpu::Mailbox& mailbox, | 815 const gpu::Mailbox& mailbox, |
| 856 uint32 sync_point, | 816 uint32 sync_point, |
| 857 const scoped_refptr<media::VideoFrame>& target, | 817 const scoped_refptr<media::VideoFrame>& target, |
| 858 const base::Callback<void(bool)>& callback) { | 818 const base::Callback<void(bool)>& callback) { |
| 859 WebGLId mailbox_texture = | 819 GLuint mailbox_texture = |
| 860 copy_impl_->ConsumeMailboxToTexture(mailbox, sync_point); | 820 copy_impl_->ConsumeMailboxToTexture(mailbox, sync_point); |
| 861 | 821 |
| 862 // Scale texture to right size. | 822 // Scale texture to right size. |
| 863 scaler_.Scale(mailbox_texture); | 823 scaler_.Scale(mailbox_texture); |
| 864 context_->deleteTexture(mailbox_texture); | 824 gl_->DeleteTextures(1, &mailbox_texture); |
| 865 | 825 |
| 866 // Convert the scaled texture in to Y, U and V planes. | 826 // Convert the scaled texture in to Y, U and V planes. |
| 867 y_.Scale(scaler_.texture()); | 827 y_.Scale(scaler_.texture()); |
| 868 u_.Scale(scaler_.texture()); | 828 u_.Scale(scaler_.texture()); |
| 869 v_.Scale(scaler_.texture()); | 829 v_.Scale(scaler_.texture()); |
| 870 | 830 |
| 871 if (target->coded_size() != dst_size_) { | 831 if (target->coded_size() != dst_size_) { |
| 872 DCHECK(target->coded_size() == dst_size_); | 832 DCHECK(target->coded_size() == dst_size_); |
| 873 LOG(ERROR) << "ReadbackYUV size error!"; | 833 LOG(ERROR) << "ReadbackYUV size error!"; |
| 874 callback.Run(false); | 834 callback.Run(false); |
| 875 return; | 835 return; |
| 876 } | 836 } |
| 877 | 837 |
| 878 // Read back planes, one at a time. Keep the video frame alive while doing the | 838 // Read back planes, one at a time. Keep the video frame alive while doing the |
| 879 // readback. | 839 // readback. |
| 880 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), | 840 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), |
| 881 target, | 841 target, |
| 882 media::VideoFrame::kYPlane, | 842 media::VideoFrame::kYPlane, |
| 883 0, | 843 0, |
| 884 dst_subrect_, | 844 dst_subrect_, |
| 885 base::Bind(&nullcallback)); | 845 base::Bind(&nullcallback)); |
| 886 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), | 846 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), |
| 887 target, | 847 target, |
| 888 media::VideoFrame::kUPlane, | 848 media::VideoFrame::kUPlane, |
| 889 1, | 849 1, |
| 890 dst_subrect_, | 850 dst_subrect_, |
| 891 base::Bind(&nullcallback)); | 851 base::Bind(&nullcallback)); |
| 892 copy_impl_->ReadbackPlane(v_.texture_and_framebuffer(), | 852 copy_impl_->ReadbackPlane( |
| 893 target, | 853 v_.texture_and_framebuffer(), |
| 894 media::VideoFrame::kVPlane, | 854 target, |
| 895 1, | 855 media::VideoFrame::kVPlane, |
| 896 dst_subrect_, | 856 1, |
| 897 base::Bind(&CallbackKeepingVideoFrameAlive, | 857 dst_subrect_, |
| 898 target, | 858 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
| 899 callback)); | 859 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
| 900 context_->bindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 901 media::LetterboxYUV(target, dst_subrect_); | 860 media::LetterboxYUV(target, dst_subrect_); |
| 902 } | 861 } |
| 903 | 862 |
| 904 // YUV readback constructors. Initiates the main scaler pipeline and | 863 // YUV readback constructors. Initiates the main scaler pipeline and |
| 905 // one planar scaler for each of the Y, U and V planes. | 864 // one planar scaler for each of the Y, U and V planes. |
| 906 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( | 865 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( |
| 907 WebGraphicsContext3D* context, | 866 GLES2Interface* gl, |
| 908 CopyTextureToImpl* copy_impl, | 867 CopyTextureToImpl* copy_impl, |
| 909 GLHelperScaling* scaler_impl, | 868 GLHelperScaling* scaler_impl, |
| 910 GLHelper::ScalerQuality quality, | 869 GLHelper::ScalerQuality quality, |
| 911 const gfx::Size& src_size, | 870 const gfx::Size& src_size, |
| 912 const gfx::Rect& src_subrect, | 871 const gfx::Rect& src_subrect, |
| 913 const gfx::Size& dst_size, | 872 const gfx::Size& dst_size, |
| 914 const gfx::Rect& dst_subrect, | 873 const gfx::Rect& dst_subrect, |
| 915 bool flip_vertically) | 874 bool flip_vertically) |
| 916 : context_(context), | 875 : gl_(gl), |
| 917 copy_impl_(copy_impl), | 876 copy_impl_(copy_impl), |
| 918 dst_size_(dst_size), | 877 dst_size_(dst_size), |
| 919 dst_subrect_(dst_subrect), | 878 dst_subrect_(dst_subrect), |
| 920 quality_(quality), | 879 quality_(quality), |
| 921 scaler_(context, scaler_impl->CreateScaler( | 880 scaler_(gl, |
| 922 quality, | 881 scaler_impl->CreateScaler(quality, |
| 923 src_size, | 882 src_size, |
| 924 src_subrect, | 883 src_subrect, |
| 925 dst_subrect.size(), | 884 dst_subrect.size(), |
| 926 false, | 885 false, |
| 927 false)), | 886 false)), |
| 928 pass1_shader_(scaler_impl->CreateYuvMrtShader( | 887 pass1_shader_(scaler_impl->CreateYuvMrtShader( |
| 929 dst_subrect.size(), | 888 dst_subrect.size(), |
| 930 gfx::Rect(0, 0, | 889 gfx::Rect(0, 0, (dst_subrect.width() + 3) & ~3, dst_subrect.height()), |
| 931 (dst_subrect.width() + 3) & ~3, | 890 gfx::Size((dst_subrect.width() + 3) / 4, dst_subrect.height()), |
| 932 dst_subrect.height()), | |
| 933 gfx::Size((dst_subrect.width() + 3) / 4, | |
| 934 dst_subrect.height()), | |
| 935 flip_vertically, | 891 flip_vertically, |
| 936 GLHelperScaling::SHADER_YUV_MRT_PASS1)), | 892 GLHelperScaling::SHADER_YUV_MRT_PASS1)), |
| 937 pass2_shader_(scaler_impl->CreateYuvMrtShader( | 893 pass2_shader_(scaler_impl->CreateYuvMrtShader( |
| 938 gfx::Size((dst_subrect.width() + 3) / 4, | 894 gfx::Size((dst_subrect.width() + 3) / 4, dst_subrect.height()), |
| 939 dst_subrect.height()), | 895 gfx::Rect(0, |
| 940 gfx::Rect(0, 0, | 896 0, |
| 941 (dst_subrect.width() + 7) / 8 * 2, | 897 (dst_subrect.width() + 7) / 8 * 2, |
| 942 dst_subrect.height()), | 898 dst_subrect.height()), |
| 943 gfx::Size((dst_subrect.width() + 7) / 8, | 899 gfx::Size((dst_subrect.width() + 7) / 8, |
| 944 (dst_subrect.height() + 1) / 2), | 900 (dst_subrect.height() + 1) / 2), |
| 945 false, | 901 false, |
| 946 GLHelperScaling::SHADER_YUV_MRT_PASS2)), | 902 GLHelperScaling::SHADER_YUV_MRT_PASS2)), |
| 947 y_(context, gfx::Size((dst_subrect.width() + 3) / 4, | 903 y_(gl, gfx::Size((dst_subrect.width() + 3) / 4, dst_subrect.height())), |
| 948 dst_subrect.height())), | 904 uv_(gl), |
| 949 uv_(context, context->createTexture()), | 905 u_(gl, |
| 950 u_(context, gfx::Size((dst_subrect.width() + 7) / 8, | 906 gfx::Size((dst_subrect.width() + 7) / 8, |
| 951 (dst_subrect.height() + 1) / 2)), | 907 (dst_subrect.height() + 1) / 2)), |
| 952 v_(context, gfx::Size((dst_subrect.width() + 7) / 8, | 908 v_(gl, |
| 953 (dst_subrect.height() + 1) / 2)) { | 909 gfx::Size((dst_subrect.width() + 7) / 8, |
| 910 (dst_subrect.height() + 1) / 2)) { | |
| 954 | 911 |
| 955 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context, uv_); | 912 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, uv_); |
| 956 context->texImage2D(GL_TEXTURE_2D, | 913 gl->TexImage2D(GL_TEXTURE_2D, |
| 957 0, | 914 0, |
| 958 GL_RGBA, | 915 GL_RGBA, |
| 959 (dst_subrect.width() + 3) / 4, | 916 (dst_subrect.width() + 3) / 4, |
| 960 dst_subrect.height(), | 917 dst_subrect.height(), |
| 961 0, | 918 0, |
| 962 GL_RGBA, | 919 GL_RGBA, |
| 963 GL_UNSIGNED_BYTE, | 920 GL_UNSIGNED_BYTE, |
| 964 NULL); | 921 NULL); |
| 965 | 922 |
| 966 DCHECK(!(dst_size.width() & 1)); | 923 DCHECK(!(dst_size.width() & 1)); |
| 967 DCHECK(!(dst_size.height() & 1)); | 924 DCHECK(!(dst_size.height() & 1)); |
| 968 DCHECK(!(dst_subrect.width() & 1)); | 925 DCHECK(!(dst_subrect.width() & 1)); |
| 969 DCHECK(!(dst_subrect.height() & 1)); | 926 DCHECK(!(dst_subrect.height() & 1)); |
| 970 DCHECK(!(dst_subrect.x() & 1)); | 927 DCHECK(!(dst_subrect.x() & 1)); |
| 971 DCHECK(!(dst_subrect.y() & 1)); | 928 DCHECK(!(dst_subrect.y() & 1)); |
| 972 } | 929 } |
| 973 | 930 |
| 974 void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV( | 931 void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV( |
| 975 const gpu::Mailbox& mailbox, | 932 const gpu::Mailbox& mailbox, |
| 976 uint32 sync_point, | 933 uint32 sync_point, |
| 977 const scoped_refptr<media::VideoFrame>& target, | 934 const scoped_refptr<media::VideoFrame>& target, |
| 978 const base::Callback<void(bool)>& callback) { | 935 const base::Callback<void(bool)>& callback) { |
| 979 WebGLId mailbox_texture = | 936 GLuint mailbox_texture = |
| 980 copy_impl_->ConsumeMailboxToTexture(mailbox, sync_point); | 937 copy_impl_->ConsumeMailboxToTexture(mailbox, sync_point); |
| 981 | 938 |
| 982 WebGLId texture; | 939 GLuint texture; |
| 983 if (quality_ == GLHelper::SCALER_QUALITY_FAST) { | 940 if (quality_ == GLHelper::SCALER_QUALITY_FAST) { |
| 984 // Optimization: SCALER_QUALITY_FAST is just a single bilinear | 941 // Optimization: SCALER_QUALITY_FAST is just a single bilinear |
| 985 // pass, which pass1_shader_ can do just as well, so let's skip | 942 // pass, which pass1_shader_ can do just as well, so let's skip |
| 986 // the actual scaling in that case. | 943 // the actual scaling in that case. |
| 987 texture = mailbox_texture; | 944 texture = mailbox_texture; |
| 988 } else { | 945 } else { |
| 989 // Scale texture to right size. | 946 // Scale texture to right size. |
| 990 scaler_.Scale(mailbox_texture); | 947 scaler_.Scale(mailbox_texture); |
| 991 texture = scaler_.texture(); | 948 texture = scaler_.texture(); |
| 992 } | 949 } |
| 993 | 950 |
| 994 | 951 std::vector<GLuint> outputs(2); |
| 995 std::vector<blink::WebGLId> outputs(2); | |
| 996 // Convert the scaled texture in to Y, U and V planes. | 952 // Convert the scaled texture in to Y, U and V planes. |
| 997 outputs[0] = y_.texture(); | 953 outputs[0] = y_.texture(); |
| 998 outputs[1] = uv_; | 954 outputs[1] = uv_; |
| 999 pass1_shader_->Execute(texture, outputs); | 955 pass1_shader_->Execute(texture, outputs); |
| 1000 | 956 |
| 1001 context_->deleteTexture(mailbox_texture); | 957 gl_->DeleteTextures(1, &mailbox_texture); |
| 1002 | 958 |
| 1003 outputs[0] = u_.texture(); | 959 outputs[0] = u_.texture(); |
| 1004 outputs[1] = v_.texture(); | 960 outputs[1] = v_.texture(); |
| 1005 pass2_shader_->Execute(uv_, outputs); | 961 pass2_shader_->Execute(uv_, outputs); |
| 1006 | 962 |
| 1007 if (target->coded_size() != dst_size_) { | 963 if (target->coded_size() != dst_size_) { |
| 1008 DCHECK(target->coded_size() == dst_size_); | 964 DCHECK(target->coded_size() == dst_size_); |
| 1009 LOG(ERROR) << "ReadbackYUV size error!"; | 965 LOG(ERROR) << "ReadbackYUV size error!"; |
| 1010 callback.Run(false); | 966 callback.Run(false); |
| 1011 return; | 967 return; |
| 1012 } | 968 } |
| 1013 | 969 |
| 1014 // Read back planes, one at a time. | 970 // Read back planes, one at a time. |
| 1015 copy_impl_->ReadbackPlane(&y_, | 971 copy_impl_->ReadbackPlane(&y_, |
| 1016 target, | 972 target, |
| 1017 media::VideoFrame::kYPlane, | 973 media::VideoFrame::kYPlane, |
| 1018 0, | 974 0, |
| 1019 dst_subrect_, | 975 dst_subrect_, |
| 1020 base::Bind(&nullcallback)); | 976 base::Bind(&nullcallback)); |
| 1021 copy_impl_->ReadbackPlane(&u_, | 977 copy_impl_->ReadbackPlane(&u_, |
| 1022 target, | 978 target, |
| 1023 media::VideoFrame::kUPlane, | 979 media::VideoFrame::kUPlane, |
| 1024 1, | 980 1, |
| 1025 dst_subrect_, | 981 dst_subrect_, |
| 1026 base::Bind(&nullcallback)); | 982 base::Bind(&nullcallback)); |
| 1027 copy_impl_->ReadbackPlane(&v_, | 983 copy_impl_->ReadbackPlane( |
| 1028 target, | 984 &v_, |
| 1029 media::VideoFrame::kVPlane, | 985 target, |
| 1030 1, | 986 media::VideoFrame::kVPlane, |
| 1031 dst_subrect_, | 987 1, |
| 1032 base::Bind(&CallbackKeepingVideoFrameAlive, | 988 dst_subrect_, |
| 1033 target, | 989 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
| 1034 callback)); | 990 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
| 1035 context_->bindFramebuffer(GL_FRAMEBUFFER, 0); | |
| 1036 media::LetterboxYUV(target, dst_subrect_); | 991 media::LetterboxYUV(target, dst_subrect_); |
| 1037 } | 992 } |
| 1038 | 993 |
| 1039 ReadbackYUVInterface* | 994 ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( |
| 1040 GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( | |
| 1041 GLHelper::ScalerQuality quality, | 995 GLHelper::ScalerQuality quality, |
| 1042 const gfx::Size& src_size, | 996 const gfx::Size& src_size, |
| 1043 const gfx::Rect& src_subrect, | 997 const gfx::Rect& src_subrect, |
| 1044 const gfx::Size& dst_size, | 998 const gfx::Size& dst_size, |
| 1045 const gfx::Rect& dst_subrect, | 999 const gfx::Rect& dst_subrect, |
| 1046 bool flip_vertically, | 1000 bool flip_vertically, |
| 1047 bool use_mrt) { | 1001 bool use_mrt) { |
| 1048 helper_->InitScalerImpl(); | 1002 helper_->InitScalerImpl(); |
| 1049 if (max_draw_buffers_ >= 2 && use_mrt) { | 1003 if (max_draw_buffers_ >= 2 && use_mrt) { |
| 1050 return new ReadbackYUV_MRT( | 1004 return new ReadbackYUV_MRT(gl_, |
| 1051 context_, | 1005 this, |
| 1052 this, | 1006 helper_->scaler_impl_.get(), |
| 1053 helper_->scaler_impl_.get(), | 1007 quality, |
| 1054 quality, | 1008 src_size, |
| 1055 src_size, | 1009 src_subrect, |
| 1056 src_subrect, | 1010 dst_size, |
| 1057 dst_size, | 1011 dst_subrect, |
| 1058 dst_subrect, | 1012 flip_vertically); |
| 1059 flip_vertically); | |
| 1060 } | 1013 } |
| 1061 return new ReadbackYUVImpl( | 1014 return new ReadbackYUVImpl(gl_, |
| 1062 context_, | 1015 this, |
| 1063 this, | 1016 helper_->scaler_impl_.get(), |
| 1064 helper_->scaler_impl_.get(), | 1017 quality, |
| 1065 quality, | 1018 src_size, |
| 1066 src_size, | 1019 src_subrect, |
| 1067 src_subrect, | 1020 dst_size, |
| 1068 dst_size, | 1021 dst_subrect, |
| 1069 dst_subrect, | 1022 flip_vertically); |
| 1070 flip_vertically); | |
| 1071 } | 1023 } |
| 1072 | 1024 |
| 1073 ReadbackYUVInterface* | 1025 ReadbackYUVInterface* GLHelper::CreateReadbackPipelineYUV( |
| 1074 GLHelper::CreateReadbackPipelineYUV( | |
| 1075 ScalerQuality quality, | 1026 ScalerQuality quality, |
| 1076 const gfx::Size& src_size, | 1027 const gfx::Size& src_size, |
| 1077 const gfx::Rect& src_subrect, | 1028 const gfx::Rect& src_subrect, |
| 1078 const gfx::Size& dst_size, | 1029 const gfx::Size& dst_size, |
| 1079 const gfx::Rect& dst_subrect, | 1030 const gfx::Rect& dst_subrect, |
| 1080 bool flip_vertically, | 1031 bool flip_vertically, |
| 1081 bool use_mrt) { | 1032 bool use_mrt) { |
| 1082 InitCopyTextToImpl(); | 1033 InitCopyTextToImpl(); |
| 1083 return copy_texture_to_impl_->CreateReadbackPipelineYUV( | 1034 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, |
| 1084 quality, | 1035 src_size, |
| 1085 src_size, | 1036 src_subrect, |
| 1086 src_subrect, | 1037 dst_size, |
| 1087 dst_size, | 1038 dst_subrect, |
| 1088 dst_subrect, | 1039 flip_vertically, |
| 1089 flip_vertically, | 1040 use_mrt); |
| 1090 use_mrt); | |
| 1091 } | 1041 } |
| 1092 | 1042 |
| 1093 } // namespace content | 1043 } // namespace content |
| OLD | NEW |