- add sources.
[platform/framework/web/crosswalk.git] / src / content / common / gpu / client / gl_helper_scaling.h
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(WebKit::WebGLId source_texture,
45                          const std::vector<WebKit::WebGLId>& dest_textures) = 0;
46   };
47
48   typedef std::pair<ShaderType, bool> ShaderProgramKeyType;
49
50   GLHelperScaling(WebKit::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 WebKit::WGC3Dfloat kVertexAttributes[];
186
187   WebKit::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_