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