Apply _RELATIVE relocations ahead of others.
[chromium-blink-merge.git] / content / common / gpu / client / gl_helper.h
blobdc90ddeb1c4639c4474817bdc5e2c245539c6c7e
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
3 // found in the LICENSE file.
5 #ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
6 #define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
8 #include "base/atomicops.h"
9 #include "base/basictypes.h"
10 #include "base/callback.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "content/common/content_export.h"
13 #include "gpu/command_buffer/client/gles2_interface.h"
14 #include "gpu/command_buffer/common/mailbox_holder.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
17 namespace gfx {
18 class Rect;
19 class Size;
22 namespace gpu {
23 class ContextSupport;
24 struct Mailbox;
27 namespace media {
28 class VideoFrame;
31 class SkRegion;
33 namespace content {
35 class GLHelperScaling;
37 class ScopedGLuint {
38 public:
39 typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids);
40 typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n,
41 const GLuint* ids);
42 ScopedGLuint(gpu::gles2::GLES2Interface* gl,
43 GenFunc gen_func,
44 DeleteFunc delete_func)
45 : gl_(gl), id_(0u), delete_func_(delete_func) {
46 (gl_->*gen_func)(1, &id_);
49 operator GLuint() const { return id_; }
51 GLuint id() const { return id_; }
53 ~ScopedGLuint() {
54 if (id_ != 0) {
55 (gl_->*delete_func_)(1, &id_);
59 private:
60 gpu::gles2::GLES2Interface* gl_;
61 GLuint id_;
62 DeleteFunc delete_func_;
64 DISALLOW_COPY_AND_ASSIGN(ScopedGLuint);
67 class ScopedBuffer : public ScopedGLuint {
68 public:
69 explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl)
70 : ScopedGLuint(gl,
71 &gpu::gles2::GLES2Interface::GenBuffers,
72 &gpu::gles2::GLES2Interface::DeleteBuffers) {}
75 class ScopedFramebuffer : public ScopedGLuint {
76 public:
77 explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl)
78 : ScopedGLuint(gl,
79 &gpu::gles2::GLES2Interface::GenFramebuffers,
80 &gpu::gles2::GLES2Interface::DeleteFramebuffers) {}
83 class ScopedTexture : public ScopedGLuint {
84 public:
85 explicit ScopedTexture(gpu::gles2::GLES2Interface* gl)
86 : ScopedGLuint(gl,
87 &gpu::gles2::GLES2Interface::GenTextures,
88 &gpu::gles2::GLES2Interface::DeleteTextures) {}
91 template <GLenum Target>
92 class ScopedBinder {
93 public:
94 typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target,
95 GLuint id);
96 ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func)
97 : gl_(gl), bind_func_(bind_func) {
98 (gl_->*bind_func_)(Target, id);
101 virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); }
103 private:
104 gpu::gles2::GLES2Interface* gl_;
105 BindFunc bind_func_;
107 DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
110 template <GLenum Target>
111 class ScopedBufferBinder : ScopedBinder<Target> {
112 public:
113 ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
114 : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {}
117 template <GLenum Target>
118 class ScopedFramebufferBinder : ScopedBinder<Target> {
119 public:
120 ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
121 : ScopedBinder<Target>(gl,
123 &gpu::gles2::GLES2Interface::BindFramebuffer) {}
126 template <GLenum Target>
127 class ScopedTextureBinder : ScopedBinder<Target> {
128 public:
129 ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
130 : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) {
134 class ReadbackYUVInterface;
135 class GLHelperReadbackSupport;
137 // Provides higher level operations on top of the gpu::gles2::GLES2Interface
138 // interfaces.
139 class CONTENT_EXPORT GLHelper {
140 public:
141 GLHelper(gpu::gles2::GLES2Interface* gl,
142 gpu::ContextSupport* context_support);
143 ~GLHelper();
145 enum ScalerQuality {
146 // Bilinear single pass, fastest possible.
147 SCALER_QUALITY_FAST = 1,
149 // Bilinear upscale + N * 50% bilinear downscales.
150 // This is still fast enough for most purposes and
151 // Image quality is nearly as good as the BEST option.
152 SCALER_QUALITY_GOOD = 2,
154 // Bicubic upscale + N * 50% bicubic downscales.
155 // Produces very good quality scaled images, but it's
156 // 2-8x slower than the "GOOD" quality, so it's not always
157 // worth it.
158 SCALER_QUALITY_BEST = 3,
161 // Copies the block of pixels specified with |src_subrect| from |src_texture|,
162 // scales it to |dst_size|, and writes it into |out|.
163 // |src_size| is the size of |src_texture|. The result is in |out_color_type|
164 // format and is potentially flipped vertically to make it a correct image
165 // representation. |callback| is invoked with the copy result when the copy
166 // operation has completed.
167 // Note that the src_texture will have the min/mag filter set to GL_LINEAR
168 // and wrap_s/t set to CLAMP_TO_EDGE in this call.
169 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 SkColorType out_color_type,
176 const base::Callback<void(bool)>& callback,
177 GLHelper::ScalerQuality quality);
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 in |out_color_type|
182 // format 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 SkColorType out_color_type,
196 const base::Callback<void(bool)>& callback,
197 GLHelper::ScalerQuality quality);
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 SkColorType format);
209 void ReadbackTextureAsync(GLuint texture,
210 const gfx::Size& dst_size,
211 unsigned char* out,
212 SkColorType color_type,
213 const base::Callback<void(bool)>& callback);
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);
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);
230 // Returns the shader compiled from the source.
231 GLuint CompileShaderFromSource(const GLchar* source, GLenum type);
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);
240 // Simply creates a texture.
241 GLuint CreateTexture();
242 // Deletes a texture.
243 void DeleteTexture(GLuint texture_id);
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);
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);
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);
261 // Resizes the texture's size to |size|.
262 void ResizeTexture(GLuint texture, const gfx::Size& size);
264 // Copies the framebuffer data given in |rect| to |texture|.
265 void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect);
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);
271 // Flushes GL commands.
272 void Flush();
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() {}
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;
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);
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);
319 // Returns the maximum number of draw buffers available,
320 // 0 if GL_EXT_draw_buffers is not available.
321 GLint MaxDrawBuffers();
323 // Checks whether the readbback is supported for texture with the
324 // matching config. This doesnt check for cross format readbacks.
325 bool IsReadbackConfigSupported(SkColorType texture_format);
327 protected:
328 class CopyTextureToImpl;
330 // Creates |copy_texture_to_impl_| if NULL.
331 void InitCopyTextToImpl();
332 // Creates |scaler_impl_| if NULL.
333 void InitScalerImpl();
335 enum ReadbackSwizzle {
336 kSwizzleNone = 0,
337 kSwizzleBGRA
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_;
346 DISALLOW_COPY_AND_ASSIGN(GLHelper);
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.
356 class CONTENT_EXPORT ReadbackYUVInterface {
357 public:
358 ReadbackYUVInterface() {}
359 virtual ~ReadbackYUVInterface() {}
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;
369 } // namespace content
371 #endif // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_