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