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