diff options
author | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-25 12:24:21 +0000 |
---|---|---|
committer | backer@chromium.org <backer@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-25 12:24:21 +0000 |
commit | 91a6d22ce735ba1bbbaffcf34e201738c7253a74 (patch) | |
tree | a2a62f52f0c90431935e5d00bcb4a07f81907084 /ui/gfx | |
parent | dcd5776135982012e99ea7b7030b3412f61235c7 (diff) | |
download | chromium_src-91a6d22ce735ba1bbbaffcf34e201738c7253a74.zip chromium_src-91a6d22ce735ba1bbbaffcf34e201738c7253a74.tar.gz chromium_src-91a6d22ce735ba1bbbaffcf34e201738c7253a74.tar.bz2 |
Expose CompositorGL and TextureGL.
RWHVV_touch will soon use CompositorGL and TextureGL. It will subclass TextureGL to wrap image data coming from the GPU process. It will need to access CompositorGL in order to make the GL context associated with the compositor current when making instances of the subclass of TextureGL.
In addition, the subclass of TextureGL will use a slightly different fragment shader. This CL also includes a refactor of how shaders are produced to share commonality.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/7235003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@90506 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx')
-rw-r--r-- | ui/gfx/compositor/compositor.gyp | 5 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.cc | 357 | ||||
-rw-r--r-- | ui/gfx/compositor/compositor_gl.h | 92 |
3 files changed, 290 insertions, 164 deletions
diff --git a/ui/gfx/compositor/compositor.gyp b/ui/gfx/compositor/compositor.gyp index 72fe768..e4c3fd1 100644 --- a/ui/gfx/compositor/compositor.gyp +++ b/ui/gfx/compositor/compositor.gyp @@ -9,10 +9,10 @@ ], 'conditions': [ ['os_posix == 1 and OS != "mac"', { - 'sources/': [['include', '_(gl)\\.cc$'],] + 'sources/': [['include', '_(gl)\\.(h|cc)$'],] }], ['OS == "win"', { - 'sources/': [['include', '_(win)\\.cc$'],] + 'sources/': [['include', '_(win)\\.(h|cc)$'],] }], ], }, @@ -30,6 +30,7 @@ 'compositor.cc', 'compositor.h', 'compositor_gl.cc', + 'compositor_gl.h', 'compositor_win.cc', 'layer.cc', 'layer.h', diff --git a/ui/gfx/compositor/compositor_gl.cc b/ui/gfx/compositor/compositor_gl.cc index ce45efe..8b9a43b 100644 --- a/ui/gfx/compositor/compositor_gl.cc +++ b/ui/gfx/compositor/compositor_gl.cc @@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/gfx/compositor/compositor.h" - -#include <GL/gl.h> +#include "ui/gfx/compositor/compositor_gl.h" #include "base/basictypes.h" #include "base/compiler_specific.h" @@ -20,82 +18,186 @@ #include "ui/gfx/gl/gl_context.h" #include "ui/gfx/gl/gl_implementation.h" #include "ui/gfx/gl/gl_surface.h" -#include "ui/gfx/gl/gl_surface_glx.h" -namespace ui { +namespace { -namespace glHidden { +GLuint CompileShader(GLenum type, const GLchar* source) { + GLuint shader = glCreateShader(type); + if (!shader) + return 0; -class CompositorGL; + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); -class TextureGL : public Texture { - public: - TextureGL(CompositorGL* compositor); + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint info_len = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); - virtual void SetBitmap(const SkBitmap& bitmap, - const gfx::Point& origin, - const gfx::Size& overall_size) OVERRIDE; + if (info_len > 0) { + scoped_array<char> info_log(new char[info_len]); + glGetShaderInfoLog(shader, info_len, NULL, info_log.get()); + LOG(ERROR) << "Compile error: " << info_log.get(); + return 0; + } + } + return shader; +} - // Draws the texture. - virtual void Draw(const ui::Transform& transform) OVERRIDE; +} // namespace (anonymous) - protected: - virtual ~TextureGL(); - private: - unsigned int texture_id_; - gfx::Size size_; - scoped_refptr <CompositorGL> compositor_; - DISALLOW_COPY_AND_ASSIGN(TextureGL); -}; +namespace ui { -class CompositorGL : public Compositor { +// Wraps a simple GL program for drawing textures to the screen. +class TextureProgramGL { public: - explicit CompositorGL(gfx::AcceleratedWidget widget); - virtual ~CompositorGL(); + TextureProgramGL(); + virtual ~TextureProgramGL() {} + + // Returns false if it was unable to initialize properly. + // + // Host GL context must be current when this is called. + virtual bool Initialize() = 0; + + // Make the program active in the current GL context. + void Use() const { glUseProgram(program_); } + + // Location of vertex position attribute in vertex shader. + GLuint a_pos_loc() const { return a_pos_loc_; } - void MakeCurrent(); - gfx::Size GetSize(); + // Location of texture co-ordinate attribute in vertex shader. + GLuint a_tex_loc() const { return a_tex_loc_; } + + // Location of transformation matrix uniform in vertex shader. + GLuint u_mat_loc() const { return u_mat_loc_; } + + // Location of texture unit uniform that we texture map from + // in the fragment shader. + GLuint u_tex_loc() const { return u_tex_loc_; } + + protected: + // Only the fragment shaders differ. This handles the initialization + // of all the other fields. + bool InitializeCommon(); - GLuint program(); - GLuint a_pos_loc(); - GLuint a_tex_loc(); - GLuint u_tex_loc(); - GLuint u_mat_loc(); + GLuint frag_shader_; private: - // Overridden from Compositor. - virtual Texture* CreateTexture() OVERRIDE; - virtual void NotifyStart() OVERRIDE; - virtual void NotifyEnd() OVERRIDE; - virtual void Blur(const gfx::Rect& bounds) OVERRIDE; - virtual void SchedulePaint() OVERRIDE; - - // Specific to CompositorGL. - bool InitShaders(); - - // The GL context used for compositing. - scoped_refptr<gfx::GLSurface> gl_surface_; - scoped_refptr<gfx::GLContext> gl_context_; - gfx::Size size_; - - // Shader program, attributes and uniforms. - // TODO(wjmaclean): Make these static so they ca be shared in a single - // context. GLuint program_; + GLuint vertex_shader_; + GLuint a_pos_loc_; GLuint a_tex_loc_; GLuint u_tex_loc_; GLuint u_mat_loc_; - // Keep track of whether compositing has started or not. - bool started_; +}; + +class TextureProgramNoSwizzleGL : public TextureProgramGL { + public: + TextureProgramNoSwizzleGL() {} + virtual bool Initialize(); + private: + DISALLOW_COPY_AND_ASSIGN(TextureProgramNoSwizzleGL); +}; - DISALLOW_COPY_AND_ASSIGN(CompositorGL); +class TextureProgramSwizzleGL : public TextureProgramGL { + public: + TextureProgramSwizzleGL() {} + virtual bool Initialize(); + private: + DISALLOW_COPY_AND_ASSIGN(TextureProgramSwizzleGL); }; -TextureGL::TextureGL(CompositorGL* compositor) +TextureProgramGL::TextureProgramGL() + : program_(0), + a_pos_loc_(0), + a_tex_loc_(0), + u_tex_loc_(0), + u_mat_loc_(0) { +} + +bool TextureProgramGL::InitializeCommon() { + const GLchar* vertex_shader_source = + "attribute vec4 a_position;" + "attribute vec2 a_texCoord;" + "uniform mat4 u_matViewProjection;" + "varying vec2 v_texCoord;" + "void main()" + "{" + " gl_Position = u_matViewProjection * a_position;" + " v_texCoord = a_texCoord;" + "}"; + + vertex_shader_ = CompileShader(GL_VERTEX_SHADER, vertex_shader_source); + if (!vertex_shader_) + return false; + + program_ = glCreateProgram(); + glAttachShader(program_, vertex_shader_); + glAttachShader(program_, frag_shader_); + glLinkProgram(program_); + + if (glGetError() != GL_NO_ERROR) + return false; + + // Store locations of program inputs. + a_pos_loc_ = glGetAttribLocation(program_, "a_position"); + a_tex_loc_ = glGetAttribLocation(program_, "a_texCoord"); + u_tex_loc_ = glGetUniformLocation(program_, "u_tex"); + u_mat_loc_ = glGetUniformLocation(program_, "u_matViewProjection"); + + return true; +} + +bool TextureProgramNoSwizzleGL::Initialize() { + const GLchar* frag_shader_source = + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "uniform sampler2D u_tex;" + "varying vec2 v_texCoord;" + "void main()" + "{" + " gl_FragColor = texture2D(u_tex, v_texCoord);" + "}"; + + frag_shader_ = CompileShader(GL_FRAGMENT_SHADER, frag_shader_source); + if (!frag_shader_) + return false; + + return InitializeCommon(); +} + +bool TextureProgramSwizzleGL::Initialize() { + const GLchar* frag_shader_source = + "#ifdef GL_ES\n" + "precision mediump float;\n" + "#endif\n" + "uniform sampler2D u_tex;" + "varying vec2 v_texCoord;" + "void main()" + "{" + " gl_FragColor = texture2D(u_tex, v_texCoord).zyxw;" + "}"; + + frag_shader_ = CompileShader(GL_FRAGMENT_SHADER, frag_shader_source); + if (!frag_shader_) + return false; + + return InitializeCommon(); +} + +TextureGL::TextureGL(CompositorGL* compositor) : texture_id_(0), + compositor_(compositor) { +} + +TextureGL::TextureGL(CompositorGL* compositor, + const gfx::Size& size) : texture_id_(0), + size_(size), compositor_(compositor) { } @@ -112,7 +214,7 @@ void TextureGL::SetBitmap(const SkBitmap& bitmap, // Verify bitmap pixels are contiguous. DCHECK_EQ(bitmap.rowBytes(), SkBitmap::ComputeRowBytes(bitmap.config(), bitmap.width())); - SkAutoLockPixels lock (bitmap); + SkAutoLockPixels lock(bitmap); void* pixels = bitmap.getPixels(); if (!texture_id_) { @@ -143,28 +245,33 @@ void TextureGL::SetBitmap(const SkBitmap& bitmap, } void TextureGL::Draw(const ui::Transform& transform) { + DCHECK(compositor_->program_swizzle()); + DrawInternal(*compositor_->program_swizzle(), transform); +} + +void TextureGL::DrawInternal(const ui::TextureProgramGL& program, + const ui::Transform& transform) { + program.Use(); + + glActiveTexture(GL_TEXTURE0); + glUniform1i(program.u_tex_loc(), 0); + glBindTexture(GL_TEXTURE_2D, texture_id_); + gfx::Size window_size = compositor_->GetSize(); ui::Transform t; - t.ConcatTranslate(1,1); + t.ConcatTranslate(1, 1); t.ConcatScale(size_.width()/2.0f, size_.height()/2.0f); t.ConcatTranslate(0, -size_.height()); t.ConcatScale(1, -1); - t.ConcatTransform(transform); // Add view transform. + t.ConcatTransform(transform); // Add view transform. t.ConcatTranslate(0, -window_size.height()); t.ConcatScale(1, -1); t.ConcatTranslate(-window_size.width()/2.0f, -window_size.height()/2.0f); t.ConcatScale(2.0f/window_size.width(), 2.0f/window_size.height()); - DCHECK(compositor_->program()); - glUseProgram(compositor_->program()); - - glActiveTexture(GL_TEXTURE0); - glUniform1i(compositor_->u_tex_loc(), 0); - glBindTexture(GL_TEXTURE_2D, texture_id_); - GLfloat m[16]; const SkMatrix& matrix = t.matrix(); @@ -191,19 +298,19 @@ void TextureGL::Draw(const ui::Transform& transform) { m[14] = 0; m[15] = matrix[8]; - const GLfloat vertices[] = { -1., -1., +0., +0., +1., - +1., -1., +0., +1., +1., - +1., +1., +0., +1., +0., - -1., +1., +0., +0., +0. }; + static const GLfloat vertices[] = { -1., -1., +0., +0., +1., + +1., -1., +0., +1., +1., + +1., +1., +0., +1., +0., + -1., +1., +0., +0., +0. }; - glVertexAttribPointer(compositor_->a_pos_loc(), 3, GL_FLOAT, + glVertexAttribPointer(program.a_pos_loc(), 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices); - glVertexAttribPointer(compositor_->a_tex_loc(), 2, GL_FLOAT, + glVertexAttribPointer(program.a_tex_loc(), 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), &vertices[3]); - glEnableVertexAttribArray(compositor_->a_pos_loc()); - glEnableVertexAttribArray(compositor_->a_tex_loc()); + glEnableVertexAttribArray(program.a_pos_loc()); + glEnableVertexAttribArray(program.a_tex_loc()); - glUniformMatrix4fv(compositor_->u_mat_loc(), 1, GL_FALSE, m); + glUniformMatrix4fv(program.u_mat_loc(), 1, GL_FALSE, m); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } @@ -215,7 +322,7 @@ CompositorGL::CompositorGL(gfx::AcceleratedWidget widget) gl_context_->MakeCurrent(gl_surface_.get()); if (!InitShaders()) LOG(ERROR) << "Unable to initialize shaders (context = " - << static_cast<void*>(gl_context_.get()) << ")" ; + << static_cast<void*>(gl_context_.get()) << ")"; glColorMask(true, true, true, true); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -232,24 +339,12 @@ gfx::Size CompositorGL::GetSize() { return gl_surface_->GetSize(); } -GLuint CompositorGL::program() { - return program_; -} - -GLuint CompositorGL::a_pos_loc() { - return a_pos_loc_; -} - -GLuint CompositorGL::a_tex_loc() { - return a_tex_loc_; -} - -GLuint CompositorGL::u_tex_loc() { - return u_tex_loc_; +TextureProgramGL* CompositorGL::program_no_swizzle() { + return program_no_swizzle_.get(); } -GLuint CompositorGL::u_mat_loc() { - return u_mat_loc_; +TextureProgramGL* CompositorGL::program_swizzle() { + return program_swizzle_.get(); } Texture* CompositorGL::CreateTexture() { @@ -291,84 +386,22 @@ void CompositorGL::SchedulePaint() { NOTIMPLEMENTED(); } -namespace { - -GLuint CompileShader(GLenum type, const GLchar* source) { - GLuint shader = glCreateShader(type); - if (!shader) - return 0; - - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - GLint compiled; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLint info_len = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); - - if (info_len > 0) { - char* info_log = reinterpret_cast<char*> ( - malloc(sizeof(info_log[0]) * info_len)); - glGetShaderInfoLog(shader, info_len, NULL, info_log); - - LOG(ERROR) << "Compile error: " << info_log; - free(info_log); - return 0; - } - } - return shader; -} - -} // namespace (anonymous) - bool CompositorGL::InitShaders() { - const GLchar* vertex_shader_source = - "attribute vec4 a_position;" - "attribute vec2 a_texCoord;" - "uniform mat4 u_matViewProjection;" - "varying vec2 v_texCoord;" - "void main()" - "{" - " gl_Position = u_matViewProjection * a_position;" - " v_texCoord = a_texCoord;" - "}"; - GLuint vertex_shader = CompileShader(GL_VERTEX_SHADER, vertex_shader_source); - if (!vertex_shader) - return false; - - const GLchar* frag_shader_source = - "#ifdef GL_ES\n" - "precision mediump float;\n" - "#endif\n" - "uniform sampler2D u_tex;" - "varying vec2 v_texCoord;" - "void main()" - "{" - " gl_FragColor = texture2D(u_tex, v_texCoord).zyxw;" - "}"; - GLuint frag_shader = CompileShader(GL_FRAGMENT_SHADER, frag_shader_source); - if (!frag_shader) + scoped_ptr<TextureProgramGL> temp_program(new TextureProgramNoSwizzleGL()); + if (!temp_program->Initialize()) return false; + else + program_no_swizzle_.reset(temp_program.release()); - program_ = glCreateProgram(); - glAttachShader(program_, vertex_shader); - glAttachShader(program_, frag_shader); - glLinkProgram(program_); - if (glGetError() != GL_NO_ERROR) + temp_program.reset(new TextureProgramSwizzleGL()); + if (!temp_program->Initialize()) return false; - - // Store locations of program inputs. - a_pos_loc_ = glGetAttribLocation(program_, "a_position"); - a_tex_loc_ = glGetAttribLocation(program_, "a_texCoord"); - u_tex_loc_ = glGetUniformLocation(program_, "u_tex"); - u_mat_loc_ = glGetUniformLocation(program_, "u_matViewProjection"); + else + program_swizzle_.reset(temp_program.release()); return true; } -} // namespace - // static Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { // The following line of code exists soley to disable IO restrictions @@ -377,7 +410,7 @@ Compositor* Compositor::Create(gfx::AcceleratedWidget widget) { base::ThreadRestrictions::ScopedAllowIO allow_io; if (gfx::GLSurface::InitializeOneOff() && gfx::GetGLImplementation() != gfx::kGLImplementationNone) - return new glHidden::CompositorGL(widget); + return new CompositorGL(widget); return NULL; } diff --git a/ui/gfx/compositor/compositor_gl.h b/ui/gfx/compositor/compositor_gl.h new file mode 100644 index 0000000..cb3c49a --- /dev/null +++ b/ui/gfx/compositor/compositor_gl.h @@ -0,0 +1,92 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_GFX_COMPOSITOR_COMPOSITOR_GL_H_ +#define UI_GFX_COMPOSITOR_COMPOSITOR_GL_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "ui/gfx/compositor/compositor.h" +#include "ui/gfx/size.h" + +namespace gfx { +class GLContext; +class GLSurface; +} + +namespace ui { + +class CompositorGL; +class TextureProgramGL; + +class TextureGL : public Texture { + public: + explicit TextureGL(CompositorGL* compositor); + + virtual void SetBitmap(const SkBitmap& bitmap, + const gfx::Point& origin, + const gfx::Size& overall_size) OVERRIDE; + + // Draws the texture. + virtual void Draw(const ui::Transform& transform) OVERRIDE; + + protected: + TextureGL(CompositorGL* compositor, const gfx::Size& size); + virtual ~TextureGL(); + + // Actually draws the texture. + void DrawInternal(const TextureProgramGL& program, + const ui::Transform& transform); + + unsigned int texture_id_; + gfx::Size size_; + CompositorGL* compositor_; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureGL); +}; + +class CompositorGL : public Compositor { + public: + explicit CompositorGL(gfx::AcceleratedWidget widget); + virtual ~CompositorGL(); + + void MakeCurrent(); + gfx::Size GetSize(); + + TextureProgramGL* program_no_swizzle(); + TextureProgramGL* program_swizzle(); + + private: + // Overridden from Compositor. + virtual Texture* CreateTexture() OVERRIDE; + virtual void NotifyStart() OVERRIDE; + virtual void NotifyEnd() OVERRIDE; + virtual void Blur(const gfx::Rect& bounds) OVERRIDE; + virtual void SchedulePaint() OVERRIDE; + + // Specific to CompositorGL. + bool InitShaders(); + + // The GL context used for compositing. + scoped_refptr<gfx::GLSurface> gl_surface_; + scoped_refptr<gfx::GLContext> gl_context_; + + // TODO(wjmaclean): Make these static so they ca be shared in a single + // context. + scoped_ptr<TextureProgramGL> program_swizzle_; + scoped_ptr<TextureProgramGL> program_no_swizzle_; + + gfx::Size size_; + + // Keep track of whether compositing has started or not. + bool started_; + + DISALLOW_COPY_AND_ASSIGN(CompositorGL); +}; + +} // namespace ui + +#endif // UI_GFX_COMPOSITOR_COMPOSITOR_GL_H_ |