Home | History | Annotate | Download | only in client
      1 // Copyright (c) 2013 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.
      4 
      5 #ifndef CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
      6 #define CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
      7 
      8 #include <deque>
      9 #include <map>
     10 #include <vector>
     11 
     12 #include "content/common/gpu/client/gl_helper.h"
     13 #include "ui/gfx/rect.h"
     14 #include "ui/gfx/size.h"
     15 
     16 namespace content {
     17 
     18 class ShaderProgram;
     19 class ScalerImpl;
     20 class GLHelperTest;
     21 
     22 // Implements GPU texture scaling methods.
     23 // Note that you should probably not use this class directly.
     24 // See gl_helper.cc::CreateScaler instead.
     25 class CONTENT_EXPORT GLHelperScaling {
     26  public:
     27   enum ShaderType {
     28     SHADER_BILINEAR,
     29     SHADER_BILINEAR2,
     30     SHADER_BILINEAR3,
     31     SHADER_BILINEAR4,
     32     SHADER_BILINEAR2X2,
     33     SHADER_BICUBIC_UPSCALE,
     34     SHADER_BICUBIC_HALF_1D,
     35     SHADER_PLANAR,
     36     SHADER_YUV_MRT_PASS1,
     37     SHADER_YUV_MRT_PASS2,
     38   };
     39 
     40   // Similar to ScalerInterface, but can generate multiple outputs.
     41   // Used for YUV conversion in gl_helper.c
     42   class CONTENT_EXPORT ShaderInterface {
     43    public:
     44     ShaderInterface() {}
     45     virtual ~ShaderInterface() {}
     46     // Note that the src_texture will have the min/mag filter set to GL_LINEAR
     47     // and wrap_s/t set to CLAMP_TO_EDGE in this call.
     48     virtual void Execute(GLuint source_texture,
     49                          const std::vector<GLuint>& dest_textures) = 0;
     50   };
     51 
     52   typedef std::pair<ShaderType, bool> ShaderProgramKeyType;
     53 
     54   GLHelperScaling(gpu::gles2::GLES2Interface* gl,
     55                   GLHelper* helper);
     56   ~GLHelperScaling();
     57   void InitBuffer();
     58 
     59   GLHelper::ScalerInterface* CreateScaler(
     60       GLHelper::ScalerQuality quality,
     61       gfx::Size src_size,
     62       gfx::Rect src_subrect,
     63       const gfx::Size& dst_size,
     64       bool vertically_flip_texture,
     65       bool swizzle);
     66 
     67   GLHelper::ScalerInterface* CreatePlanarScaler(
     68       const gfx::Size& src_size,
     69       const gfx::Rect& src_subrect,
     70       const gfx::Size& dst_size,
     71       bool vertically_flip_texture,
     72       bool swizzle,
     73       const float color_weights[4]);
     74 
     75   ShaderInterface* CreateYuvMrtShader(
     76       const gfx::Size& src_size,
     77       const gfx::Rect& src_subrect,
     78       const gfx::Size& dst_size,
     79       bool vertically_flip_texture,
     80       bool swizzle,
     81       ShaderType shader);
     82 
     83  private:
     84   // A ScaleOp represents a pass in a scaler pipeline, in one dimension.
     85   // Note that when quality is GOOD, multiple scaler passes will be
     86   // combined into one operation for increased performance.
     87   // Exposed in the header file for testing purposes.
     88   struct ScaleOp {
     89     ScaleOp(int factor, bool x, int size)
     90         : scale_factor(factor), scale_x(x), scale_size(size) {
     91     }
     92 
     93     // Calculate a set of ScaleOp needed to convert an image of size
     94     // |src| into an image of size |dst|. If |scale_x| is true, then
     95     // the calculations are for the X axis of the image, otherwise Y.
     96     // If |allow3| is true, we can use a SHADER_BILINEAR3 to replace
     97     // a scale up and scale down with a 3-tap bilinear scale.
     98     // The calculated ScaleOps are added to |ops|.
     99     static void AddOps(int src,
    100                        int dst,
    101                        bool scale_x,
    102                        bool allow3,
    103                        std::deque<ScaleOp>* ops) {
    104       int num_downscales = 0;
    105       if (allow3 && dst * 3 >= src && dst * 2 < src) {
    106         // Technically, this should be a scale up and then a
    107         // scale down, but it makes the optimization code more
    108         // complicated.
    109         ops->push_back(ScaleOp(3, scale_x, dst));
    110         return;
    111       }
    112       while ((dst << num_downscales) < src) {
    113         num_downscales++;
    114       }
    115       if ((dst << num_downscales) != src) {
    116         ops->push_back(ScaleOp(0, scale_x, dst << num_downscales));
    117       }
    118       while (num_downscales) {
    119         num_downscales--;
    120         ops->push_back(ScaleOp(2, scale_x, dst << num_downscales));
    121       }
    122     }
    123 
    124     // Update |size| to its new size. Before calling this function
    125     // |size| should be the size of the input image. After calling it,
    126     // |size| will be the size of the image after this particular
    127     // scaling operation.
    128     void UpdateSize(gfx::Size* subrect) {
    129       if (scale_x) {
    130         subrect->set_width(scale_size);
    131       } else {
    132         subrect->set_height(scale_size);
    133       }
    134     }
    135 
    136     // A scale factor of 0 means upscale
    137     // 2 means 50% scale
    138     // 3 means 33% scale, etc.
    139     int scale_factor;
    140     bool scale_x;  // Otherwise y
    141     int scale_size;  // Size to scale to.
    142   };
    143 
    144   // Full specification for a single scaling stage.
    145   struct ScalerStage {
    146     ScalerStage(ShaderType shader_,
    147                 gfx::Size src_size_,
    148                 gfx::Rect src_subrect_,
    149                 gfx::Size dst_size_,
    150                 bool scale_x_,
    151                 bool vertically_flip_texture_,
    152                 bool swizzle_);
    153     ShaderType shader;
    154     gfx::Size src_size;
    155     gfx::Rect src_subrect;
    156     gfx::Size dst_size;
    157     bool scale_x;
    158     bool vertically_flip_texture;
    159     bool swizzle;
    160   };
    161 
    162   // Compute a vector of scaler stages for a particular
    163   // set of input/output parameters.
    164   void ComputeScalerStages(GLHelper::ScalerQuality quality,
    165                            const gfx::Size& src_size,
    166                            const gfx::Rect& src_subrect,
    167                            const gfx::Size& dst_size,
    168                            bool vertically_flip_texture,
    169                            bool swizzle,
    170                            std::vector<ScalerStage> *scaler_stages);
    171 
    172   // Take two queues of ScaleOp structs and generate a
    173   // vector of scaler stages. This is the second half of
    174   // ComputeScalerStages.
    175   void ConvertScalerOpsToScalerStages(
    176       GLHelper::ScalerQuality quality,
    177       gfx::Size src_size,
    178       gfx::Rect src_subrect,
    179       const gfx::Size& dst_size,
    180       bool vertically_flip_texture,
    181       bool swizzle,
    182       std::deque<GLHelperScaling::ScaleOp>* x_ops,
    183       std::deque<GLHelperScaling::ScaleOp>* y_ops,
    184       std::vector<ScalerStage> *scaler_stages);
    185 
    186 
    187   scoped_refptr<ShaderProgram> GetShaderProgram(ShaderType type, bool swizzle);
    188 
    189   // Interleaved array of 2-dimentional vertex positions (x, y) and
    190   // 2-dimentional texture coordinates (s, t).
    191   static const GLfloat kVertexAttributes[];
    192 
    193   gpu::gles2::GLES2Interface* gl_;
    194   GLHelper* helper_;
    195 
    196   // The buffer that holds the vertices and the texture coordinates data for
    197   // drawing a quad.
    198   ScopedBuffer vertex_attributes_buffer_;
    199 
    200   std::map<ShaderProgramKeyType,
    201            scoped_refptr<ShaderProgram> > shader_programs_;
    202 
    203   friend class ShaderProgram;
    204   friend class ScalerImpl;
    205   friend class GLHelperTest;
    206   DISALLOW_COPY_AND_ASSIGN(GLHelperScaling);
    207 };
    208 
    209 
    210 }  // namespace content
    211 
    212 #endif  // CONTENT_COMMON_GPU_CLIENT_GL_HELPER_SCALING_H_
    213