#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 WebKit::WebGLId;
-using WebKit::WebGraphicsContext3D;
+using gpu::gles2::GLES2Interface;
namespace content {
-GLHelperScaling::GLHelperScaling(WebKit::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 WebKit::WGC3Dchar* vertex_shader_text,
- const WebKit::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
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.
- WebKit::WGC3Dint position_location_;
+ GLint position_location_;
// The location of the texture coordinate in the program.
- WebKit::WGC3Dint texcoord_location_;
+ GLint texcoord_location_;
// The location of the source texture in the program.
- WebKit::WGC3Dint texture_location_;
+ GLint texture_location_;
// The location of the texture coordinate of
// the sub-rectangle in the program.
- WebKit::WGC3Dint src_subrect_location_;
+ GLint src_subrect_location_;
// Location of size of source image in pixels.
- WebKit::WGC3Dint src_pixelsize_location_;
+ GLint src_pixelsize_location_;
// Location of size of destination image in pixels.
- WebKit::WGC3Dint dst_pixelsize_location_;
+ GLint dst_pixelsize_location_;
// Location of vector for scaling direction.
- WebKit::WGC3Dint scaling_vector_location_;
+ GLint scaling_vector_location_;
// Location of color weights.
- WebKit::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.
// 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];
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() {
+ ~ScalerImpl() override {
if (intermediate_texture_) {
- context_->deleteTexture(intermediate_texture_);
+ gl_->DeleteTextures(1, &intermediate_texture_);
}
}
// GLHelperShader::ShaderInterface implementation.
- virtual void Execute(
- WebKit::WebGLId source_texture,
- const std::vector<WebKit::WebGLId>& dest_textures) OVERRIDE {
+ 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<WebKit::WGC3Denum[]> buffers(
- new WebKit::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(WebKit::WebGLId source_texture,
- WebKit::WebGLId dest_texture) OVERRIDE {
- std::vector<WebKit::WebGLId> tmp(1);
+ void Scale(GLuint source_texture, GLuint dest_texture) override {
+ std::vector<GLuint> tmp(1);
tmp[0] = dest_texture;
Execute(source_texture, tmp);
}
- virtual const gfx::Size& SrcSize() OVERRIDE {
+ const gfx::Size& SrcSize() override {
if (subscaler_) {
return subscaler_->SrcSize();
}
return spec_.src_size;
}
- virtual const gfx::Rect& SrcSubrect() OVERRIDE {
+ const gfx::Rect& SrcSubrect() override {
if (subscaler_) {
return subscaler_->SrcSubrect();
}
return spec_.src_subrect;
}
- virtual const gfx::Size& DstSize() OVERRIDE {
- return spec_.dst_size;
- }
+ const gfx::Size& DstSize() override { return spec_.dst_size; }
private:
- WebGraphicsContext3D* context_;
+ GLES2Interface* gl_;
GLHelperScaling* scaler_helper_;
GLHelperScaling::ScalerStage spec_;
GLfloat color_weights_[4];
- WebKit::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
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;
// * 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
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,
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,
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,
bool vertically_flip_texture,
+ bool swizzle,
const float color_weights[4]) {
ScalerStage stage(SHADER_PLANAR,
src_size,
dst_size,
true,
vertically_flip_texture,
- false);
- return new ScalerImpl(context_, this, stage, NULL, color_weights);
+ swizzle);
+ 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,
bool vertically_flip_texture,
+ bool swizzle,
ShaderType shader) {
DCHECK(shader == SHADER_YUV_MRT_PASS1 || shader == SHADER_YUV_MRT_PASS2);
ScalerStage stage(shader,
dst_size,
true,
vertically_flip_texture,
- false);
- return new ScalerImpl(context_, this, stage, NULL, NULL);
+ swizzle);
+ return new ScalerImpl(gl_, this, stage, NULL, NULL);
}
-const WebKit::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<WebKit::WGC3Dchar> vertex_program;
- std::basic_string<WebKit::WGC3Dchar> fragment_program;
- std::basic_string<WebKit::WGC3Dchar> vertex_header;
- std::basic_string<WebKit::WGC3Dchar> fragment_directives;
- std::basic_string<WebKit::WGC3Dchar> fragment_header;
- std::basic_string<WebKit::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"
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");
// 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"
" (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
// 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"
// 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");
" 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"
" vec4(texture2D(s_texture, v_texcoords[0].zw).rgb, 1.0),\n"
" vec4(texture2D(s_texture, v_texcoords[1].xy).rgb, 1.0),\n"
" vec4(texture2D(s_texture, v_texcoords[1].zw).rgb, 1.0));\n");
- // Swizzle makes no sense for this shader.
- DCHECK(!swizzle);
break;
case SHADER_YUV_MRT_PASS1:
// 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");
" 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"
" dot(pixel34, kRGBtoU),\n"
" dot(pixel12, kRGBtoV),\n"
" dot(pixel34, kRGBtoV)) + kUVBias;\n");
- // Swizzle makes no sense for this shader.
- DCHECK(!swizzle);
break;
case SHADER_YUV_MRT_PASS2:
// 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");
" 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"
" gl_FragData[0] = vec4(lo_uuvv.rg, hi_uuvv.rg);\n"
" gl_FragData[1] = vec4(lo_uuvv.ba, hi_uuvv.ba);\n");
- // Swizzle makes no sense for this shader.
- DCHECK(!swizzle);
break;
}
if (swizzle) {
- fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n");
+ switch(type) {
+ case SHADER_YUV_MRT_PASS1:
+ fragment_program.append(" gl_FragData[0] = gl_FragData[0].bgra;\n");
+ break;
+ case SHADER_YUV_MRT_PASS2:
+ fragment_program.append(" gl_FragData[0] = gl_FragData[0].bgra;\n");
+ fragment_program.append(" gl_FragData[1] = gl_FragData[1].bgra;\n");
+ break;
+ default:
+ fragment_program.append(" gl_FragColor = gl_FragColor.bgra;\n");
+ break;
+ }
}
- 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 WebKit::WGC3Dchar* vertex_shader_text,
- const WebKit::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_);
-
- WebKit::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_);
-
- WebKit::WGC3Dintptr offset = 0;
- context_->vertexAttribPointer(position_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(WebKit::WGC3Dfloat),
- offset);
- context_->enableVertexAttribArray(position_location_);
-
- offset += 2 * sizeof(WebKit::WGC3Dfloat);
- context_->vertexAttribPointer(texcoord_location_,
- 2,
- GL_FLOAT,
- GL_FALSE,
- 4 * sizeof(WebKit::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