gl_helper.h revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Use of this source code is governed by a BSD-style license that can be
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// found in the LICENSE file.
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "base/atomicops.h"
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "base/basictypes.h"
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "base/callback.h"
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "base/memory/scoped_ptr.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "content/common/content_export.h"
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "gpu/command_buffer/client/gles2_interface.h"
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "gpu/command_buffer/common/mailbox_holder.h"
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "third_party/skia/include/core/SkBitmap.h"
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace gfx {
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Rect;
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass Size;
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace gpu {
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ContextSupport;
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstruct Mailbox;
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace media {
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass VideoFrame;
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass SkRegion;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace content {
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass GLHelperScaling;
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedGLuint {
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids);
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n,
41471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org                                                         const GLuint* ids);
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ScopedGLuint(gpu::gles2::GLES2Interface* gl,
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               GenFunc gen_func,
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org               DeleteFunc delete_func)
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : gl_(gl), id_(0u), delete_func_(delete_func) {
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    (gl_->*gen_func)(1, &id_);
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  operator GLuint() const { return id_; }
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  GLuint id() const { return id_; }
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ~ScopedGLuint() {
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (id_ != 0) {
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      (gl_->*delete_func_)(1, &id_);
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private:
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  gpu::gles2::GLES2Interface* gl_;
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  GLuint id_;
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DeleteFunc delete_func_;
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DISALLOW_COPY_AND_ASSIGN(ScopedGLuint);
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedBuffer : public ScopedGLuint {
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl)
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedGLuint(gl,
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::GenBuffers,
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::DeleteBuffers) {}
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedFramebuffer : public ScopedGLuint {
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl)
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedGLuint(gl,
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::GenFramebuffers,
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::DeleteFramebuffers) {}
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedTexture : public ScopedGLuint {
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  explicit ScopedTexture(gpu::gles2::GLES2Interface* gl)
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedGLuint(gl,
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::GenTextures,
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                     &gpu::gles2::GLES2Interface::DeleteTextures) {}
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtemplate <GLenum Target>
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedBinder {
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target,
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                       GLuint id);
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func)
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : gl_(gl), bind_func_(bind_func) {
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    (gl_->*bind_func_)(Target, id);
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); }
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org private:
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  gpu::gles2::GLES2Interface* gl_;
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  BindFunc bind_func_;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtemplate <GLenum Target>
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedBufferBinder : ScopedBinder<Target> {
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {}
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtemplate <GLenum Target>
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedFramebufferBinder : ScopedBinder<Target> {
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedBinder<Target>(gl,
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             id,
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                             &gpu::gles2::GLES2Interface::BindFramebuffer) {}
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtemplate <GLenum Target>
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ScopedTextureBinder : ScopedBinder<Target> {
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) {
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass ReadbackYUVInterface;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass GLHelperReadbackSupport;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1377f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org// Provides higher level operations on top of the gpu::gles2::GLES2Interface
1387f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org// interfaces.
1397f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.orgclass CONTENT_EXPORT GLHelper {
1407f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org public:
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  GLHelper(gpu::gles2::GLES2Interface* gl,
1427f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org           gpu::ContextSupport* context_support);
1437f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org  ~GLHelper();
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1457f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org  enum ScalerQuality {
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Bilinear single pass, fastest possible.
1477f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org    SCALER_QUALITY_FAST = 1,
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1497f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org    // Bilinear upscale + N * 50% bilinear downscales.
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // This is still fast enough for most purposes and
1517f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org    // Image quality is nearly as good as the BEST option.
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SCALER_QUALITY_GOOD = 2,
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1547f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org    // Bicubic upscale + N * 50% bicubic downscales.
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Produces very good quality scaled images, but it's
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // 2-8x slower than the "GOOD" quality, so it's not always
1577f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org    // worth it.
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    SCALER_QUALITY_BEST = 3,
1597f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org  };
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1617f5e2973967c6ef5859334eb4ccac2c7c0020565henrika@webrtc.org  // Copies the block of pixels specified with |src_subrect| from |src_texture|,
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // scales it to |dst_size|, and writes it into |out|.
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // |src_size| is the size of |src_texture|. The result is of format GL_BGRA
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // and is potentially flipped vertically to make it a correct image
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // representation.  |callback| is invoked with the copy result when the copy
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // operation has completed.
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  void CropScaleReadbackAndCleanTexture(
170      GLuint src_texture,
171      const gfx::Size& src_size,
172      const gfx::Rect& src_subrect,
173      const gfx::Size& dst_size,
174      unsigned char* out,
175      const SkBitmap::Config config,
176      const base::Callback<void(bool)>& callback,
177      GLHelper::ScalerQuality quality);
178
179  // Copies the block of pixels specified with |src_subrect| from |src_mailbox|,
180  // scales it to |dst_size|, and writes it into |out|.
181  // |src_size| is the size of |src_mailbox|. The result is of format GL_BGRA
182  // and is potentially flipped vertically to make it a correct image
183  // representation.  |callback| is invoked with the copy result when the copy
184  // operation has completed.
185  // Note that the texture bound to src_mailbox will have the min/mag filter set
186  // to GL_LINEAR and wrap_s/t set to CLAMP_TO_EDGE in this call. src_mailbox is
187  // assumed to be GL_TEXTURE_2D.
188  void CropScaleReadbackAndCleanMailbox(
189      const gpu::Mailbox& src_mailbox,
190      uint32 sync_point,
191      const gfx::Size& src_size,
192      const gfx::Rect& src_subrect,
193      const gfx::Size& dst_size,
194      unsigned char* out,
195      const SkBitmap::Config config,
196      const base::Callback<void(bool)>& callback,
197      GLHelper::ScalerQuality quality);
198
199  // Copies the texture data out of |texture| into |out|.  |size| is the
200  // size of the texture.  No post processing is applied to the pixels.  The
201  // texture is assumed to have a format of GL_RGBA with a pixel type of
202  // GL_UNSIGNED_BYTE.  This is a blocking call that calls glReadPixels on the
203  // current OpenGL context.
204  void ReadbackTextureSync(GLuint texture,
205                           const gfx::Rect& src_rect,
206                           unsigned char* out,
207                           SkBitmap::Config format);
208
209  void ReadbackTextureAsync(GLuint texture,
210                            const gfx::Size& dst_size,
211                            unsigned char* out,
212                            SkBitmap::Config config,
213                            const base::Callback<void(bool)>& callback);
214
215  // Creates a copy of the specified texture. |size| is the size of the texture.
216  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
217  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
218  GLuint CopyTexture(GLuint texture, const gfx::Size& size);
219
220  // Creates a scaled copy of the specified texture. |src_size| is the size of
221  // the texture and |dst_size| is the size of the resulting copy.
222  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
223  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
224  GLuint CopyAndScaleTexture(GLuint texture,
225                             const gfx::Size& src_size,
226                             const gfx::Size& dst_size,
227                             bool vertically_flip_texture,
228                             ScalerQuality quality);
229
230  // Returns the shader compiled from the source.
231  GLuint CompileShaderFromSource(const GLchar* source, GLenum type);
232
233  // Copies all pixels from |previous_texture| into |texture| that are
234  // inside the region covered by |old_damage| but not part of |new_damage|.
235  void CopySubBufferDamage(GLuint texture,
236                           GLuint previous_texture,
237                           const SkRegion& new_damage,
238                           const SkRegion& old_damage);
239
240  // Simply creates a texture.
241  GLuint CreateTexture();
242  // Deletes a texture.
243  void DeleteTexture(GLuint texture_id);
244
245  // Insert a sync point into the GL command buffer.
246  uint32 InsertSyncPoint();
247  // Wait for the sync point before executing further GL commands.
248  void WaitSyncPoint(uint32 sync_point);
249
250  // Creates a mailbox holder that is attached to the given texture id, with a
251  // sync point to wait on before using the mailbox. Returns a holder with an
252  // empty mailbox on failure.
253  // Note the texture is assumed to be GL_TEXTURE_2D.
254  gpu::MailboxHolder ProduceMailboxHolderFromTexture(GLuint texture_id);
255
256  // Creates a texture and consumes a mailbox into it. Returns 0 on failure.
257  // Note the mailbox is assumed to be GL_TEXTURE_2D.
258  GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
259                                 uint32 sync_point);
260
261  // Resizes the texture's size to |size|.
262  void ResizeTexture(GLuint texture, const gfx::Size& size);
263
264  // Copies the framebuffer data given in |rect| to |texture|.
265  void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect);
266
267  // Copies the all framebuffer data to |texture|. |size| specifies the
268  // size of the framebuffer.
269  void CopyTextureFullImage(GLuint texture, const gfx::Size& size);
270
271  // Flushes GL commands.
272  void Flush();
273
274
275  // A scaler will cache all intermediate textures and programs
276  // needed to scale from a specified size to a destination size.
277  // If the source or destination sizes changes, you must create
278  // a new scaler.
279  class CONTENT_EXPORT ScalerInterface {
280   public:
281    ScalerInterface() {}
282    virtual ~ScalerInterface() {}
283
284    // Note that the src_texture will have the min/mag filter set to GL_LINEAR
285    // and wrap_s/t set to CLAMP_TO_EDGE in this call.
286    virtual void Scale(GLuint source_texture, GLuint dest_texture) = 0;
287    virtual const gfx::Size& SrcSize() = 0;
288    virtual const gfx::Rect& SrcSubrect() = 0;
289    virtual const gfx::Size& DstSize() = 0;
290  };
291
292  // Note that the quality may be adjusted down if texture
293  // allocations fail or hardware doesn't support the requtested
294  // quality. Note that ScalerQuality enum is arranged in
295  // numerical order for simplicity.
296  ScalerInterface* CreateScaler(ScalerQuality quality,
297                                const gfx::Size& src_size,
298                                const gfx::Rect& src_subrect,
299                                const gfx::Size& dst_size,
300                                bool vertically_flip_texture,
301                                bool swizzle);
302
303  // Create a readback pipeline that will scale a subsection of the source
304  // texture, then convert it to YUV422 planar form and then read back that.
305  // This reduces the amount of memory read from GPU to CPU memory by a factor
306  // 2.6, which can be quite handy since readbacks have very limited speed
307  // on some platforms. All values in |dst_size| and |dst_subrect| must be
308  // a multiple of two. If |use_mrt| is true, the pipeline will try to optimize
309  // the YUV conversion using the multi-render-target extension. |use_mrt|
310  // should only be set to false for testing.
311  ReadbackYUVInterface* CreateReadbackPipelineYUV(ScalerQuality quality,
312                                                  const gfx::Size& src_size,
313                                                  const gfx::Rect& src_subrect,
314                                                  const gfx::Size& dst_size,
315                                                  const gfx::Rect& dst_subrect,
316                                                  bool flip_vertically,
317                                                  bool use_mrt);
318
319  // Returns the maximum number of draw buffers available,
320  // 0 if GL_EXT_draw_buffers is not available.
321  GLint MaxDrawBuffers();
322
323  // Checks whether the readbback is supported for texture with the
324  // matching config. This doesnt check for cross format readbacks.
325  bool IsReadbackConfigSupported(SkBitmap::Config texture_format);
326
327 protected:
328  class CopyTextureToImpl;
329
330  // Creates |copy_texture_to_impl_| if NULL.
331  void InitCopyTextToImpl();
332  // Creates |scaler_impl_| if NULL.
333  void InitScalerImpl();
334
335  enum ReadbackSwizzle {
336    kSwizzleNone = 0,
337    kSwizzleBGRA
338  };
339
340  gpu::gles2::GLES2Interface* gl_;
341  gpu::ContextSupport* context_support_;
342  scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_;
343  scoped_ptr<GLHelperScaling> scaler_impl_;
344  scoped_ptr<GLHelperReadbackSupport> readback_support_;
345
346  DISALLOW_COPY_AND_ASSIGN(GLHelper);
347};
348
349// Similar to a ScalerInterface, a yuv readback pipeline will
350// cache a scaler and all intermediate textures and frame buffers
351// needed to scale, crop, letterbox and read back a texture from
352// the GPU into CPU-accessible RAM. A single readback pipeline
353// can handle multiple outstanding readbacks at the same time, but
354// if the source or destination sizes change, you'll need to create
355// a new readback pipeline.
356class CONTENT_EXPORT ReadbackYUVInterface {
357 public:
358  ReadbackYUVInterface() {}
359  virtual ~ReadbackYUVInterface() {}
360
361  // Note that |target| must use YV12 format.
362  virtual void ReadbackYUV(const gpu::Mailbox& mailbox,
363                           uint32 sync_point,
364                           const scoped_refptr<media::VideoFrame>& target,
365                           const base::Callback<void(bool)>& callback) = 0;
366  virtual GLHelper::ScalerInterface* scaler() = 0;
367};
368
369}  // namespace content
370
371#endif  // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
372