Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(829)

Side by Side Diff: content/common/gpu/client/gl_helper_scaling.cc

Issue 117233006: Port content::GLHelper over to GLES2Interface (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: NULL-check gl->GetString(GL_EXTENSIONS) Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/client/gl_helper_scaling.h" 5 #include "content/common/gpu/client/gl_helper_scaling.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/debug/trace_event.h" 12 #include "base/debug/trace_event.h"
13 #include "base/lazy_instance.h" 13 #include "base/lazy_instance.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/ref_counted.h" 15 #include "base/memory/ref_counted.h"
16 #include "base/message_loop/message_loop.h" 16 #include "base/message_loop/message_loop.h"
17 #include "base/time/time.h" 17 #include "base/time/time.h"
18 #include "third_party/WebKit/public/platform/WebCString.h" 18 #include "gpu/command_buffer/client/gles2_interface.h"
19 #include "third_party/skia/include/core/SkRegion.h" 19 #include "third_party/skia/include/core/SkRegion.h"
20 #include "ui/gfx/rect.h" 20 #include "ui/gfx/rect.h"
21 #include "ui/gfx/size.h" 21 #include "ui/gfx/size.h"
22 #include "ui/gl/gl_bindings.h"
23 22
24 using blink::WebGLId; 23 using gpu::gles2::GLES2Interface;
25 using blink::WebGraphicsContext3D;
26 24
27 namespace content { 25 namespace content {
28 26
29 GLHelperScaling::GLHelperScaling(blink::WebGraphicsContext3D* context, 27 GLHelperScaling::GLHelperScaling(GLES2Interface* gl, GLHelper* helper)
30 GLHelper* helper) 28 : gl_(gl), helper_(helper), vertex_attributes_buffer_(gl_) {
31 : context_(context),
32 helper_(helper),
33 vertex_attributes_buffer_(context_, context_->createBuffer()) {
34 InitBuffer(); 29 InitBuffer();
35 } 30 }
36 31
37 GLHelperScaling::~GLHelperScaling() { 32 GLHelperScaling::~GLHelperScaling() {}
38 }
39 33
40 // Used to keep track of a generated shader program. The program 34 // Used to keep track of a generated shader program. The program
41 // is passed in as text through Setup and is used by calling 35 // is passed in as text through Setup and is used by calling
42 // UseProgram() with the right parameters. Note that |context_| 36 // UseProgram() with the right parameters. Note that |gl_|
43 // and |helper_| are assumed to live longer than this program. 37 // and |helper_| are assumed to live longer than this program.
44 class ShaderProgram : public base::RefCounted<ShaderProgram> { 38 class ShaderProgram : public base::RefCounted<ShaderProgram> {
45 public: 39 public:
46 ShaderProgram(WebGraphicsContext3D* context, 40 ShaderProgram(GLES2Interface* gl, GLHelper* helper)
47 GLHelper* helper) 41 : gl_(gl),
48 : context_(context),
49 helper_(helper), 42 helper_(helper),
50 program_(context, context->createProgram()) { 43 program_(gl_->CreateProgram()),
51 } 44 position_location_(-1),
45 texcoord_location_(-1),
46 src_subrect_location_(-1),
47 src_pixelsize_location_(-1),
48 dst_pixelsize_location_(-1),
49 scaling_vector_location_(-1),
50 color_weights_location_(-1) {}
52 51
53 // Compile shader program, return true if successful. 52 // Compile shader program.
54 bool Setup(const blink::WGC3Dchar* vertex_shader_text, 53 void Setup(const GLchar* vertex_shader_text,
55 const blink::WGC3Dchar* fragment_shader_text); 54 const GLchar* fragment_shader_text);
56 55
57 // UseProgram must be called with GL_TEXTURE_2D bound to the 56 // UseProgram must be called with GL_TEXTURE_2D bound to the
58 // source texture and GL_ARRAY_BUFFER bound to a vertex 57 // source texture and GL_ARRAY_BUFFER bound to a vertex
59 // attribute buffer. 58 // attribute buffer.
60 void UseProgram(const gfx::Size& src_size, 59 void UseProgram(const gfx::Size& src_size,
61 const gfx::Rect& src_subrect, 60 const gfx::Rect& src_subrect,
62 const gfx::Size& dst_size, 61 const gfx::Size& dst_size,
63 bool scale_x, 62 bool scale_x,
64 bool flip_y, 63 bool flip_y,
65 GLfloat color_weights[4]); 64 GLfloat color_weights[4]);
66 65
66 bool Initialized() const { return position_location_ != -1; }
67
67 private: 68 private:
68 friend class base::RefCounted<ShaderProgram>; 69 friend class base::RefCounted<ShaderProgram>;
69 ~ShaderProgram() {} 70 ~ShaderProgram() { gl_->DeleteProgram(program_); }
70 71
71 WebGraphicsContext3D* context_; 72 GLES2Interface* gl_;
72 GLHelper* helper_; 73 GLHelper* helper_;
73 74
74 // A program for copying a source texture into a destination texture. 75 // A program for copying a source texture into a destination texture.
75 ScopedProgram program_; 76 GLuint program_;
76 77
77 // The location of the position in the program. 78 // The location of the position in the program.
78 blink::WGC3Dint position_location_; 79 GLint position_location_;
79 // The location of the texture coordinate in the program. 80 // The location of the texture coordinate in the program.
80 blink::WGC3Dint texcoord_location_; 81 GLint texcoord_location_;
81 // The location of the source texture in the program. 82 // The location of the source texture in the program.
82 blink::WGC3Dint texture_location_; 83 GLint texture_location_;
83 // The location of the texture coordinate of 84 // The location of the texture coordinate of
84 // the sub-rectangle in the program. 85 // the sub-rectangle in the program.
85 blink::WGC3Dint src_subrect_location_; 86 GLint src_subrect_location_;
86 // Location of size of source image in pixels. 87 // Location of size of source image in pixels.
87 blink::WGC3Dint src_pixelsize_location_; 88 GLint src_pixelsize_location_;
88 // Location of size of destination image in pixels. 89 // Location of size of destination image in pixels.
89 blink::WGC3Dint dst_pixelsize_location_; 90 GLint dst_pixelsize_location_;
90 // Location of vector for scaling direction. 91 // Location of vector for scaling direction.
91 blink::WGC3Dint scaling_vector_location_; 92 GLint scaling_vector_location_;
92 // Location of color weights. 93 // Location of color weights.
93 blink::WGC3Dint color_weights_location_; 94 GLint color_weights_location_;
94 95
95 DISALLOW_COPY_AND_ASSIGN(ShaderProgram); 96 DISALLOW_COPY_AND_ASSIGN(ShaderProgram);
96 }; 97 };
97 98
98
99 // Implementation of a single stage in a scaler pipeline. If the pipeline has 99 // Implementation of a single stage in a scaler pipeline. If the pipeline has
100 // multiple stages, it calls Scale() on the subscaler, then further scales the 100 // multiple stages, it calls Scale() on the subscaler, then further scales the
101 // output. Caches textures and framebuffers to avoid allocating/deleting 101 // output. Caches textures and framebuffers to avoid allocating/deleting
102 // them once per frame, which can be expensive on some drivers. 102 // them once per frame, which can be expensive on some drivers.
103 class ScalerImpl : 103 class ScalerImpl : public GLHelper::ScalerInterface,
104 public GLHelper::ScalerInterface, 104 public GLHelperScaling::ShaderInterface {
105 public GLHelperScaling::ShaderInterface {
106 public: 105 public:
107 // |context| and |copy_impl| are expected to live longer than this object. 106 // |gl| and |copy_impl| are expected to live longer than this object.
108 // |src_size| is the size of the input texture in pixels. 107 // |src_size| is the size of the input texture in pixels.
109 // |dst_size| is the size of the output texutre in pixels. 108 // |dst_size| is the size of the output texutre in pixels.
110 // |src_subrect| is the portion of the src to copy to the output texture. 109 // |src_subrect| is the portion of the src to copy to the output texture.
111 // If |scale_x| is true, we are scaling along the X axis, otherwise Y. 110 // If |scale_x| is true, we are scaling along the X axis, otherwise Y.
112 // If we are scaling in both X and Y, |scale_x| is ignored. 111 // If we are scaling in both X and Y, |scale_x| is ignored.
113 // If |vertically_flip_texture| is true, output will be upside-down. 112 // If |vertically_flip_texture| is true, output will be upside-down.
114 // If |swizzle| is true, RGBA will be transformed into BGRA. 113 // If |swizzle| is true, RGBA will be transformed into BGRA.
115 // |color_weights| are only used together with SHADER_PLANAR to specify 114 // |color_weights| are only used together with SHADER_PLANAR to specify
116 // how to convert RGB colors into a single value. 115 // how to convert RGB colors into a single value.
117 ScalerImpl(WebGraphicsContext3D* context, 116 ScalerImpl(GLES2Interface* gl,
118 GLHelperScaling* scaler_helper, 117 GLHelperScaling* scaler_helper,
119 const GLHelperScaling::ScalerStage &scaler_stage, 118 const GLHelperScaling::ScalerStage& scaler_stage,
120 ScalerImpl* subscaler, 119 ScalerImpl* subscaler,
121 const float* color_weights) : 120 const float* color_weights)
122 context_(context), 121 : gl_(gl),
123 scaler_helper_(scaler_helper), 122 scaler_helper_(scaler_helper),
124 spec_(scaler_stage), 123 spec_(scaler_stage),
125 intermediate_texture_(0), 124 intermediate_texture_(0),
126 dst_framebuffer_(context, context_->createFramebuffer()), 125 dst_framebuffer_(gl),
127 subscaler_(subscaler) { 126 subscaler_(subscaler) {
128 if (color_weights) { 127 if (color_weights) {
129 color_weights_[0] = color_weights[0]; 128 color_weights_[0] = color_weights[0];
130 color_weights_[1] = color_weights[1]; 129 color_weights_[1] = color_weights[1];
131 color_weights_[2] = color_weights[2]; 130 color_weights_[2] = color_weights[2];
132 color_weights_[3] = color_weights[3]; 131 color_weights_[3] = color_weights[3];
133 } else { 132 } else {
134 color_weights_[0] = 0.0; 133 color_weights_[0] = 0.0;
135 color_weights_[1] = 0.0; 134 color_weights_[1] = 0.0;
136 color_weights_[2] = 0.0; 135 color_weights_[2] = 0.0;
137 color_weights_[3] = 0.0; 136 color_weights_[3] = 0.0;
138 } 137 }
139 shader_program_ = scaler_helper_->GetShaderProgram(spec_.shader, 138 shader_program_ =
140 spec_.swizzle); 139 scaler_helper_->GetShaderProgram(spec_.shader, spec_.swizzle);
141 140
142 if (subscaler_) { 141 if (subscaler_) {
143 intermediate_texture_ = context_->createTexture(); 142 intermediate_texture_ = 0u;
144 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( 143 gl_->GenTextures(1, &intermediate_texture_);
145 context_, 144 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_,
146 intermediate_texture_); 145 intermediate_texture_);
147 context_->texImage2D(GL_TEXTURE_2D, 146 gl_->TexImage2D(GL_TEXTURE_2D,
148 0, 147 0,
149 GL_RGBA, 148 GL_RGBA,
150 spec_.src_size.width(), 149 spec_.src_size.width(),
151 spec_.src_size.height(), 150 spec_.src_size.height(),
152 0, 151 0,
153 GL_RGBA, 152 GL_RGBA,
154 GL_UNSIGNED_BYTE, 153 GL_UNSIGNED_BYTE,
155 NULL); 154 NULL);
156 } 155 }
157 } 156 }
158 157
159 virtual ~ScalerImpl() { 158 virtual ~ScalerImpl() {
160 if (intermediate_texture_) { 159 if (intermediate_texture_) {
161 context_->deleteTexture(intermediate_texture_); 160 gl_->DeleteTextures(1, &intermediate_texture_);
162 } 161 }
163 } 162 }
164 163
165 // GLHelperShader::ShaderInterface implementation. 164 // GLHelperShader::ShaderInterface implementation.
166 virtual void Execute( 165 virtual void Execute(GLuint source_texture,
167 blink::WebGLId source_texture, 166 const std::vector<GLuint>& dest_textures) OVERRIDE {
168 const std::vector<blink::WebGLId>& dest_textures) OVERRIDE {
169 if (subscaler_) { 167 if (subscaler_) {
170 subscaler_->Scale(source_texture, intermediate_texture_); 168 subscaler_->Scale(source_texture, intermediate_texture_);
171 source_texture = intermediate_texture_; 169 source_texture = intermediate_texture_;
172 } 170 }
173 171
174 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( 172 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
175 context_, 173 gl_, dst_framebuffer_);
176 dst_framebuffer_);
177 DCHECK_GT(dest_textures.size(), 0U); 174 DCHECK_GT(dest_textures.size(), 0U);
178 scoped_ptr<blink::WGC3Denum[]> buffers( 175 scoped_ptr<GLenum[]> buffers(new GLenum[dest_textures.size()]);
179 new blink::WGC3Denum[dest_textures.size()]);
180 for (size_t t = 0; t < dest_textures.size(); t++) { 176 for (size_t t = 0; t < dest_textures.size(); t++) {
181 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, 177 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dest_textures[t]);
182 dest_textures[t]); 178 gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
183 context_->framebufferTexture2D(GL_FRAMEBUFFER, 179 GL_COLOR_ATTACHMENT0 + t,
184 GL_COLOR_ATTACHMENT0 + t, 180 GL_TEXTURE_2D,
185 GL_TEXTURE_2D, 181 dest_textures[t],
186 dest_textures[t], 182 0);
187 0);
188 buffers[t] = GL_COLOR_ATTACHMENT0 + t; 183 buffers[t] = GL_COLOR_ATTACHMENT0 + t;
189 } 184 }
190 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, 185 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, source_texture);
191 source_texture);
192 186
193 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, 187 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
194 GL_LINEAR); 188 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
195 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 189 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
196 GL_LINEAR); 190 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
197 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
198 GL_CLAMP_TO_EDGE);
199 context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
200 GL_CLAMP_TO_EDGE);
201 191
202 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( 192 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
203 context_, 193 gl_, scaler_helper_->vertex_attributes_buffer_);
204 scaler_helper_->vertex_attributes_buffer_); 194 DCHECK(shader_program_->Initialized());
205 shader_program_->UseProgram(spec_.src_size, 195 shader_program_->UseProgram(spec_.src_size,
206 spec_.src_subrect, 196 spec_.src_subrect,
207 spec_.dst_size, 197 spec_.dst_size,
208 spec_.scale_x, 198 spec_.scale_x,
209 spec_.vertically_flip_texture, 199 spec_.vertically_flip_texture,
210 color_weights_); 200 color_weights_);
211 context_->viewport(0, 0, spec_.dst_size.width(), spec_.dst_size.height()); 201 gl_->Viewport(0, 0, spec_.dst_size.width(), spec_.dst_size.height());
212 202
213 if (dest_textures.size() > 1) { 203 if (dest_textures.size() > 1) {
214 DCHECK_LE(static_cast<int>(dest_textures.size()), 204 DCHECK_LE(static_cast<int>(dest_textures.size()),
215 scaler_helper_->helper_->MaxDrawBuffers()); 205 scaler_helper_->helper_->MaxDrawBuffers());
216 context_->drawBuffersEXT(dest_textures.size(), buffers.get()); 206 gl_->DrawBuffersEXT(dest_textures.size(), buffers.get());
217 } 207 }
218 // Conduct texture mapping by drawing a quad composed of two triangles. 208 // Conduct texture mapping by drawing a quad composed of two triangles.
219 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); 209 gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
220 if (dest_textures.size() > 1) { 210 if (dest_textures.size() > 1) {
221 // Set the draw buffers back to not confuse others. 211 // Set the draw buffers back to not confuse others.
222 context_->drawBuffersEXT(1, &buffers[0]); 212 gl_->DrawBuffersEXT(1, &buffers[0]);
223 } 213 }
224 } 214 }
225 215
226 // GLHelper::ScalerInterface implementation. 216 // GLHelper::ScalerInterface implementation.
227 virtual void Scale(blink::WebGLId source_texture, 217 virtual void Scale(GLuint source_texture, GLuint dest_texture) OVERRIDE {
228 blink::WebGLId dest_texture) OVERRIDE { 218 std::vector<GLuint> tmp(1);
229 std::vector<blink::WebGLId> tmp(1);
230 tmp[0] = dest_texture; 219 tmp[0] = dest_texture;
231 Execute(source_texture, tmp); 220 Execute(source_texture, tmp);
232 } 221 }
233 222
234 virtual const gfx::Size& SrcSize() OVERRIDE { 223 virtual const gfx::Size& SrcSize() OVERRIDE {
235 if (subscaler_) { 224 if (subscaler_) {
236 return subscaler_->SrcSize(); 225 return subscaler_->SrcSize();
237 } 226 }
238 return spec_.src_size; 227 return spec_.src_size;
239 } 228 }
240 virtual const gfx::Rect& SrcSubrect() OVERRIDE { 229 virtual const gfx::Rect& SrcSubrect() OVERRIDE {
241 if (subscaler_) { 230 if (subscaler_) {
242 return subscaler_->SrcSubrect(); 231 return subscaler_->SrcSubrect();
243 } 232 }
244 return spec_.src_subrect; 233 return spec_.src_subrect;
245 } 234 }
246 virtual const gfx::Size& DstSize() OVERRIDE { 235 virtual const gfx::Size& DstSize() OVERRIDE { return spec_.dst_size; }
247 return spec_.dst_size;
248 }
249 236
250 private: 237 private:
251 WebGraphicsContext3D* context_; 238 GLES2Interface* gl_;
252 GLHelperScaling* scaler_helper_; 239 GLHelperScaling* scaler_helper_;
253 GLHelperScaling::ScalerStage spec_; 240 GLHelperScaling::ScalerStage spec_;
254 GLfloat color_weights_[4]; 241 GLfloat color_weights_[4];
255 blink::WebGLId intermediate_texture_; 242 GLuint intermediate_texture_;
256 scoped_refptr<ShaderProgram> shader_program_; 243 scoped_refptr<ShaderProgram> shader_program_;
257 ScopedFramebuffer dst_framebuffer_; 244 ScopedFramebuffer dst_framebuffer_;
258 scoped_ptr<ScalerImpl> subscaler_; 245 scoped_ptr<ScalerImpl> subscaler_;
259 }; 246 };
260 247
261 GLHelperScaling::ScalerStage::ScalerStage( 248 GLHelperScaling::ScalerStage::ScalerStage(ShaderType shader_,
262 ShaderType shader_, 249 gfx::Size src_size_,
263 gfx::Size src_size_, 250 gfx::Rect src_subrect_,
264 gfx::Rect src_subrect_, 251 gfx::Size dst_size_,
265 gfx::Size dst_size_, 252 bool scale_x_,
266 bool scale_x_, 253 bool vertically_flip_texture_,
267 bool vertically_flip_texture_, 254 bool swizzle_)
268 bool swizzle_)
269 : shader(shader_), 255 : shader(shader_),
270 src_size(src_size_), 256 src_size(src_size_),
271 src_subrect(src_subrect_), 257 src_subrect(src_subrect_),
272 dst_size(dst_size_), 258 dst_size(dst_size_),
273 scale_x(scale_x_), 259 scale_x(scale_x_),
274 vertically_flip_texture(vertically_flip_texture_), 260 vertically_flip_texture(vertically_flip_texture_),
275 swizzle(swizzle_) { 261 swizzle(swizzle_) {}
276 }
277 262
278 // The important inputs for this function is |x_ops| and 263 // The important inputs for this function is |x_ops| and
279 // |y_ops|. They represent scaling operations to be done 264 // |y_ops|. They represent scaling operations to be done
280 // on an imag of size |src_size|. If |quality| is SCALER_QUALITY_BEST, 265 // on an imag of size |src_size|. If |quality| is SCALER_QUALITY_BEST,
281 // then we will interpret these scale operations literally and we'll 266 // then we will interpret these scale operations literally and we'll
282 // create one scaler stage for each ScaleOp. However, if |quality| 267 // create one scaler stage for each ScaleOp. However, if |quality|
283 // is SCALER_QUALITY_GOOD, then we can do a whole bunch of optimizations 268 // is SCALER_QUALITY_GOOD, then we can do a whole bunch of optimizations
284 // by combining two or more ScaleOps in to a single scaler stage. 269 // by combining two or more ScaleOps in to a single scaler stage.
285 // Normally we process ScaleOps from |y_ops| first and |x_ops| after 270 // Normally we process ScaleOps from |y_ops| first and |x_ops| after
286 // all |y_ops| are processed, but sometimes we can combine one or more 271 // all |y_ops| are processed, but sometimes we can combine one or more
287 // operation from both queues essentially for free. This is the reason 272 // operation from both queues essentially for free. This is the reason
288 // why |x_ops| and |y_ops| aren't just one single queue. 273 // why |x_ops| and |y_ops| aren't just one single queue.
289 void GLHelperScaling::ConvertScalerOpsToScalerStages( 274 void GLHelperScaling::ConvertScalerOpsToScalerStages(
290 GLHelper::ScalerQuality quality, 275 GLHelper::ScalerQuality quality,
291 gfx::Size src_size, 276 gfx::Size src_size,
292 gfx::Rect src_subrect, 277 gfx::Rect src_subrect,
293 const gfx::Size& dst_size, 278 const gfx::Size& dst_size,
294 bool vertically_flip_texture, 279 bool vertically_flip_texture,
295 bool swizzle, 280 bool swizzle,
296 std::deque<GLHelperScaling::ScaleOp>* x_ops, 281 std::deque<GLHelperScaling::ScaleOp>* x_ops,
297 std::deque<GLHelperScaling::ScaleOp>* y_ops, 282 std::deque<GLHelperScaling::ScaleOp>* y_ops,
298 std::vector<ScalerStage> *scaler_stages) { 283 std::vector<ScalerStage>* scaler_stages) {
299 while (!x_ops->empty() || !y_ops->empty()) { 284 while (!x_ops->empty() || !y_ops->empty()) {
300 gfx::Size intermediate_size = src_subrect.size(); 285 gfx::Size intermediate_size = src_subrect.size();
301 std::deque<ScaleOp>* current_queue = NULL; 286 std::deque<ScaleOp>* current_queue = NULL;
302 287
303 if (!y_ops->empty()) { 288 if (!y_ops->empty()) {
304 current_queue = y_ops; 289 current_queue = y_ops;
305 } else { 290 } else {
306 current_queue = x_ops; 291 current_queue = x_ops;
307 } 292 }
308 293
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 // Check if we can combine some steps in the other dimension as well. 332 // Check if we can combine some steps in the other dimension as well.
348 // Since all shaders currently use GL_LINEAR, we can easily scale up 333 // Since all shaders currently use GL_LINEAR, we can easily scale up
349 // or scale down by exactly 2x at the same time as we do another 334 // or scale down by exactly 2x at the same time as we do another
350 // operation. Currently, the following mergers are supported: 335 // operation. Currently, the following mergers are supported:
351 // * 1 bilinear Y-pass with 1 bilinear X-pass (up or down) 336 // * 1 bilinear Y-pass with 1 bilinear X-pass (up or down)
352 // * 2 bilinear Y-passes with 2 bilinear X-passes 337 // * 2 bilinear Y-passes with 2 bilinear X-passes
353 // * 1 bilinear Y-pass with N bilinear X-pass 338 // * 1 bilinear Y-pass with N bilinear X-pass
354 // * N bilinear Y-passes with 1 bilinear X-pass (down only) 339 // * N bilinear Y-passes with 1 bilinear X-pass (down only)
355 // Measurements indicate that generalizing this for 3x3 and 4x4 340 // Measurements indicate that generalizing this for 3x3 and 4x4
356 // makes it slower on some platforms, such as the Pixel. 341 // makes it slower on some platforms, such as the Pixel.
357 if (!scale_x && x_ops->size() > 0 && 342 if (!scale_x && x_ops->size() > 0 && x_ops->front().scale_factor <= 2) {
358 x_ops->front().scale_factor <= 2) {
359 int x_passes = 0; 343 int x_passes = 0;
360 if (current_shader == SHADER_BILINEAR2 && x_ops->size() >= 2) { 344 if (current_shader == SHADER_BILINEAR2 && x_ops->size() >= 2) {
361 // 2y + 2x passes 345 // 2y + 2x passes
362 x_passes = 2; 346 x_passes = 2;
363 current_shader = SHADER_BILINEAR2X2; 347 current_shader = SHADER_BILINEAR2X2;
364 } else if (current_shader == SHADER_BILINEAR) { 348 } else if (current_shader == SHADER_BILINEAR) {
365 // 1y + Nx passes 349 // 1y + Nx passes
366 scale_x = true; 350 scale_x = true;
367 switch (x_ops->size()) { 351 switch (x_ops->size()) {
368 case 0: 352 case 0:
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
408 } 392 }
409 } 393 }
410 394
411 void GLHelperScaling::ComputeScalerStages( 395 void GLHelperScaling::ComputeScalerStages(
412 GLHelper::ScalerQuality quality, 396 GLHelper::ScalerQuality quality,
413 const gfx::Size& src_size, 397 const gfx::Size& src_size,
414 const gfx::Rect& src_subrect, 398 const gfx::Rect& src_subrect,
415 const gfx::Size& dst_size, 399 const gfx::Size& dst_size,
416 bool vertically_flip_texture, 400 bool vertically_flip_texture,
417 bool swizzle, 401 bool swizzle,
418 std::vector<ScalerStage> *scaler_stages) { 402 std::vector<ScalerStage>* scaler_stages) {
419 if (quality == GLHelper::SCALER_QUALITY_FAST || 403 if (quality == GLHelper::SCALER_QUALITY_FAST ||
420 src_subrect.size() == dst_size) { 404 src_subrect.size() == dst_size) {
421 scaler_stages->push_back(ScalerStage(SHADER_BILINEAR, 405 scaler_stages->push_back(ScalerStage(SHADER_BILINEAR,
422 src_size, 406 src_size,
423 src_subrect, 407 src_subrect,
424 dst_size, 408 dst_size,
425 false, 409 false,
426 vertically_flip_texture, 410 vertically_flip_texture,
427 swizzle)); 411 swizzle));
428 return; 412 return;
429 } 413 }
430 414
431 std::deque<GLHelperScaling::ScaleOp> x_ops, y_ops; 415 std::deque<GLHelperScaling::ScaleOp> x_ops, y_ops;
432 GLHelperScaling::ScaleOp::AddOps(src_subrect.width(), 416 GLHelperScaling::ScaleOp::AddOps(src_subrect.width(),
433 dst_size.width(), 417 dst_size.width(),
434 true, 418 true,
435 quality == GLHelper::SCALER_QUALITY_GOOD, 419 quality == GLHelper::SCALER_QUALITY_GOOD,
436 &x_ops); 420 &x_ops);
437 GLHelperScaling::ScaleOp::AddOps(src_subrect.height(), 421 GLHelperScaling::ScaleOp::AddOps(src_subrect.height(),
438 dst_size.height(), 422 dst_size.height(),
439 false, 423 false,
440 quality == GLHelper::SCALER_QUALITY_GOOD, 424 quality == GLHelper::SCALER_QUALITY_GOOD,
441 &y_ops); 425 &y_ops);
442 426
443 ConvertScalerOpsToScalerStages( 427 ConvertScalerOpsToScalerStages(quality,
444 quality, 428 src_size,
445 src_size, 429 src_subrect,
446 src_subrect, 430 dst_size,
447 dst_size, 431 vertically_flip_texture,
448 vertically_flip_texture, 432 swizzle,
449 swizzle, 433 &x_ops,
450 &x_ops, 434 &y_ops,
451 &y_ops, 435 scaler_stages);
452 scaler_stages);
453 } 436 }
454 437
455 GLHelper::ScalerInterface* 438 GLHelper::ScalerInterface* GLHelperScaling::CreateScaler(
456 GLHelperScaling::CreateScaler(GLHelper::ScalerQuality quality, 439 GLHelper::ScalerQuality quality,
457 gfx::Size src_size, 440 gfx::Size src_size,
458 gfx::Rect src_subrect, 441 gfx::Rect src_subrect,
459 const gfx::Size& dst_size, 442 const gfx::Size& dst_size,
460 bool vertically_flip_texture, 443 bool vertically_flip_texture,
461 bool swizzle) { 444 bool swizzle) {
462 std::vector<ScalerStage> scaler_stages; 445 std::vector<ScalerStage> scaler_stages;
463 ComputeScalerStages(quality, 446 ComputeScalerStages(quality,
464 src_size, 447 src_size,
465 src_subrect, 448 src_subrect,
466 dst_size, 449 dst_size,
467 vertically_flip_texture, 450 vertically_flip_texture,
468 swizzle, 451 swizzle,
469 &scaler_stages); 452 &scaler_stages);
470 453
471 ScalerImpl* ret = NULL; 454 ScalerImpl* ret = NULL;
472 for (unsigned int i = 0; i < scaler_stages.size(); i++) { 455 for (unsigned int i = 0; i < scaler_stages.size(); i++) {
473 ret = new ScalerImpl(context_, this, scaler_stages[i], ret, NULL); 456 ret = new ScalerImpl(gl_, this, scaler_stages[i], ret, NULL);
474 } 457 }
475 return ret; 458 return ret;
476 } 459 }
477 460
478 GLHelper::ScalerInterface* 461 GLHelper::ScalerInterface* GLHelperScaling::CreatePlanarScaler(
479 GLHelperScaling::CreatePlanarScaler(
480 const gfx::Size& src_size, 462 const gfx::Size& src_size,
481 const gfx::Rect& src_subrect, 463 const gfx::Rect& src_subrect,
482 const gfx::Size& dst_size, 464 const gfx::Size& dst_size,
483 bool vertically_flip_texture, 465 bool vertically_flip_texture,
484 const float color_weights[4]) { 466 const float color_weights[4]) {
485 ScalerStage stage(SHADER_PLANAR, 467 ScalerStage stage(SHADER_PLANAR,
486 src_size, 468 src_size,
487 src_subrect, 469 src_subrect,
488 dst_size, 470 dst_size,
489 true, 471 true,
490 vertically_flip_texture, 472 vertically_flip_texture,
491 false); 473 false);
492 return new ScalerImpl(context_, this, stage, NULL, color_weights); 474 return new ScalerImpl(gl_, this, stage, NULL, color_weights);
493 } 475 }
494 476
495 GLHelperScaling::ShaderInterface* 477 GLHelperScaling::ShaderInterface* GLHelperScaling::CreateYuvMrtShader(
496 GLHelperScaling::CreateYuvMrtShader(
497 const gfx::Size& src_size, 478 const gfx::Size& src_size,
498 const gfx::Rect& src_subrect, 479 const gfx::Rect& src_subrect,
499 const gfx::Size& dst_size, 480 const gfx::Size& dst_size,
500 bool vertically_flip_texture, 481 bool vertically_flip_texture,
501 ShaderType shader) { 482 ShaderType shader) {
502 DCHECK(shader == SHADER_YUV_MRT_PASS1 || shader == SHADER_YUV_MRT_PASS2); 483 DCHECK(shader == SHADER_YUV_MRT_PASS1 || shader == SHADER_YUV_MRT_PASS2);
503 ScalerStage stage(shader, 484 ScalerStage stage(shader,
504 src_size, 485 src_size,
505 src_subrect, 486 src_subrect,
506 dst_size, 487 dst_size,
507 true, 488 true,
508 vertically_flip_texture, 489 vertically_flip_texture,
509 false); 490 false);
510 return new ScalerImpl(context_, this, stage, NULL, NULL); 491 return new ScalerImpl(gl_, this, stage, NULL, NULL);
511 } 492 }
512 493
513 const blink::WGC3Dfloat GLHelperScaling::kVertexAttributes[] = { 494 const GLfloat GLHelperScaling::kVertexAttributes[] = {
514 -1.0f, -1.0f, 0.0f, 0.0f, 495 -1.0f, -1.0f, 0.0f, 0.0f, // vertex 0
515 1.0f, -1.0f, 1.0f, 0.0f, 496 1.0f, -1.0f, 1.0f, 0.0f, // vertex 1
516 -1.0f, 1.0f, 0.0f, 1.0f, 497 -1.0f, 1.0f, 0.0f, 1.0f, // vertex 2
517 1.0f, 1.0f, 1.0f, 1.0f, 498 1.0f, 1.0f, 1.0f, 1.0f, }; // vertex 3
518 };
519 499
520 void GLHelperScaling::InitBuffer() { 500 void GLHelperScaling::InitBuffer() {
521 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( 501 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(gl_,
522 context_, vertex_attributes_buffer_); 502 vertex_attributes_buffer_);
523 context_->bufferData(GL_ARRAY_BUFFER, 503 gl_->BufferData(GL_ARRAY_BUFFER,
524 sizeof(kVertexAttributes), 504 sizeof(kVertexAttributes),
525 kVertexAttributes, 505 kVertexAttributes,
526 GL_STATIC_DRAW); 506 GL_STATIC_DRAW);
527 } 507 }
528 508
529 scoped_refptr<ShaderProgram> 509 scoped_refptr<ShaderProgram> GLHelperScaling::GetShaderProgram(ShaderType type,
530 GLHelperScaling::GetShaderProgram(ShaderType type, 510 bool swizzle) {
531 bool swizzle) {
532 ShaderProgramKeyType key(type, swizzle); 511 ShaderProgramKeyType key(type, swizzle);
533 scoped_refptr<ShaderProgram>& cache_entry(shader_programs_[key]); 512 scoped_refptr<ShaderProgram>& cache_entry(shader_programs_[key]);
534 if (!cache_entry.get()) { 513 if (!cache_entry.get()) {
535 cache_entry = new ShaderProgram(context_, helper_); 514 cache_entry = new ShaderProgram(gl_, helper_);
536 std::basic_string<blink::WGC3Dchar> vertex_program; 515 std::basic_string<GLchar> vertex_program;
537 std::basic_string<blink::WGC3Dchar> fragment_program; 516 std::basic_string<GLchar> fragment_program;
538 std::basic_string<blink::WGC3Dchar> vertex_header; 517 std::basic_string<GLchar> vertex_header;
539 std::basic_string<blink::WGC3Dchar> fragment_directives; 518 std::basic_string<GLchar> fragment_directives;
540 std::basic_string<blink::WGC3Dchar> fragment_header; 519 std::basic_string<GLchar> fragment_header;
541 std::basic_string<blink::WGC3Dchar> shared_variables; 520 std::basic_string<GLchar> shared_variables;
542 521
543 vertex_header.append( 522 vertex_header.append(
544 "precision highp float;\n" 523 "precision highp float;\n"
545 "attribute vec2 a_position;\n" 524 "attribute vec2 a_position;\n"
546 "attribute vec2 a_texcoord;\n" 525 "attribute vec2 a_texcoord;\n"
547 "uniform vec4 src_subrect;\n"); 526 "uniform vec4 src_subrect;\n");
548 527
549 fragment_header.append( 528 fragment_header.append(
550 "precision mediump float;\n" 529 "precision mediump float;\n"
551 "uniform sampler2D s_texture;\n"); 530 "uniform sampler2D s_texture;\n");
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 " v_texcoords2 = texcoord - step;\n"); 578 " v_texcoords2 = texcoord - step;\n");
600 fragment_program.append( 579 fragment_program.append(
601 " gl_FragColor = (texture2D(s_texture, v_texcoords1.xy) +\n" 580 " gl_FragColor = (texture2D(s_texture, v_texcoords1.xy) +\n"
602 " texture2D(s_texture, v_texcoords1.zw) +\n" 581 " texture2D(s_texture, v_texcoords1.zw) +\n"
603 " texture2D(s_texture, v_texcoords2)) / 3.0;\n"); 582 " texture2D(s_texture, v_texcoords2)) / 3.0;\n");
604 break; 583 break;
605 584
606 case SHADER_BILINEAR4: 585 case SHADER_BILINEAR4:
607 // This is equivialent to three passes of the BILINEAR shader above, 586 // This is equivialent to three passes of the BILINEAR shader above,
608 // It can be used to scale an image down 2.0x-4.0x or exactly 8x. 587 // It can be used to scale an image down 2.0x-4.0x or exactly 8x.
609 shared_variables.append( 588 shared_variables.append("varying vec4 v_texcoords[2];\n");
610 "varying vec4 v_texcoords[2];\n");
611 vertex_header.append( 589 vertex_header.append(
612 "uniform vec2 scaling_vector;\n" 590 "uniform vec2 scaling_vector;\n"
613 "uniform vec2 dst_pixelsize;\n"); 591 "uniform vec2 dst_pixelsize;\n");
614 vertex_program.append( 592 vertex_program.append(
615 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n" 593 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
616 " step /= 8.0;\n" 594 " step /= 8.0;\n"
617 " v_texcoords[0].xy = texcoord - step * 3.0;\n" 595 " v_texcoords[0].xy = texcoord - step * 3.0;\n"
618 " v_texcoords[0].zw = texcoord - step;\n" 596 " v_texcoords[0].zw = texcoord - step;\n"
619 " v_texcoords[1].xy = texcoord + step;\n" 597 " v_texcoords[1].xy = texcoord + step;\n"
620 " v_texcoords[1].zw = texcoord + step * 3.0;\n"); 598 " v_texcoords[1].zw = texcoord + step * 3.0;\n");
621 fragment_program.append( 599 fragment_program.append(
622 " gl_FragColor = (\n" 600 " gl_FragColor = (\n"
623 " texture2D(s_texture, v_texcoords[0].xy) +\n" 601 " texture2D(s_texture, v_texcoords[0].xy) +\n"
624 " texture2D(s_texture, v_texcoords[0].zw) +\n" 602 " texture2D(s_texture, v_texcoords[0].zw) +\n"
625 " texture2D(s_texture, v_texcoords[1].xy) +\n" 603 " texture2D(s_texture, v_texcoords[1].xy) +\n"
626 " texture2D(s_texture, v_texcoords[1].zw)) / 4.0;\n"); 604 " texture2D(s_texture, v_texcoords[1].zw)) / 4.0;\n");
627 break; 605 break;
628 606
629 case SHADER_BILINEAR2X2: 607 case SHADER_BILINEAR2X2:
630 // This is equivialent to four passes of the BILINEAR shader above. 608 // This is equivialent to four passes of the BILINEAR shader above.
631 // Two in each dimension. It can be used to scale an image down 609 // Two in each dimension. It can be used to scale an image down
632 // 1.0x-2.0x in both X and Y directions. Or, it could be used to 610 // 1.0x-2.0x in both X and Y directions. Or, it could be used to
633 // scale an image down by exactly 4x in both dimensions. 611 // scale an image down by exactly 4x in both dimensions.
634 shared_variables.append( 612 shared_variables.append("varying vec4 v_texcoords[2];\n");
635 "varying vec4 v_texcoords[2];\n"); 613 vertex_header.append("uniform vec2 dst_pixelsize;\n");
636 vertex_header.append(
637 "uniform vec2 dst_pixelsize;\n");
638 vertex_program.append( 614 vertex_program.append(
639 " vec2 step = src_subrect.zw / 4.0 / dst_pixelsize;\n" 615 " vec2 step = src_subrect.zw / 4.0 / dst_pixelsize;\n"
640 " v_texcoords[0].xy = texcoord + vec2(step.x, step.y);\n" 616 " v_texcoords[0].xy = texcoord + vec2(step.x, step.y);\n"
641 " v_texcoords[0].zw = texcoord + vec2(step.x, -step.y);\n" 617 " v_texcoords[0].zw = texcoord + vec2(step.x, -step.y);\n"
642 " v_texcoords[1].xy = texcoord + vec2(-step.x, step.y);\n" 618 " v_texcoords[1].xy = texcoord + vec2(-step.x, step.y);\n"
643 " v_texcoords[1].zw = texcoord + vec2(-step.x, -step.y);\n"); 619 " v_texcoords[1].zw = texcoord + vec2(-step.x, -step.y);\n");
644 fragment_program.append( 620 fragment_program.append(
645 " gl_FragColor = (\n" 621 " gl_FragColor = (\n"
646 " texture2D(s_texture, v_texcoords[0].xy) +\n" 622 " texture2D(s_texture, v_texcoords[0].xy) +\n"
647 " texture2D(s_texture, v_texcoords[0].zw) +\n" 623 " texture2D(s_texture, v_texcoords[0].zw) +\n"
(...skipping 23 matching lines...) Expand all
671 fragment_program.append( 647 fragment_program.append(
672 " gl_FragColor = \n" 648 " gl_FragColor = \n"
673 // Lobe pixels 649 // Lobe pixels
674 " (texture2D(s_texture, v_texcoords[0].xy) +\n" 650 " (texture2D(s_texture, v_texcoords[0].xy) +\n"
675 " texture2D(s_texture, v_texcoords[1].zw)) *\n" 651 " texture2D(s_texture, v_texcoords[1].zw)) *\n"
676 " LobeWeight +\n" 652 " LobeWeight +\n"
677 // Center pixels 653 // Center pixels
678 " (texture2D(s_texture, v_texcoords[0].zw) +\n" 654 " (texture2D(s_texture, v_texcoords[0].zw) +\n"
679 " texture2D(s_texture, v_texcoords[1].xy)) *\n" 655 " texture2D(s_texture, v_texcoords[1].xy)) *\n"
680 " CenterWeight;\n"); 656 " CenterWeight;\n");
681 break; 657 break;
682 658
683 case SHADER_BICUBIC_UPSCALE: 659 case SHADER_BICUBIC_UPSCALE:
684 // When scaling up, we need 4 texture reads, but we can 660 // When scaling up, we need 4 texture reads, but we can
685 // save some instructions because will know in which range of 661 // save some instructions because will know in which range of
686 // the bicubic function each call call to the bicubic function 662 // the bicubic function each call call to the bicubic function
687 // will be in. 663 // will be in.
688 // Also, when sampling the bicubic function like this, the sum 664 // Also, when sampling the bicubic function like this, the sum
689 // is always exactly one, so we can skip normalization as well. 665 // is always exactly one, so we can skip normalization as well.
690 shared_variables.append( 666 shared_variables.append("varying vec2 v_texcoord;\n");
691 "varying vec2 v_texcoord;\n"); 667 vertex_program.append(" v_texcoord = texcoord;\n");
692 vertex_program.append(
693 " v_texcoord = texcoord;\n");
694 fragment_header.append( 668 fragment_header.append(
695 "uniform vec2 src_pixelsize;\n" 669 "uniform vec2 src_pixelsize;\n"
696 "uniform vec2 scaling_vector;\n" 670 "uniform vec2 scaling_vector;\n"
697 "const float a = -0.5;\n" 671 "const float a = -0.5;\n"
698 // This function is equivialent to calling the bicubic 672 // This function is equivialent to calling the bicubic
699 // function with x-1, x, 1-x and 2-x 673 // function with x-1, x, 1-x and 2-x
700 // (assuming 0 <= x < 1) 674 // (assuming 0 <= x < 1)
701 "vec4 filt4(float x) {\n" 675 "vec4 filt4(float x) {\n"
702 " return vec4(x * x * x, x * x, x, 1) *\n" 676 " return vec4(x * x * x, x * x, x, 1) *\n"
703 " mat4( a, -2.0 * a, a, 0.0,\n" 677 " mat4( a, -2.0 * a, a, 0.0,\n"
(...skipping 17 matching lines...) Expand all
721 " gl_FragColor = pixels_x(base, step) * filt4(frac);\n"); 695 " gl_FragColor = pixels_x(base, step) * filt4(frac);\n");
722 break; 696 break;
723 697
724 case SHADER_PLANAR: 698 case SHADER_PLANAR:
725 // Converts four RGBA pixels into one pixel. Each RGBA 699 // Converts four RGBA pixels into one pixel. Each RGBA
726 // pixel will be dot-multiplied with the color weights and 700 // pixel will be dot-multiplied with the color weights and
727 // then placed into a component of the output. This is used to 701 // then placed into a component of the output. This is used to
728 // convert RGBA textures into Y, U and V textures. We do this 702 // convert RGBA textures into Y, U and V textures. We do this
729 // because single-component textures are not renderable on all 703 // because single-component textures are not renderable on all
730 // architectures. 704 // architectures.
731 shared_variables.append( 705 shared_variables.append("varying vec4 v_texcoords[2];\n");
732 "varying vec4 v_texcoords[2];\n");
733 vertex_header.append( 706 vertex_header.append(
734 "uniform vec2 scaling_vector;\n" 707 "uniform vec2 scaling_vector;\n"
735 "uniform vec2 dst_pixelsize;\n"); 708 "uniform vec2 dst_pixelsize;\n");
736 vertex_program.append( 709 vertex_program.append(
737 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n" 710 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
738 " step /= 4.0;\n" 711 " step /= 4.0;\n"
739 " v_texcoords[0].xy = texcoord - step * 1.5;\n" 712 " v_texcoords[0].xy = texcoord - step * 1.5;\n"
740 " v_texcoords[0].zw = texcoord - step * 0.5;\n" 713 " v_texcoords[0].zw = texcoord - step * 0.5;\n"
741 " v_texcoords[1].xy = texcoord + step * 0.5;\n" 714 " v_texcoords[1].xy = texcoord + step * 0.5;\n"
742 " v_texcoords[1].zw = texcoord + step * 1.5;\n"); 715 " v_texcoords[1].zw = texcoord + step * 1.5;\n");
743 fragment_header.append( 716 fragment_header.append("uniform vec4 color_weights;\n");
744 "uniform vec4 color_weights;\n");
745 fragment_program.append( 717 fragment_program.append(
746 " gl_FragColor = color_weights * mat4(\n" 718 " gl_FragColor = color_weights * mat4(\n"
747 " vec4(texture2D(s_texture, v_texcoords[0].xy).rgb, 1.0),\n" 719 " vec4(texture2D(s_texture, v_texcoords[0].xy).rgb, 1.0),\n"
748 " vec4(texture2D(s_texture, v_texcoords[0].zw).rgb, 1.0),\n" 720 " vec4(texture2D(s_texture, v_texcoords[0].zw).rgb, 1.0),\n"
749 " vec4(texture2D(s_texture, v_texcoords[1].xy).rgb, 1.0),\n" 721 " vec4(texture2D(s_texture, v_texcoords[1].xy).rgb, 1.0),\n"
750 " vec4(texture2D(s_texture, v_texcoords[1].zw).rgb, 1.0));\n"); 722 " vec4(texture2D(s_texture, v_texcoords[1].zw).rgb, 1.0));\n");
751 // Swizzle makes no sense for this shader. 723 // Swizzle makes no sense for this shader.
752 DCHECK(!swizzle); 724 DCHECK(!swizzle);
753 break; 725 break;
754 726
(...skipping 16 matching lines...) Expand all
771 // YYYY YYYY UUVV UUVV 743 // YYYY YYYY UUVV UUVV
772 // First YYYY YYYY UUVV UUVV 744 // First YYYY YYYY UUVV UUVV
773 // pass YYYY YYYY UUVV UUVV 745 // pass YYYY YYYY UUVV UUVV
774 // YYYY YYYY UUVV UUVV 746 // YYYY YYYY UUVV UUVV
775 // | 747 // |
776 // | (u plane) (v plane) 748 // | (u plane) (v plane)
777 // Second | UUUU VVVV 749 // Second | UUUU VVVV
778 // pass +--> { UUUU + VVVV } 750 // pass +--> { UUUU + VVVV }
779 // UUUU VVVV 751 // UUUU VVVV
780 // 752 //
781 shared_variables.append( 753 shared_variables.append("varying vec4 v_texcoords[2];\n");
782 "varying vec4 v_texcoords[2];\n");
783 vertex_header.append( 754 vertex_header.append(
784 "uniform vec2 scaling_vector;\n" 755 "uniform vec2 scaling_vector;\n"
785 "uniform vec2 dst_pixelsize;\n"); 756 "uniform vec2 dst_pixelsize;\n");
786 vertex_program.append( 757 vertex_program.append(
787 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n" 758 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
788 " step /= 4.0;\n" 759 " step /= 4.0;\n"
789 " v_texcoords[0].xy = texcoord - step * 1.5;\n" 760 " v_texcoords[0].xy = texcoord - step * 1.5;\n"
790 " v_texcoords[0].zw = texcoord - step * 0.5;\n" 761 " v_texcoords[0].zw = texcoord - step * 0.5;\n"
791 " v_texcoords[1].xy = texcoord + step * 0.5;\n" 762 " v_texcoords[1].xy = texcoord + step * 0.5;\n"
792 " v_texcoords[1].zw = texcoord + step * 1.5;\n"); 763 " v_texcoords[1].zw = texcoord + step * 1.5;\n");
793 fragment_directives.append( 764 fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
794 "#extension GL_EXT_draw_buffers : enable\n");
795 fragment_header.append( 765 fragment_header.append(
796 "const vec3 kRGBtoY = vec3(0.257, 0.504, 0.098);\n" 766 "const vec3 kRGBtoY = vec3(0.257, 0.504, 0.098);\n"
797 "const float kYBias = 0.0625;\n" 767 "const float kYBias = 0.0625;\n"
798 // Divide U and V by two to compensate for averaging below. 768 // Divide U and V by two to compensate for averaging below.
799 "const vec3 kRGBtoU = vec3(-0.148, -0.291, 0.439) / 2.0;\n" 769 "const vec3 kRGBtoU = vec3(-0.148, -0.291, 0.439) / 2.0;\n"
800 "const vec3 kRGBtoV = vec3(0.439, -0.368, -0.071) / 2.0;\n" 770 "const vec3 kRGBtoV = vec3(0.439, -0.368, -0.071) / 2.0;\n"
801 "const float kUVBias = 0.5;\n"); 771 "const float kUVBias = 0.5;\n");
802 fragment_program.append( 772 fragment_program.append(
803 " vec3 pixel1 = texture2D(s_texture, v_texcoords[0].xy).rgb;\n" 773 " vec3 pixel1 = texture2D(s_texture, v_texcoords[0].xy).rgb;\n"
804 " vec3 pixel2 = texture2D(s_texture, v_texcoords[0].zw).rgb;\n" 774 " vec3 pixel2 = texture2D(s_texture, v_texcoords[0].zw).rgb;\n"
(...skipping 10 matching lines...) Expand all
815 " dot(pixel12, kRGBtoV),\n" 785 " dot(pixel12, kRGBtoV),\n"
816 " dot(pixel34, kRGBtoV)) + kUVBias;\n"); 786 " dot(pixel34, kRGBtoV)) + kUVBias;\n");
817 // Swizzle makes no sense for this shader. 787 // Swizzle makes no sense for this shader.
818 DCHECK(!swizzle); 788 DCHECK(!swizzle);
819 break; 789 break;
820 790
821 case SHADER_YUV_MRT_PASS2: 791 case SHADER_YUV_MRT_PASS2:
822 // We're just sampling two pixels and unswizzling them. There's 792 // We're just sampling two pixels and unswizzling them. There's
823 // no need to do vertical scaling with math, since bilinear 793 // no need to do vertical scaling with math, since bilinear
824 // interpolation in the sampler takes care of that. 794 // interpolation in the sampler takes care of that.
825 shared_variables.append( 795 shared_variables.append("varying vec4 v_texcoords;\n");
826 "varying vec4 v_texcoords;\n");
827 vertex_header.append( 796 vertex_header.append(
828 "uniform vec2 scaling_vector;\n" 797 "uniform vec2 scaling_vector;\n"
829 "uniform vec2 dst_pixelsize;\n"); 798 "uniform vec2 dst_pixelsize;\n");
830 vertex_program.append( 799 vertex_program.append(
831 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n" 800 " vec2 step = scaling_vector * src_subrect.zw / dst_pixelsize;\n"
832 " step /= 2.0;\n" 801 " step /= 2.0;\n"
833 " v_texcoords.xy = texcoord - step * 0.5;\n" 802 " v_texcoords.xy = texcoord - step * 0.5;\n"
834 " v_texcoords.zw = texcoord + step * 0.5;\n"); 803 " v_texcoords.zw = texcoord + step * 0.5;\n");
835 fragment_directives.append( 804 fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
836 "#extension GL_EXT_draw_buffers : enable\n");
837 fragment_program.append( 805 fragment_program.append(
838 " vec4 lo_uuvv = texture2D(s_texture, v_texcoords.xy);\n" 806 " vec4 lo_uuvv = texture2D(s_texture, v_texcoords.xy);\n"
839 " vec4 hi_uuvv = texture2D(s_texture, v_texcoords.zw);\n" 807 " vec4 hi_uuvv = texture2D(s_texture, v_texcoords.zw);\n"
840 " gl_FragData[0] = vec4(lo_uuvv.rg, hi_uuvv.rg);\n" 808 " gl_FragData[0] = vec4(lo_uuvv.rg, hi_uuvv.rg);\n"
841 " gl_FragData[1] = vec4(lo_uuvv.ba, hi_uuvv.ba);\n"); 809 " gl_FragData[1] = vec4(lo_uuvv.ba, hi_uuvv.ba);\n");
842 // Swizzle makes no sense for this shader. 810 // Swizzle makes no sense for this shader.
843 DCHECK(!swizzle); 811 DCHECK(!swizzle);
844 break; 812 break;
845 } 813 }
846 if (swizzle) { 814 if (swizzle) {
847 fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n"); 815 fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n");
848 } 816 }
849 817
850 vertex_program = 818 vertex_program = vertex_header + shared_variables + "void main() {\n" +
851 vertex_header + 819 vertex_program + "}\n";
852 shared_variables +
853 "void main() {\n" +
854 vertex_program +
855 "}\n";
856 820
857 fragment_program = 821 fragment_program = fragment_directives + fragment_header +
858 fragment_directives + 822 shared_variables + "void main() {\n" + fragment_program +
859 fragment_header + 823 "}\n";
860 shared_variables +
861 "void main() {\n" +
862 fragment_program +
863 "}\n";
864 824
865 bool result = cache_entry->Setup(vertex_program.c_str(), 825 cache_entry->Setup(vertex_program.c_str(), fragment_program.c_str());
866 fragment_program.c_str());
867 DCHECK(result || context_->isContextLost())
868 << "vertex_program =\n" << vertex_program
869 << "fragment_program =\n" << fragment_program;
870 } 826 }
871 return cache_entry; 827 return cache_entry;
872 } 828 }
873 829
874 bool ShaderProgram::Setup(const blink::WGC3Dchar* vertex_shader_text, 830 void ShaderProgram::Setup(const GLchar* vertex_shader_text,
875 const blink::WGC3Dchar* fragment_shader_text) { 831 const GLchar* fragment_shader_text) {
876 // Shaders to map the source texture to |dst_texture_|. 832 // Shaders to map the source texture to |dst_texture_|.
877 ScopedShader vertex_shader(context_, helper_->CompileShaderFromSource( 833 GLuint vertex_shader =
878 vertex_shader_text, GL_VERTEX_SHADER)); 834 helper_->CompileShaderFromSource(vertex_shader_text, GL_VERTEX_SHADER);
879 if (vertex_shader.id() == 0) { 835 if (vertex_shader == 0)
880 return false; 836 return;
881 }
882 context_->attachShader(program_, vertex_shader);
883 ScopedShader fragment_shader(context_, helper_->CompileShaderFromSource(
884 fragment_shader_text, GL_FRAGMENT_SHADER));
885 if (fragment_shader.id() == 0) {
886 return false;
887 }
888 context_->attachShader(program_, fragment_shader);
889 context_->linkProgram(program_);
890 837
891 blink::WGC3Dint link_status = 0; 838 gl_->AttachShader(program_, vertex_shader);
892 context_->getProgramiv(program_, GL_LINK_STATUS, &link_status); 839 gl_->DeleteShader(vertex_shader);
893 if (!link_status) { 840
894 LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8()); 841 GLuint fragment_shader = helper_->CompileShaderFromSource(
895 return false; 842 fragment_shader_text, GL_FRAGMENT_SHADER);
896 } 843 if (fragment_shader == 0)
897 position_location_ = context_->getAttribLocation(program_, "a_position"); 844 return;
898 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord"); 845 gl_->AttachShader(program_, fragment_shader);
899 texture_location_ = context_->getUniformLocation(program_, "s_texture"); 846 gl_->DeleteShader(fragment_shader);
900 src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect"); 847
901 src_pixelsize_location_ = context_->getUniformLocation(program_, 848 gl_->LinkProgram(program_);
902 "src_pixelsize"); 849
903 dst_pixelsize_location_ = context_->getUniformLocation(program_, 850 GLint link_status = 0;
904 "dst_pixelsize"); 851 gl_->GetProgramiv(program_, GL_LINK_STATUS, &link_status);
905 scaling_vector_location_ = context_->getUniformLocation(program_, 852 if (!link_status)
906 "scaling_vector"); 853 return;
907 color_weights_location_ = context_->getUniformLocation(program_, 854
908 "color_weights"); 855 position_location_ = gl_->GetAttribLocation(program_, "a_position");
909 return true; 856 texcoord_location_ = gl_->GetAttribLocation(program_, "a_texcoord");
857 texture_location_ = gl_->GetUniformLocation(program_, "s_texture");
858 src_subrect_location_ = gl_->GetUniformLocation(program_, "src_subrect");
859 src_pixelsize_location_ = gl_->GetUniformLocation(program_, "src_pixelsize");
860 dst_pixelsize_location_ = gl_->GetUniformLocation(program_, "dst_pixelsize");
861 scaling_vector_location_ =
862 gl_->GetUniformLocation(program_, "scaling_vector");
863 color_weights_location_ = gl_->GetUniformLocation(program_, "color_weights");
864 return;
910 } 865 }
911 866
912 void ShaderProgram::UseProgram( 867 void ShaderProgram::UseProgram(const gfx::Size& src_size,
913 const gfx::Size& src_size, 868 const gfx::Rect& src_subrect,
914 const gfx::Rect& src_subrect, 869 const gfx::Size& dst_size,
915 const gfx::Size& dst_size, 870 bool scale_x,
916 bool scale_x, 871 bool flip_y,
917 bool flip_y, 872 GLfloat color_weights[4]) {
918 GLfloat color_weights[4]) { 873 gl_->UseProgram(program_);
919 context_->useProgram(program_);
920 874
921 blink::WGC3Dintptr offset = 0; 875 // OpenGL defines the last parameter to VertexAttribPointer as type
922 context_->vertexAttribPointer(position_location_, 876 // "const GLvoid*" even though it is actually an offset into the buffer
923 2, 877 // object's data store and not a pointer to the client's address space.
924 GL_FLOAT, 878 const void* offsets[2] = {
925 GL_FALSE, 879 0, reinterpret_cast<const void*>(2 * sizeof(GLfloat))
926 4 * sizeof(blink::WGC3Dfloat), 880 };
927 offset);
928 context_->enableVertexAttribArray(position_location_);
929 881
930 offset += 2 * sizeof(blink::WGC3Dfloat); 882 gl_->VertexAttribPointer(position_location_,
931 context_->vertexAttribPointer(texcoord_location_, 883 2,
932 2, 884 GL_FLOAT,
933 GL_FLOAT, 885 GL_FALSE,
934 GL_FALSE, 886 4 * sizeof(GLfloat),
935 4 * sizeof(blink::WGC3Dfloat), 887 offsets[0]);
936 offset); 888 gl_->EnableVertexAttribArray(position_location_);
937 context_->enableVertexAttribArray(texcoord_location_);
938 889
939 context_->uniform1i(texture_location_, 0); 890 gl_->VertexAttribPointer(texcoord_location_,
891 2,
892 GL_FLOAT,
893 GL_FALSE,
894 4 * sizeof(GLfloat),
895 offsets[1]);
896 gl_->EnableVertexAttribArray(texcoord_location_);
897
898 gl_->Uniform1i(texture_location_, 0);
940 899
941 // Convert |src_subrect| to texture coordinates. 900 // Convert |src_subrect| to texture coordinates.
942 GLfloat src_subrect_texcoord[] = { 901 GLfloat src_subrect_texcoord[] = {
943 static_cast<float>(src_subrect.x()) / src_size.width(), 902 static_cast<float>(src_subrect.x()) / src_size.width(),
944 static_cast<float>(src_subrect.y()) / src_size.height(), 903 static_cast<float>(src_subrect.y()) / src_size.height(),
945 static_cast<float>(src_subrect.width()) / src_size.width(), 904 static_cast<float>(src_subrect.width()) / src_size.width(),
946 static_cast<float>(src_subrect.height()) / src_size.height(), 905 static_cast<float>(src_subrect.height()) / src_size.height(), };
947 };
948 if (flip_y) { 906 if (flip_y) {
949 src_subrect_texcoord[1] += src_subrect_texcoord[3]; 907 src_subrect_texcoord[1] += src_subrect_texcoord[3];
950 src_subrect_texcoord[3] *= -1.0; 908 src_subrect_texcoord[3] *= -1.0;
951 } 909 }
952 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord); 910 gl_->Uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
953 911
954 context_->uniform2f(src_pixelsize_location_, 912 gl_->Uniform2f(src_pixelsize_location_, src_size.width(), src_size.height());
955 src_size.width(), 913 gl_->Uniform2f(dst_pixelsize_location_,
956 src_size.height()); 914 static_cast<float>(dst_size.width()),
957 context_->uniform2f(dst_pixelsize_location_, 915 static_cast<float>(dst_size.height()));
958 static_cast<float>(dst_size.width()),
959 static_cast<float>(dst_size.height()));
960 916
961 context_->uniform2f(scaling_vector_location_, 917 gl_->Uniform2f(
962 scale_x ? 1.0 : 0.0, 918 scaling_vector_location_, scale_x ? 1.0 : 0.0, scale_x ? 0.0 : 1.0);
963 scale_x ? 0.0 : 1.0); 919 gl_->Uniform4fv(color_weights_location_, 1, color_weights);
964 context_->uniform4fv(color_weights_location_, 1, color_weights);
965 } 920 }
966 921
967 } // namespace content 922 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper_scaling.h ('k') | content/common/gpu/client/gl_helper_unittests.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698