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 |