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 |