Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: content/common/gpu/client/gl_helper.cc

Issue 117233006: Port content::GLHelper over to GLES2Interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: NULL-check gl->GetString(GL_EXTENSIONS) Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_benchmark.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_benchmark.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698