| Index: content/common/gpu/client/gl_helper_scaling.cc
|
| diff --git a/content/common/gpu/client/gl_helper_scaling.cc b/content/common/gpu/client/gl_helper_scaling.cc
|
| index ff6a6b7c8558d6c16d0f87ffff94bcc3a2a6cdc3..ce72becc0b9dfc07b025f282b550355e93e2d4a2 100644
|
| --- a/content/common/gpu/client/gl_helper_scaling.cc
|
| +++ b/content/common/gpu/client/gl_helper_scaling.cc
|
| @@ -15,44 +15,43 @@
|
| #include "base/memory/ref_counted.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/time/time.h"
|
| -#include "third_party/WebKit/public/platform/WebCString.h"
|
| +#include "gpu/command_buffer/client/gles2_interface.h"
|
| #include "third_party/skia/include/core/SkRegion.h"
|
| #include "ui/gfx/rect.h"
|
| #include "ui/gfx/size.h"
|
| -#include "ui/gl/gl_bindings.h"
|
|
|
| -using blink::WebGLId;
|
| -using blink::WebGraphicsContext3D;
|
| +using gpu::gles2::GLES2Interface;
|
|
|
| namespace content {
|
|
|
| -GLHelperScaling::GLHelperScaling(blink::WebGraphicsContext3D* context,
|
| - GLHelper* helper)
|
| - : context_(context),
|
| - helper_(helper),
|
| - vertex_attributes_buffer_(context_, context_->createBuffer()) {
|
| +GLHelperScaling::GLHelperScaling(GLES2Interface* gl, GLHelper* helper)
|
| + : gl_(gl), helper_(helper), vertex_attributes_buffer_(gl_) {
|
| InitBuffer();
|
| }
|
|
|
| -GLHelperScaling::~GLHelperScaling() {
|
| -}
|
| +GLHelperScaling::~GLHelperScaling() {}
|
|
|
| // Used to keep track of a generated shader program. The program
|
| // is passed in as text through Setup and is used by calling
|
| -// UseProgram() with the right parameters. Note that |context_|
|
| +// UseProgram() with the right parameters. Note that |gl_|
|
| // and |helper_| are assumed to live longer than this program.
|
| class ShaderProgram : public base::RefCounted<ShaderProgram> {
|
| public:
|
| - ShaderProgram(WebGraphicsContext3D* context,
|
| - GLHelper* helper)
|
| - : context_(context),
|
| + ShaderProgram(GLES2Interface* gl, GLHelper* helper)
|
| + : gl_(gl),
|
| helper_(helper),
|
| - program_(context, context->createProgram()) {
|
| - }
|
| -
|
| - // Compile shader program, return true if successful.
|
| - bool Setup(const blink::WGC3Dchar* vertex_shader_text,
|
| - const blink::WGC3Dchar* fragment_shader_text);
|
| + program_(gl_->CreateProgram()),
|
| + position_location_(-1),
|
| + texcoord_location_(-1),
|
| + src_subrect_location_(-1),
|
| + src_pixelsize_location_(-1),
|
| + dst_pixelsize_location_(-1),
|
| + scaling_vector_location_(-1),
|
| + color_weights_location_(-1) {}
|
| +
|
| + // Compile shader program.
|
| + void Setup(const GLchar* vertex_shader_text,
|
| + const GLchar* fragment_shader_text);
|
|
|
| // UseProgram must be called with GL_TEXTURE_2D bound to the
|
| // source texture and GL_ARRAY_BUFFER bound to a vertex
|
| @@ -64,47 +63,47 @@ class ShaderProgram : public base::RefCounted<ShaderProgram> {
|
| bool flip_y,
|
| GLfloat color_weights[4]);
|
|
|
| + bool Initialized() const { return position_location_ != -1; }
|
| +
|
| private:
|
| friend class base::RefCounted<ShaderProgram>;
|
| - ~ShaderProgram() {}
|
| + ~ShaderProgram() { gl_->DeleteProgram(program_); }
|
|
|
| - WebGraphicsContext3D* context_;
|
| + GLES2Interface* gl_;
|
| GLHelper* helper_;
|
|
|
| // A program for copying a source texture into a destination texture.
|
| - ScopedProgram program_;
|
| + GLuint program_;
|
|
|
| // The location of the position in the program.
|
| - blink::WGC3Dint position_location_;
|
| + GLint position_location_;
|
| // The location of the texture coordinate in the program.
|
| - blink::WGC3Dint texcoord_location_;
|
| + GLint texcoord_location_;
|
| // The location of the source texture in the program.
|
| - blink::WGC3Dint texture_location_;
|
| + GLint texture_location_;
|
| // The location of the texture coordinate of
|
| // the sub-rectangle in the program.
|
| - blink::WGC3Dint src_subrect_location_;
|
| + GLint src_subrect_location_;
|
| // Location of size of source image in pixels.
|
| - blink::WGC3Dint src_pixelsize_location_;
|
| + GLint src_pixelsize_location_;
|
| // Location of size of destination image in pixels.
|
| - blink::WGC3Dint dst_pixelsize_location_;
|
| + GLint dst_pixelsize_location_;
|
| // Location of vector for scaling direction.
|
| - blink::WGC3Dint scaling_vector_location_;
|
| + GLint scaling_vector_location_;
|
| // Location of color weights.
|
| - blink::WGC3Dint color_weights_location_;
|
| + GLint color_weights_location_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(ShaderProgram);
|
| };
|
|
|
| -
|
| // Implementation of a single stage in a scaler pipeline. If the pipeline has
|
| // multiple stages, it calls Scale() on the subscaler, then further scales the
|
| // output. Caches textures and framebuffers to avoid allocating/deleting
|
| // them once per frame, which can be expensive on some drivers.
|
| -class ScalerImpl :
|
| - public GLHelper::ScalerInterface,
|
| - public GLHelperScaling::ShaderInterface {
|
| +class ScalerImpl : public GLHelper::ScalerInterface,
|
| + public GLHelperScaling::ShaderInterface {
|
| public:
|
| - // |context| and |copy_impl| are expected to live longer than this object.
|
| + // |gl| and |copy_impl| are expected to live longer than this object.
|
| // |src_size| is the size of the input texture in pixels.
|
| // |dst_size| is the size of the output texutre in pixels.
|
| // |src_subrect| is the portion of the src to copy to the output texture.
|
| @@ -114,17 +113,17 @@ class ScalerImpl :
|
| // If |swizzle| is true, RGBA will be transformed into BGRA.
|
| // |color_weights| are only used together with SHADER_PLANAR to specify
|
| // how to convert RGB colors into a single value.
|
| - ScalerImpl(WebGraphicsContext3D* context,
|
| + ScalerImpl(GLES2Interface* gl,
|
| GLHelperScaling* scaler_helper,
|
| - const GLHelperScaling::ScalerStage &scaler_stage,
|
| + const GLHelperScaling::ScalerStage& scaler_stage,
|
| ScalerImpl* subscaler,
|
| - const float* color_weights) :
|
| - context_(context),
|
| - scaler_helper_(scaler_helper),
|
| - spec_(scaler_stage),
|
| - intermediate_texture_(0),
|
| - dst_framebuffer_(context, context_->createFramebuffer()),
|
| - subscaler_(subscaler) {
|
| + const float* color_weights)
|
| + : gl_(gl),
|
| + scaler_helper_(scaler_helper),
|
| + spec_(scaler_stage),
|
| + intermediate_texture_(0),
|
| + dst_framebuffer_(gl),
|
| + subscaler_(subscaler) {
|
| if (color_weights) {
|
| color_weights_[0] = color_weights[0];
|
| color_weights_[1] = color_weights[1];
|
| @@ -136,97 +135,87 @@ class ScalerImpl :
|
| color_weights_[2] = 0.0;
|
| color_weights_[3] = 0.0;
|
| }
|
| - shader_program_ = scaler_helper_->GetShaderProgram(spec_.shader,
|
| - spec_.swizzle);
|
| + shader_program_ =
|
| + scaler_helper_->GetShaderProgram(spec_.shader, spec_.swizzle);
|
|
|
| if (subscaler_) {
|
| - intermediate_texture_ = context_->createTexture();
|
| - ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
|
| - context_,
|
| - intermediate_texture_);
|
| - context_->texImage2D(GL_TEXTURE_2D,
|
| - 0,
|
| - GL_RGBA,
|
| - spec_.src_size.width(),
|
| - spec_.src_size.height(),
|
| - 0,
|
| - GL_RGBA,
|
| - GL_UNSIGNED_BYTE,
|
| - NULL);
|
| + intermediate_texture_ = 0u;
|
| + gl_->GenTextures(1, &intermediate_texture_);
|
| + ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_,
|
| + intermediate_texture_);
|
| + gl_->TexImage2D(GL_TEXTURE_2D,
|
| + 0,
|
| + GL_RGBA,
|
| + spec_.src_size.width(),
|
| + spec_.src_size.height(),
|
| + 0,
|
| + GL_RGBA,
|
| + GL_UNSIGNED_BYTE,
|
| + NULL);
|
| }
|
| }
|
|
|
| virtual ~ScalerImpl() {
|
| if (intermediate_texture_) {
|
| - context_->deleteTexture(intermediate_texture_);
|
| + gl_->DeleteTextures(1, &intermediate_texture_);
|
| }
|
| }
|
|
|
| // GLHelperShader::ShaderInterface implementation.
|
| - virtual void Execute(
|
| - blink::WebGLId source_texture,
|
| - const std::vector<blink::WebGLId>& dest_textures) OVERRIDE {
|
| + virtual void Execute(GLuint source_texture,
|
| + const std::vector<GLuint>& dest_textures) OVERRIDE {
|
| if (subscaler_) {
|
| subscaler_->Scale(source_texture, intermediate_texture_);
|
| source_texture = intermediate_texture_;
|
| }
|
|
|
| ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
|
| - context_,
|
| - dst_framebuffer_);
|
| + gl_, dst_framebuffer_);
|
| DCHECK_GT(dest_textures.size(), 0U);
|
| - scoped_ptr<blink::WGC3Denum[]> buffers(
|
| - new blink::WGC3Denum[dest_textures.size()]);
|
| + scoped_ptr<GLenum[]> buffers(new GLenum[dest_textures.size()]);
|
| for (size_t t = 0; t < dest_textures.size(); t++) {
|
| - ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_,
|
| - dest_textures[t]);
|
| - context_->framebufferTexture2D(GL_FRAMEBUFFER,
|
| - GL_COLOR_ATTACHMENT0 + t,
|
| - GL_TEXTURE_2D,
|
| - dest_textures[t],
|
| - 0);
|
| + ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dest_textures[t]);
|
| + gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
|
| + GL_COLOR_ATTACHMENT0 + t,
|
| + GL_TEXTURE_2D,
|
| + dest_textures[t],
|
| + 0);
|
| buffers[t] = GL_COLOR_ATTACHMENT0 + t;
|
| }
|
| - ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_,
|
| - source_texture);
|
| -
|
| - context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
| - GL_LINEAR);
|
| - context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
| - GL_LINEAR);
|
| - context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
|
| - GL_CLAMP_TO_EDGE);
|
| - context_->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
|
| - GL_CLAMP_TO_EDGE);
|
| + ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, source_texture);
|
| +
|
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
| ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
|
| - context_,
|
| - scaler_helper_->vertex_attributes_buffer_);
|
| + gl_, scaler_helper_->vertex_attributes_buffer_);
|
| + DCHECK(shader_program_->Initialized());
|
| shader_program_->UseProgram(spec_.src_size,
|
| spec_.src_subrect,
|
| spec_.dst_size,
|
| spec_.scale_x,
|
| spec_.vertically_flip_texture,
|
| color_weights_);
|
| - context_->viewport(0, 0, spec_.dst_size.width(), spec_.dst_size.height());
|
| + gl_->Viewport(0, 0, spec_.dst_size.width(), spec_.dst_size.height());
|
|
|
| if (dest_textures.size() > 1) {
|
| DCHECK_LE(static_cast<int>(dest_textures.size()),
|
| scaler_helper_->helper_->MaxDrawBuffers());
|
| - context_->drawBuffersEXT(dest_textures.size(), buffers.get());
|
| + gl_->DrawBuffersEXT(dest_textures.size(), buffers.get());
|
| }
|
| // Conduct texture mapping by drawing a quad composed of two triangles.
|
| - context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
| + gl_->DrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
| if (dest_textures.size() > 1) {
|
| // Set the draw buffers back to not confuse others.
|
| - context_->drawBuffersEXT(1, &buffers[0]);
|
| + gl_->DrawBuffersEXT(1, &buffers[0]);
|
| }
|
| }
|
|
|
| // GLHelper::ScalerInterface implementation.
|
| - virtual void Scale(blink::WebGLId source_texture,
|
| - blink::WebGLId dest_texture) OVERRIDE {
|
| - std::vector<blink::WebGLId> tmp(1);
|
| + virtual void Scale(GLuint source_texture, GLuint dest_texture) OVERRIDE {
|
| + std::vector<GLuint> tmp(1);
|
| tmp[0] = dest_texture;
|
| Execute(source_texture, tmp);
|
| }
|
| @@ -243,37 +232,33 @@ class ScalerImpl :
|
| }
|
| return spec_.src_subrect;
|
| }
|
| - virtual const gfx::Size& DstSize() OVERRIDE {
|
| - return spec_.dst_size;
|
| - }
|
| + virtual const gfx::Size& DstSize() OVERRIDE { return spec_.dst_size; }
|
|
|
| private:
|
| - WebGraphicsContext3D* context_;
|
| + GLES2Interface* gl_;
|
| GLHelperScaling* scaler_helper_;
|
| GLHelperScaling::ScalerStage spec_;
|
| GLfloat color_weights_[4];
|
| - blink::WebGLId intermediate_texture_;
|
| + GLuint intermediate_texture_;
|
| scoped_refptr<ShaderProgram> shader_program_;
|
| ScopedFramebuffer dst_framebuffer_;
|
| scoped_ptr<ScalerImpl> subscaler_;
|
| };
|
|
|
| -GLHelperScaling::ScalerStage::ScalerStage(
|
| - ShaderType shader_,
|
| - gfx::Size src_size_,
|
| - gfx::Rect src_subrect_,
|
| - gfx::Size dst_size_,
|
| - bool scale_x_,
|
| - bool vertically_flip_texture_,
|
| - bool swizzle_)
|
| +GLHelperScaling::ScalerStage::ScalerStage(ShaderType shader_,
|
| + gfx::Size src_size_,
|
| + gfx::Rect src_subrect_,
|
| + gfx::Size dst_size_,
|
| + bool scale_x_,
|
| + bool vertically_flip_texture_,
|
| + bool swizzle_)
|
| : shader(shader_),
|
| src_size(src_size_),
|
| src_subrect(src_subrect_),
|
| dst_size(dst_size_),
|
| scale_x(scale_x_),
|
| vertically_flip_texture(vertically_flip_texture_),
|
| - swizzle(swizzle_) {
|
| -}
|
| + swizzle(swizzle_) {}
|
|
|
| // The important inputs for this function is |x_ops| and
|
| // |y_ops|. They represent scaling operations to be done
|
| @@ -295,7 +280,7 @@ void GLHelperScaling::ConvertScalerOpsToScalerStages(
|
| bool swizzle,
|
| std::deque<GLHelperScaling::ScaleOp>* x_ops,
|
| std::deque<GLHelperScaling::ScaleOp>* y_ops,
|
| - std::vector<ScalerStage> *scaler_stages) {
|
| + std::vector<ScalerStage>* scaler_stages) {
|
| while (!x_ops->empty() || !y_ops->empty()) {
|
| gfx::Size intermediate_size = src_subrect.size();
|
| std::deque<ScaleOp>* current_queue = NULL;
|
| @@ -354,8 +339,7 @@ void GLHelperScaling::ConvertScalerOpsToScalerStages(
|
| // * N bilinear Y-passes with 1 bilinear X-pass (down only)
|
| // Measurements indicate that generalizing this for 3x3 and 4x4
|
| // makes it slower on some platforms, such as the Pixel.
|
| - if (!scale_x && x_ops->size() > 0 &&
|
| - x_ops->front().scale_factor <= 2) {
|
| + if (!scale_x && x_ops->size() > 0 && x_ops->front().scale_factor <= 2) {
|
| int x_passes = 0;
|
| if (current_shader == SHADER_BILINEAR2 && x_ops->size() >= 2) {
|
| // 2y + 2x passes
|
| @@ -415,7 +399,7 @@ void GLHelperScaling::ComputeScalerStages(
|
| const gfx::Size& dst_size,
|
| bool vertically_flip_texture,
|
| bool swizzle,
|
| - std::vector<ScalerStage> *scaler_stages) {
|
| + std::vector<ScalerStage>* scaler_stages) {
|
| if (quality == GLHelper::SCALER_QUALITY_FAST ||
|
| src_subrect.size() == dst_size) {
|
| scaler_stages->push_back(ScalerStage(SHADER_BILINEAR,
|
| @@ -440,25 +424,24 @@ void GLHelperScaling::ComputeScalerStages(
|
| quality == GLHelper::SCALER_QUALITY_GOOD,
|
| &y_ops);
|
|
|
| - ConvertScalerOpsToScalerStages(
|
| - quality,
|
| - src_size,
|
| - src_subrect,
|
| - dst_size,
|
| - vertically_flip_texture,
|
| - swizzle,
|
| - &x_ops,
|
| - &y_ops,
|
| - scaler_stages);
|
| + ConvertScalerOpsToScalerStages(quality,
|
| + src_size,
|
| + src_subrect,
|
| + dst_size,
|
| + vertically_flip_texture,
|
| + swizzle,
|
| + &x_ops,
|
| + &y_ops,
|
| + scaler_stages);
|
| }
|
|
|
| -GLHelper::ScalerInterface*
|
| -GLHelperScaling::CreateScaler(GLHelper::ScalerQuality quality,
|
| - gfx::Size src_size,
|
| - gfx::Rect src_subrect,
|
| - const gfx::Size& dst_size,
|
| - bool vertically_flip_texture,
|
| - bool swizzle) {
|
| +GLHelper::ScalerInterface* GLHelperScaling::CreateScaler(
|
| + GLHelper::ScalerQuality quality,
|
| + gfx::Size src_size,
|
| + gfx::Rect src_subrect,
|
| + const gfx::Size& dst_size,
|
| + bool vertically_flip_texture,
|
| + bool swizzle) {
|
| std::vector<ScalerStage> scaler_stages;
|
| ComputeScalerStages(quality,
|
| src_size,
|
| @@ -470,13 +453,12 @@ GLHelperScaling::CreateScaler(GLHelper::ScalerQuality quality,
|
|
|
| ScalerImpl* ret = NULL;
|
| for (unsigned int i = 0; i < scaler_stages.size(); i++) {
|
| - ret = new ScalerImpl(context_, this, scaler_stages[i], ret, NULL);
|
| + ret = new ScalerImpl(gl_, this, scaler_stages[i], ret, NULL);
|
| }
|
| return ret;
|
| }
|
|
|
| -GLHelper::ScalerInterface*
|
| -GLHelperScaling::CreatePlanarScaler(
|
| +GLHelper::ScalerInterface* GLHelperScaling::CreatePlanarScaler(
|
| const gfx::Size& src_size,
|
| const gfx::Rect& src_subrect,
|
| const gfx::Size& dst_size,
|
| @@ -489,11 +471,10 @@ GLHelperScaling::CreatePlanarScaler(
|
| true,
|
| vertically_flip_texture,
|
| false);
|
| - return new ScalerImpl(context_, this, stage, NULL, color_weights);
|
| + return new ScalerImpl(gl_, this, stage, NULL, color_weights);
|
| }
|
|
|
| -GLHelperScaling::ShaderInterface*
|
| -GLHelperScaling::CreateYuvMrtShader(
|
| +GLHelperScaling::ShaderInterface* GLHelperScaling::CreateYuvMrtShader(
|
| const gfx::Size& src_size,
|
| const gfx::Rect& src_subrect,
|
| const gfx::Size& dst_size,
|
| @@ -507,38 +488,36 @@ GLHelperScaling::CreateYuvMrtShader(
|
| true,
|
| vertically_flip_texture,
|
| false);
|
| - return new ScalerImpl(context_, this, stage, NULL, NULL);
|
| + return new ScalerImpl(gl_, this, stage, NULL, NULL);
|
| }
|
|
|
| -const blink::WGC3Dfloat GLHelperScaling::kVertexAttributes[] = {
|
| - -1.0f, -1.0f, 0.0f, 0.0f,
|
| - 1.0f, -1.0f, 1.0f, 0.0f,
|
| - -1.0f, 1.0f, 0.0f, 1.0f,
|
| - 1.0f, 1.0f, 1.0f, 1.0f,
|
| -};
|
| +const GLfloat GLHelperScaling::kVertexAttributes[] = {
|
| + -1.0f, -1.0f, 0.0f, 0.0f, // vertex 0
|
| + 1.0f, -1.0f, 1.0f, 0.0f, // vertex 1
|
| + -1.0f, 1.0f, 0.0f, 1.0f, // vertex 2
|
| + 1.0f, 1.0f, 1.0f, 1.0f, }; // vertex 3
|
|
|
| void GLHelperScaling::InitBuffer() {
|
| - ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
|
| - context_, vertex_attributes_buffer_);
|
| - context_->bufferData(GL_ARRAY_BUFFER,
|
| - sizeof(kVertexAttributes),
|
| - kVertexAttributes,
|
| - GL_STATIC_DRAW);
|
| + ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(gl_,
|
| + vertex_attributes_buffer_);
|
| + gl_->BufferData(GL_ARRAY_BUFFER,
|
| + sizeof(kVertexAttributes),
|
| + kVertexAttributes,
|
| + GL_STATIC_DRAW);
|
| }
|
|
|
| -scoped_refptr<ShaderProgram>
|
| -GLHelperScaling::GetShaderProgram(ShaderType type,
|
| - bool swizzle) {
|
| +scoped_refptr<ShaderProgram> GLHelperScaling::GetShaderProgram(ShaderType type,
|
| + bool swizzle) {
|
| ShaderProgramKeyType key(type, swizzle);
|
| scoped_refptr<ShaderProgram>& cache_entry(shader_programs_[key]);
|
| if (!cache_entry.get()) {
|
| - cache_entry = new ShaderProgram(context_, helper_);
|
| - std::basic_string<blink::WGC3Dchar> vertex_program;
|
| - std::basic_string<blink::WGC3Dchar> fragment_program;
|
| - std::basic_string<blink::WGC3Dchar> vertex_header;
|
| - std::basic_string<blink::WGC3Dchar> fragment_directives;
|
| - std::basic_string<blink::WGC3Dchar> fragment_header;
|
| - std::basic_string<blink::WGC3Dchar> shared_variables;
|
| + cache_entry = new ShaderProgram(gl_, helper_);
|
| + std::basic_string<GLchar> vertex_program;
|
| + std::basic_string<GLchar> fragment_program;
|
| + std::basic_string<GLchar> vertex_header;
|
| + std::basic_string<GLchar> fragment_directives;
|
| + std::basic_string<GLchar> fragment_header;
|
| + std::basic_string<GLchar> shared_variables;
|
|
|
| vertex_header.append(
|
| "precision highp float;\n"
|
| @@ -606,8 +585,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| case SHADER_BILINEAR4:
|
| // This is equivialent to three passes of the BILINEAR shader above,
|
| // It can be used to scale an image down 2.0x-4.0x or exactly 8x.
|
| - shared_variables.append(
|
| - "varying vec4 v_texcoords[2];\n");
|
| + shared_variables.append("varying vec4 v_texcoords[2];\n");
|
| vertex_header.append(
|
| "uniform vec2 scaling_vector;\n"
|
| "uniform vec2 dst_pixelsize;\n");
|
| @@ -631,10 +609,8 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| // Two in each dimension. It can be used to scale an image down
|
| // 1.0x-2.0x in both X and Y directions. Or, it could be used to
|
| // scale an image down by exactly 4x in both dimensions.
|
| - shared_variables.append(
|
| - "varying vec4 v_texcoords[2];\n");
|
| - vertex_header.append(
|
| - "uniform vec2 dst_pixelsize;\n");
|
| + shared_variables.append("varying vec4 v_texcoords[2];\n");
|
| + vertex_header.append("uniform vec2 dst_pixelsize;\n");
|
| vertex_program.append(
|
| " vec2 step = src_subrect.zw / 4.0 / dst_pixelsize;\n"
|
| " v_texcoords[0].xy = texcoord + vec2(step.x, step.y);\n"
|
| @@ -678,7 +654,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| " (texture2D(s_texture, v_texcoords[0].zw) +\n"
|
| " texture2D(s_texture, v_texcoords[1].xy)) *\n"
|
| " CenterWeight;\n");
|
| - break;
|
| + break;
|
|
|
| case SHADER_BICUBIC_UPSCALE:
|
| // When scaling up, we need 4 texture reads, but we can
|
| @@ -687,10 +663,8 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| // will be in.
|
| // Also, when sampling the bicubic function like this, the sum
|
| // is always exactly one, so we can skip normalization as well.
|
| - shared_variables.append(
|
| - "varying vec2 v_texcoord;\n");
|
| - vertex_program.append(
|
| - " v_texcoord = texcoord;\n");
|
| + shared_variables.append("varying vec2 v_texcoord;\n");
|
| + vertex_program.append(" v_texcoord = texcoord;\n");
|
| fragment_header.append(
|
| "uniform vec2 src_pixelsize;\n"
|
| "uniform vec2 scaling_vector;\n"
|
| @@ -728,8 +702,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| // convert RGBA textures into Y, U and V textures. We do this
|
| // because single-component textures are not renderable on all
|
| // architectures.
|
| - shared_variables.append(
|
| - "varying vec4 v_texcoords[2];\n");
|
| + shared_variables.append("varying vec4 v_texcoords[2];\n");
|
| vertex_header.append(
|
| "uniform vec2 scaling_vector;\n"
|
| "uniform vec2 dst_pixelsize;\n");
|
| @@ -740,8 +713,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| " v_texcoords[0].zw = texcoord - step * 0.5;\n"
|
| " v_texcoords[1].xy = texcoord + step * 0.5;\n"
|
| " v_texcoords[1].zw = texcoord + step * 1.5;\n");
|
| - fragment_header.append(
|
| - "uniform vec4 color_weights;\n");
|
| + fragment_header.append("uniform vec4 color_weights;\n");
|
| fragment_program.append(
|
| " gl_FragColor = color_weights * mat4(\n"
|
| " vec4(texture2D(s_texture, v_texcoords[0].xy).rgb, 1.0),\n"
|
| @@ -778,8 +750,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| // pass +--> { UUUU + VVVV }
|
| // UUUU VVVV
|
| //
|
| - shared_variables.append(
|
| - "varying vec4 v_texcoords[2];\n");
|
| + shared_variables.append("varying vec4 v_texcoords[2];\n");
|
| vertex_header.append(
|
| "uniform vec2 scaling_vector;\n"
|
| "uniform vec2 dst_pixelsize;\n");
|
| @@ -790,8 +761,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| " v_texcoords[0].zw = texcoord - step * 0.5;\n"
|
| " v_texcoords[1].xy = texcoord + step * 0.5;\n"
|
| " v_texcoords[1].zw = texcoord + step * 1.5;\n");
|
| - fragment_directives.append(
|
| - "#extension GL_EXT_draw_buffers : enable\n");
|
| + fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
|
| fragment_header.append(
|
| "const vec3 kRGBtoY = vec3(0.257, 0.504, 0.098);\n"
|
| "const float kYBias = 0.0625;\n"
|
| @@ -822,8 +792,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| // We're just sampling two pixels and unswizzling them. There's
|
| // no need to do vertical scaling with math, since bilinear
|
| // interpolation in the sampler takes care of that.
|
| - shared_variables.append(
|
| - "varying vec4 v_texcoords;\n");
|
| + shared_variables.append("varying vec4 v_texcoords;\n");
|
| vertex_header.append(
|
| "uniform vec2 scaling_vector;\n"
|
| "uniform vec2 dst_pixelsize;\n");
|
| @@ -832,8 +801,7 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| " step /= 2.0;\n"
|
| " v_texcoords.xy = texcoord - step * 0.5;\n"
|
| " v_texcoords.zw = texcoord + step * 0.5;\n");
|
| - fragment_directives.append(
|
| - "#extension GL_EXT_draw_buffers : enable\n");
|
| + fragment_directives.append("#extension GL_EXT_draw_buffers : enable\n");
|
| fragment_program.append(
|
| " vec4 lo_uuvv = texture2D(s_texture, v_texcoords.xy);\n"
|
| " vec4 hi_uuvv = texture2D(s_texture, v_texcoords.zw);\n"
|
| @@ -847,121 +815,108 @@ GLHelperScaling::GetShaderProgram(ShaderType type,
|
| fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n");
|
| }
|
|
|
| - vertex_program =
|
| - vertex_header +
|
| - shared_variables +
|
| - "void main() {\n" +
|
| - vertex_program +
|
| - "}\n";
|
| -
|
| - fragment_program =
|
| - fragment_directives +
|
| - fragment_header +
|
| - shared_variables +
|
| - "void main() {\n" +
|
| - fragment_program +
|
| - "}\n";
|
| -
|
| - bool result = cache_entry->Setup(vertex_program.c_str(),
|
| - fragment_program.c_str());
|
| - DCHECK(result || context_->isContextLost())
|
| - << "vertex_program =\n" << vertex_program
|
| - << "fragment_program =\n" << fragment_program;
|
| + vertex_program = vertex_header + shared_variables + "void main() {\n" +
|
| + vertex_program + "}\n";
|
| +
|
| + fragment_program = fragment_directives + fragment_header +
|
| + shared_variables + "void main() {\n" + fragment_program +
|
| + "}\n";
|
| +
|
| + cache_entry->Setup(vertex_program.c_str(), fragment_program.c_str());
|
| }
|
| return cache_entry;
|
| }
|
|
|
| -bool ShaderProgram::Setup(const blink::WGC3Dchar* vertex_shader_text,
|
| - const blink::WGC3Dchar* fragment_shader_text) {
|
| +void ShaderProgram::Setup(const GLchar* vertex_shader_text,
|
| + const GLchar* fragment_shader_text) {
|
| // Shaders to map the source texture to |dst_texture_|.
|
| - ScopedShader vertex_shader(context_, helper_->CompileShaderFromSource(
|
| - vertex_shader_text, GL_VERTEX_SHADER));
|
| - if (vertex_shader.id() == 0) {
|
| - return false;
|
| - }
|
| - context_->attachShader(program_, vertex_shader);
|
| - ScopedShader fragment_shader(context_, helper_->CompileShaderFromSource(
|
| - fragment_shader_text, GL_FRAGMENT_SHADER));
|
| - if (fragment_shader.id() == 0) {
|
| - return false;
|
| - }
|
| - context_->attachShader(program_, fragment_shader);
|
| - context_->linkProgram(program_);
|
| -
|
| - blink::WGC3Dint link_status = 0;
|
| - context_->getProgramiv(program_, GL_LINK_STATUS, &link_status);
|
| - if (!link_status) {
|
| - LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8());
|
| - return false;
|
| - }
|
| - position_location_ = context_->getAttribLocation(program_, "a_position");
|
| - texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord");
|
| - texture_location_ = context_->getUniformLocation(program_, "s_texture");
|
| - src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect");
|
| - src_pixelsize_location_ = context_->getUniformLocation(program_,
|
| - "src_pixelsize");
|
| - dst_pixelsize_location_ = context_->getUniformLocation(program_,
|
| - "dst_pixelsize");
|
| - scaling_vector_location_ = context_->getUniformLocation(program_,
|
| - "scaling_vector");
|
| - color_weights_location_ = context_->getUniformLocation(program_,
|
| - "color_weights");
|
| - return true;
|
| + GLuint vertex_shader =
|
| + helper_->CompileShaderFromSource(vertex_shader_text, GL_VERTEX_SHADER);
|
| + if (vertex_shader == 0)
|
| + return;
|
| +
|
| + gl_->AttachShader(program_, vertex_shader);
|
| + gl_->DeleteShader(vertex_shader);
|
| +
|
| + GLuint fragment_shader = helper_->CompileShaderFromSource(
|
| + fragment_shader_text, GL_FRAGMENT_SHADER);
|
| + if (fragment_shader == 0)
|
| + return;
|
| + gl_->AttachShader(program_, fragment_shader);
|
| + gl_->DeleteShader(fragment_shader);
|
| +
|
| + gl_->LinkProgram(program_);
|
| +
|
| + GLint link_status = 0;
|
| + gl_->GetProgramiv(program_, GL_LINK_STATUS, &link_status);
|
| + if (!link_status)
|
| + return;
|
| +
|
| + position_location_ = gl_->GetAttribLocation(program_, "a_position");
|
| + texcoord_location_ = gl_->GetAttribLocation(program_, "a_texcoord");
|
| + texture_location_ = gl_->GetUniformLocation(program_, "s_texture");
|
| + src_subrect_location_ = gl_->GetUniformLocation(program_, "src_subrect");
|
| + src_pixelsize_location_ = gl_->GetUniformLocation(program_, "src_pixelsize");
|
| + dst_pixelsize_location_ = gl_->GetUniformLocation(program_, "dst_pixelsize");
|
| + scaling_vector_location_ =
|
| + gl_->GetUniformLocation(program_, "scaling_vector");
|
| + color_weights_location_ = gl_->GetUniformLocation(program_, "color_weights");
|
| + return;
|
| }
|
|
|
| -void ShaderProgram::UseProgram(
|
| - const gfx::Size& src_size,
|
| - const gfx::Rect& src_subrect,
|
| - const gfx::Size& dst_size,
|
| - bool scale_x,
|
| - bool flip_y,
|
| - GLfloat color_weights[4]) {
|
| - context_->useProgram(program_);
|
| -
|
| - blink::WGC3Dintptr offset = 0;
|
| - context_->vertexAttribPointer(position_location_,
|
| - 2,
|
| - GL_FLOAT,
|
| - GL_FALSE,
|
| - 4 * sizeof(blink::WGC3Dfloat),
|
| - offset);
|
| - context_->enableVertexAttribArray(position_location_);
|
| -
|
| - offset += 2 * sizeof(blink::WGC3Dfloat);
|
| - context_->vertexAttribPointer(texcoord_location_,
|
| - 2,
|
| - GL_FLOAT,
|
| - GL_FALSE,
|
| - 4 * sizeof(blink::WGC3Dfloat),
|
| - offset);
|
| - context_->enableVertexAttribArray(texcoord_location_);
|
| -
|
| - context_->uniform1i(texture_location_, 0);
|
| +void ShaderProgram::UseProgram(const gfx::Size& src_size,
|
| + const gfx::Rect& src_subrect,
|
| + const gfx::Size& dst_size,
|
| + bool scale_x,
|
| + bool flip_y,
|
| + GLfloat color_weights[4]) {
|
| + gl_->UseProgram(program_);
|
| +
|
| + // OpenGL defines the last parameter to VertexAttribPointer as type
|
| + // "const GLvoid*" even though it is actually an offset into the buffer
|
| + // object's data store and not a pointer to the client's address space.
|
| + const void* offsets[2] = {
|
| + 0, reinterpret_cast<const void*>(2 * sizeof(GLfloat))
|
| + };
|
| +
|
| + gl_->VertexAttribPointer(position_location_,
|
| + 2,
|
| + GL_FLOAT,
|
| + GL_FALSE,
|
| + 4 * sizeof(GLfloat),
|
| + offsets[0]);
|
| + gl_->EnableVertexAttribArray(position_location_);
|
| +
|
| + gl_->VertexAttribPointer(texcoord_location_,
|
| + 2,
|
| + GL_FLOAT,
|
| + GL_FALSE,
|
| + 4 * sizeof(GLfloat),
|
| + offsets[1]);
|
| + gl_->EnableVertexAttribArray(texcoord_location_);
|
| +
|
| + gl_->Uniform1i(texture_location_, 0);
|
|
|
| // Convert |src_subrect| to texture coordinates.
|
| GLfloat src_subrect_texcoord[] = {
|
| - static_cast<float>(src_subrect.x()) / src_size.width(),
|
| - static_cast<float>(src_subrect.y()) / src_size.height(),
|
| - static_cast<float>(src_subrect.width()) / src_size.width(),
|
| - static_cast<float>(src_subrect.height()) / src_size.height(),
|
| - };
|
| + static_cast<float>(src_subrect.x()) / src_size.width(),
|
| + static_cast<float>(src_subrect.y()) / src_size.height(),
|
| + static_cast<float>(src_subrect.width()) / src_size.width(),
|
| + static_cast<float>(src_subrect.height()) / src_size.height(), };
|
| if (flip_y) {
|
| src_subrect_texcoord[1] += src_subrect_texcoord[3];
|
| src_subrect_texcoord[3] *= -1.0;
|
| }
|
| - context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
|
| -
|
| - context_->uniform2f(src_pixelsize_location_,
|
| - src_size.width(),
|
| - src_size.height());
|
| - context_->uniform2f(dst_pixelsize_location_,
|
| - static_cast<float>(dst_size.width()),
|
| - static_cast<float>(dst_size.height()));
|
| -
|
| - context_->uniform2f(scaling_vector_location_,
|
| - scale_x ? 1.0 : 0.0,
|
| - scale_x ? 0.0 : 1.0);
|
| - context_->uniform4fv(color_weights_location_, 1, color_weights);
|
| + gl_->Uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
|
| +
|
| + gl_->Uniform2f(src_pixelsize_location_, src_size.width(), src_size.height());
|
| + gl_->Uniform2f(dst_pixelsize_location_,
|
| + static_cast<float>(dst_size.width()),
|
| + static_cast<float>(dst_size.height()));
|
| +
|
| + gl_->Uniform2f(
|
| + scaling_vector_location_, scale_x ? 1.0 : 0.0, scale_x ? 0.0 : 1.0);
|
| + gl_->Uniform4fv(color_weights_location_, 1, color_weights);
|
| }
|
|
|
| } // namespace content
|
|
|