15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/atomicops.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/common/content_export.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/client/gles2_interface.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gpu/command_buffer/common/mailbox_holder.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Rect;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Size;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace gpu {
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)class ContextSupport;
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstruct Mailbox;
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace media {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class VideoFrame;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SkRegion;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class GLHelperScaling;
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedGLuint {
3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef void (gpu::gles2::GLES2Interface::*GenFunc)(GLsizei n, GLuint* ids);
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef void (gpu::gles2::GLES2Interface::*DeleteFunc)(GLsizei n,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                         const GLuint* ids);
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedGLuint(gpu::gles2::GLES2Interface* gl,
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               GenFunc gen_func,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)               DeleteFunc delete_func)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : gl_(gl), id_(0u), delete_func_(delete_func) {
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    (gl_->*gen_func)(1, &id_);
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  operator GLuint() const { return id_; }
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint id() const { return id_; }
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~ScopedGLuint() {
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    if (id_ != 0) {
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      (gl_->*delete_func_)(1, &id_);
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gpu::gles2::GLES2Interface* gl_;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint id_;
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DeleteFunc delete_func_;
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedGLuint);
6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedBuffer : public ScopedGLuint {
6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ScopedBuffer(gpu::gles2::GLES2Interface* gl)
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedGLuint(gl,
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::GenBuffers,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::DeleteBuffers) {}
7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedFramebuffer : public ScopedGLuint {
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ScopedFramebuffer(gpu::gles2::GLES2Interface* gl)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedGLuint(gl,
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::GenFramebuffers,
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::DeleteFramebuffers) {}
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedTexture : public ScopedGLuint {
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit ScopedTexture(gpu::gles2::GLES2Interface* gl)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedGLuint(gl,
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::GenTextures,
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     &gpu::gles2::GLES2Interface::DeleteTextures) {}
8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target>
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class ScopedBinder {
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef void (gpu::gles2::GLES2Interface::*BindFunc)(GLenum target,
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                       GLuint id);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedBinder(gpu::gles2::GLES2Interface* gl, GLuint id, BindFunc bind_func)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : gl_(gl), bind_func_(bind_func) {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    (gl_->*bind_func_)(Target, id);
9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~ScopedBinder() { (gl_->*bind_func_)(Target, 0); }
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) private:
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gpu::gles2::GLES2Interface* gl_;
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  BindFunc bind_func_;
10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target>
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedBufferBinder : ScopedBinder<Target> {
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedBufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindBuffer) {}
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target>
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedFramebufferBinder : ScopedBinder<Target> {
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedFramebufferBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedBinder<Target>(gl,
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             id,
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             &gpu::gles2::GLES2Interface::BindFramebuffer) {}
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template <GLenum Target>
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class ScopedTextureBinder : ScopedBinder<Target> {
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public:
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScopedTextureBinder(gpu::gles2::GLES2Interface* gl, GLuint id)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : ScopedBinder<Target>(gl, id, &gpu::gles2::GLES2Interface::BindTexture) {
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)};
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class ReadbackYUVInterface;
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class GLHelperReadbackSupport;
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Provides higher level operations on top of the gpu::gles2::GLES2Interface
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// interfaces.
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class CONTENT_EXPORT GLHelper {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLHelper(gpu::gles2::GLES2Interface* gl,
1428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)           gpu::ContextSupport* context_support);
14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ~GLHelper();
14490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  enum ScalerQuality {
14690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Bilinear single pass, fastest possible.
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SCALER_QUALITY_FAST = 1,
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Bilinear upscale + N * 50% bilinear downscales.
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // This is still fast enough for most purposes and
15190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Image quality is nearly as good as the BEST option.
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SCALER_QUALITY_GOOD = 2,
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Bicubic upscale + N * 50% bicubic downscales.
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Produces very good quality scaled images, but it's
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // 2-8x slower than the "GOOD" quality, so it's not always
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // worth it.
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    SCALER_QUALITY_BEST = 3,
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copies the block of pixels specified with |src_subrect| from |src_texture|,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scales it to |dst_size|, and writes it into |out|.
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |src_size| is the size of |src_texture|. The result is in |out_color_type|
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // format and is potentially flipped vertically to make it a correct image
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // representation.  |callback| is invoked with the copy result when the copy
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operation has completed.
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
16890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CropScaleReadbackAndCleanTexture(
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GLuint src_texture,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Size& src_size,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Rect& src_subrect,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const gfx::Size& dst_size,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      unsigned char* out,
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const SkColorType out_color_type,
176cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::Callback<void(bool)>& callback,
177cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GLHelper::ScalerQuality quality);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Copies the block of pixels specified with |src_subrect| from |src_mailbox|,
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // scales it to |dst_size|, and writes it into |out|.
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // |src_size| is the size of |src_mailbox|. The result is in |out_color_type|
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // format and is potentially flipped vertically to make it a correct image
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // representation.  |callback| is invoked with the copy result when the copy
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // operation has completed.
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Note that the texture bound to src_mailbox will have the min/mag filter set
1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // to GL_LINEAR and wrap_s/t set to CLAMP_TO_EDGE in this call. src_mailbox is
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // assumed to be GL_TEXTURE_2D.
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void CropScaleReadbackAndCleanMailbox(
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const gpu::Mailbox& src_mailbox,
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      uint32 sync_point,
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const gfx::Size& src_size,
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const gfx::Rect& src_subrect,
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const gfx::Size& dst_size,
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      unsigned char* out,
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const SkColorType out_color_type,
196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      const base::Callback<void(bool)>& callback,
197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      GLHelper::ScalerQuality quality);
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Copies the texture data out of |texture| into |out|.  |size| is the
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size of the texture.  No post processing is applied to the pixels.  The
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // texture is assumed to have a format of GL_RGBA with a pixel type of
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // GL_UNSIGNED_BYTE.  This is a blocking call that calls glReadPixels on the
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // current OpenGL context.
2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ReadbackTextureSync(GLuint texture,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const gfx::Rect& src_rect,
2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           unsigned char* out,
207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           SkColorType format);
2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ReadbackTextureAsync(GLuint texture,
2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            const gfx::Size& dst_size,
2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            unsigned char* out,
212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            SkColorType color_type,
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            const base::Callback<void(bool)>& callback);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a copy of the specified texture. |size| is the size of the texture.
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint CopyTexture(GLuint texture, const gfx::Size& size);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a scaled copy of the specified texture. |src_size| is the size of
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the texture and |dst_size| is the size of the resulting copy.
22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note that the src_texture will have the min/mag filter set to GL_LINEAR
22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // and wrap_s/t set to CLAMP_TO_EDGE in this call.
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint CopyAndScaleTexture(GLuint texture,
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             const gfx::Size& src_size,
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             const gfx::Size& dst_size,
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             bool vertically_flip_texture,
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             ScalerQuality quality);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the shader compiled from the source.
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint CompileShaderFromSource(const GLchar* source, GLenum type);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Copies all pixels from |previous_texture| into |texture| that are
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // inside the region covered by |old_damage| but not part of |new_damage|.
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CopySubBufferDamage(GLuint texture,
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           GLuint previous_texture,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SkRegion& new_damage,
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           const SkRegion& old_damage);
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
240868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Simply creates a texture.
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint CreateTexture();
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Deletes a texture.
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void DeleteTexture(GLuint texture_id);
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Insert a sync point into the GL command buffer.
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 InsertSyncPoint();
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Wait for the sync point before executing further GL commands.
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void WaitSyncPoint(uint32 sync_point);
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Creates a mailbox holder that is attached to the given texture id, with a
2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // sync point to wait on before using the mailbox. Returns a holder with an
2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // empty mailbox on failure.
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Note the texture is assumed to be GL_TEXTURE_2D.
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gpu::MailboxHolder ProduceMailboxHolderFromTexture(GLuint texture_id);
255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
2567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Creates a texture and consumes a mailbox into it. Returns 0 on failure.
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Note the mailbox is assumed to be GL_TEXTURE_2D.
2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLuint ConsumeMailboxToTexture(const gpu::Mailbox& mailbox,
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 uint32 sync_point);
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Resizes the texture's size to |size|.
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void ResizeTexture(GLuint texture, const gfx::Size& size);
263868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
264868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Copies the framebuffer data given in |rect| to |texture|.
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CopyTextureSubImage(GLuint texture, const gfx::Rect& rect);
266868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
267868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Copies the all framebuffer data to |texture|. |size| specifies the
268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // size of the framebuffer.
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void CopyTextureFullImage(GLuint texture, const gfx::Size& size);
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Flushes GL commands.
272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  void Flush();
273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
274868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // A scaler will cache all intermediate textures and programs
27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // needed to scale from a specified size to a destination size.
27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the source or destination sizes changes, you must create
27890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // a new scaler.
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  class CONTENT_EXPORT ScalerInterface {
28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)   public:
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ScalerInterface() {}
28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    virtual ~ScalerInterface() {}
28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
28490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Note that the src_texture will have the min/mag filter set to GL_LINEAR
28590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // and wrap_s/t set to CLAMP_TO_EDGE in this call.
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    virtual void Scale(GLuint source_texture, GLuint dest_texture) = 0;
28790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    virtual const gfx::Size& SrcSize() = 0;
28890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    virtual const gfx::Rect& SrcSubrect() = 0;
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    virtual const gfx::Size& DstSize() = 0;
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  };
29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note that the quality may be adjusted down if texture
29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // allocations fail or hardware doesn't support the requtested
29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // quality. Note that ScalerQuality enum is arranged in
29590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // numerical order for simplicity.
29690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  ScalerInterface* CreateScaler(ScalerQuality quality,
29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const gfx::Size& src_size,
29890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const gfx::Rect& src_subrect,
29990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                const gfx::Size& dst_size,
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                bool vertically_flip_texture,
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                bool swizzle);
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
303868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Create a readback pipeline that will scale a subsection of the source
304868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // texture, then convert it to YUV422 planar form and then read back that.
305868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // This reduces the amount of memory read from GPU to CPU memory by a factor
306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 2.6, which can be quite handy since readbacks have very limited speed
307868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // on some platforms. All values in |dst_size| and |dst_subrect| must be
308868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // a multiple of two. If |use_mrt| is true, the pipeline will try to optimize
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // the YUV conversion using the multi-render-target extension. |use_mrt|
310868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // should only be set to false for testing.
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ReadbackYUVInterface* CreateReadbackPipelineYUV(ScalerQuality quality,
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const gfx::Size& src_size,
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const gfx::Rect& src_subrect,
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const gfx::Size& dst_size,
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const gfx::Rect& dst_subrect,
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  bool flip_vertically,
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  bool use_mrt);
318868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
319868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Returns the maximum number of draw buffers available,
320868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // 0 if GL_EXT_draw_buffers is not available.
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GLint MaxDrawBuffers();
322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Checks whether the readbback is supported for texture with the
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // matching config. This doesnt check for cross format readbacks.
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool IsReadbackConfigSupported(SkColorType texture_format);
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) protected:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class CopyTextureToImpl;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates |copy_texture_to_impl_| if NULL.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InitCopyTextToImpl();
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Creates |scaler_impl_| if NULL.
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void InitScalerImpl();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  enum ReadbackSwizzle {
336effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    kSwizzleNone = 0,
337effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    kSwizzleBGRA
338effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
339effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gpu::gles2::GLES2Interface* gl_;
3418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  gpu::ContextSupport* context_support_;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<CopyTextureToImpl> copy_texture_to_impl_;
34390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  scoped_ptr<GLHelperScaling> scaler_impl_;
344a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  scoped_ptr<GLHelperReadbackSupport> readback_support_;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GLHelper);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Similar to a ScalerInterface, a yuv readback pipeline will
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// cache a scaler and all intermediate textures and frame buffers
351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// needed to scale, crop, letterbox and read back a texture from
352868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// the GPU into CPU-accessible RAM. A single readback pipeline
353868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// can handle multiple outstanding readbacks at the same time, but
354868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// if the source or destination sizes change, you'll need to create
355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// a new readback pipeline.
356868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)class CONTENT_EXPORT ReadbackYUVInterface {
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
358868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ReadbackYUVInterface() {}
359868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual ~ReadbackYUVInterface() {}
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Note that |target| must use YV12 format.
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void ReadbackYUV(const gpu::Mailbox& mailbox,
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           uint32 sync_point,
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           const scoped_refptr<media::VideoFrame>& target,
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           const base::Callback<void(bool)>& callback) = 0;
366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual GLHelper::ScalerInterface* scaler() = 0;
367868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
368868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_H_
372