summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorvigneshv@chromium.org <vigneshv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 21:50:54 +0000
committervigneshv@chromium.org <vigneshv@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-07 21:50:54 +0000
commit0402b238e35ca5870036685c05e5b4fd6e870103 (patch)
treed9eb2365dddd50e962e978dadfd0eb8d0750f68e /cc/output
parent639ac9701e25c6de1696c9b81a4afd9aeb34b57f (diff)
downloadchromium_src-0402b238e35ca5870036685c05e5b4fd6e870103.zip
chromium_src-0402b238e35ca5870036685c05e5b4fd6e870103.tar.gz
chromium_src-0402b238e35ca5870036685c05e5b4fd6e870103.tar.bz2
Adding YUVA support for enabling Alpha Playback
Adding YUVA support for enabling VP8 Alpha Playback. Trying to reland the change that was reverted earlier. Old CL: https://codereview.chromium.org/12157002/ BUG=147355 TBR=jschuh@chromium.org Review URL: https://chromiumcodereview.appspot.com/16580006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204944 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/output')
-rw-r--r--cc/output/delegating_renderer_unittest.cc6
-rw-r--r--cc/output/gl_renderer.cc95
-rw-r--r--cc/output/gl_renderer.h6
-rw-r--r--cc/output/gl_renderer_unittest.cc1
-rw-r--r--cc/output/renderer_pixeltest.cc117
-rw-r--r--cc/output/shader.cc73
-rw-r--r--cc/output/shader.h31
7 files changed, 305 insertions, 24 deletions
diff --git a/cc/output/delegating_renderer_unittest.cc b/cc/output/delegating_renderer_unittest.cc
index 94cae6a..bc3bcfd 100644
--- a/cc/output/delegating_renderer_unittest.cc
+++ b/cc/output/delegating_renderer_unittest.cc
@@ -127,12 +127,12 @@ class DelegatingRendererTestResources : public DelegatingRendererTest {
ASSERT_TRUE(last_frame.delegated_frame_data);
EXPECT_EQ(2u, last_frame.delegated_frame_data->render_pass_list.size());
- // Each render pass has 9 resources in it. And the root render pass has a
- // mask resource used when drawing the child render pass. The number 9 may
+ // Each render pass has 10 resources in it. And the root render pass has a
+ // mask resource used when drawing the child render pass. The number 10 may
// change if AppendOneOfEveryQuadType() is updated, and the value here
// should be updated accordingly.
EXPECT_EQ(
- 19u, last_frame.delegated_frame_data->resource_list.size());
+ 21u, last_frame.delegated_frame_data->resource_list.size());
EndTest();
}
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 4519af3..7cfb124 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -1375,8 +1375,7 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
context_, &highp_threshold_cache_, highp_threshold_min_,
quad->shared_quad_state->visible_content_rect.bottom_right());
- const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision);
- DCHECK(program && (program->initialized() || IsContextLost()));
+ bool use_alpha_plane = quad->a_plane_resource_id != 0;
GLC(Context(), Context()->activeTexture(GL_TEXTURE1));
ResourceProvider::ScopedSamplerGL y_plane_lock(
@@ -1387,19 +1386,61 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
GLC(Context(), Context()->activeTexture(GL_TEXTURE3));
ResourceProvider::ScopedSamplerGL v_plane_lock(
resource_provider_, quad->v_plane_resource_id, GL_TEXTURE_2D, GL_LINEAR);
+ scoped_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
+ if (use_alpha_plane) {
+ GLC(Context(), Context()->activeTexture(GL_TEXTURE4));
+ a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
+ resource_provider_,
+ quad->a_plane_resource_id,
+ GL_TEXTURE_2D,
+ GL_LINEAR));
+ }
- SetUseProgram(program->program());
+ int tex_scale_location = -1;
+ int matrix_location = -1;
+ int y_texture_location = -1;
+ int u_texture_location = -1;
+ int v_texture_location = -1;
+ int a_texture_location = -1;
+ int yuv_matrix_location = -1;
+ int yuv_adj_location = -1;
+ int alpha_location = -1;
+ if (use_alpha_plane) {
+ const VideoYUVAProgram* program = GetVideoYUVAProgram(tex_coord_precision);
+ DCHECK(program && (program->initialized() || IsContextLost()));
+ SetUseProgram(program->program());
+ tex_scale_location = program->vertex_shader().tex_scale_location();
+ matrix_location = program->vertex_shader().matrix_location();
+ y_texture_location = program->fragment_shader().y_texture_location();
+ u_texture_location = program->fragment_shader().u_texture_location();
+ v_texture_location = program->fragment_shader().v_texture_location();
+ a_texture_location = program->fragment_shader().a_texture_location();
+ yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
+ yuv_adj_location = program->fragment_shader().yuv_adj_location();
+ alpha_location = program->fragment_shader().alpha_location();
+ } else {
+ const VideoYUVProgram* program = GetVideoYUVProgram(tex_coord_precision);
+ DCHECK(program && (program->initialized() || IsContextLost()));
+ SetUseProgram(program->program());
+ tex_scale_location = program->vertex_shader().tex_scale_location();
+ matrix_location = program->vertex_shader().matrix_location();
+ y_texture_location = program->fragment_shader().y_texture_location();
+ u_texture_location = program->fragment_shader().u_texture_location();
+ v_texture_location = program->fragment_shader().v_texture_location();
+ yuv_matrix_location = program->fragment_shader().yuv_matrix_location();
+ yuv_adj_location = program->fragment_shader().yuv_adj_location();
+ alpha_location = program->fragment_shader().alpha_location();
+ }
GLC(Context(),
- Context()->uniform2f(program->vertex_shader().tex_scale_location(),
+ Context()->uniform2f(tex_scale_location,
quad->tex_scale.width(),
quad->tex_scale.height()));
- GLC(Context(),
- Context()->uniform1i(program->fragment_shader().y_texture_location(), 1));
- GLC(Context(),
- Context()->uniform1i(program->fragment_shader().u_texture_location(), 2));
- GLC(Context(),
- Context()->uniform1i(program->fragment_shader().v_texture_location(), 3));
+ GLC(Context(), Context()->uniform1i(y_texture_location, 1));
+ GLC(Context(), Context()->uniform1i(u_texture_location, 2));
+ GLC(Context(), Context()->uniform1i(v_texture_location, 3));
+ if (use_alpha_plane)
+ GLC(Context(), Context()->uniform1i(a_texture_location, 4));
// These values are magic numbers that are used in the transformation from YUV
// to RGB color values. They are taken from the following webpage:
@@ -1410,8 +1451,7 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
1.596f, -.813f, 0.0f,
};
GLC(Context(),
- Context()->uniformMatrix3fv(
- program->fragment_shader().yuv_matrix_location(), 1, 0, yuv_to_rgb));
+ Context()->uniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb));
// These values map to 16, 128, and 128 respectively, and are computed
// as a fraction over 256 (e.g. 16 / 256 = 0.0625).
@@ -1420,16 +1460,11 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
// U - 128 : Turns unsigned U into signed U [-128,127]
// V - 128 : Turns unsigned V into signed V [-128,127]
float yuv_adjust[3] = { -0.0625f, -0.5f, -0.5f, };
- GLC(Context(),
- Context()->uniform3fv(
- program->fragment_shader().yuv_adj_location(), 1, yuv_adjust));
+ GLC(Context(), Context()->uniform3fv(yuv_adj_location, 1, yuv_adjust));
- SetShaderOpacity(quad->opacity(),
- program->fragment_shader().alpha_location());
- DrawQuadGeometry(frame,
- quad->quadTransform(),
- quad->rect,
- program->vertex_shader().matrix_location());
+
+ SetShaderOpacity(quad->opacity(), alpha_location);
+ DrawQuadGeometry(frame, quad->quadTransform(), quad->rect, matrix_location);
// Reset active texture back to texture 0.
GLC(Context(), Context()->activeTexture(GL_TEXTURE0));
@@ -2731,6 +2766,20 @@ const GLRenderer::VideoYUVProgram* GLRenderer::GetVideoYUVProgram(
return program.get();
}
+const GLRenderer::VideoYUVAProgram* GLRenderer::GetVideoYUVAProgram(
+ TexCoordPrecision precision) {
+ scoped_ptr<VideoYUVAProgram>& program =
+ (precision == TexCoordPrecisionHigh) ? video_yuva_program_highp_
+ : video_yuva_program_;
+ if (!program)
+ program = make_scoped_ptr(new VideoYUVAProgram(context_, precision));
+ if (!program->initialized()) {
+ TRACE_EVENT0("cc", "GLRenderer::videoYUVAProgram::initialize");
+ program->Initialize(context_, is_using_bind_uniform_);
+ }
+ return program.get();
+}
+
const GLRenderer::VideoStreamTextureProgram*
GLRenderer::GetVideoStreamTextureProgram(TexCoordPrecision precision) {
if (!Capabilities().using_egl_image)
@@ -2831,11 +2880,15 @@ void GLRenderer::CleanupSharedObjects() {
if (video_yuv_program_)
video_yuv_program_->Cleanup(context_);
+ if (video_yuva_program_)
+ video_yuva_program_->Cleanup(context_);
if (video_stream_texture_program_)
video_stream_texture_program_->Cleanup(context_);
if (video_yuv_program_highp_)
video_yuv_program_highp_->Cleanup(context_);
+ if (video_yuva_program_highp_)
+ video_yuva_program_highp_->Cleanup(context_);
if (video_stream_texture_program_highp_)
video_stream_texture_program_highp_->Cleanup(context_);
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index a45af22..e693777 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -289,6 +289,8 @@ class CC_EXPORT GLRenderer
VideoStreamTextureProgram;
typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVVideo>
VideoYUVProgram;
+ typedef ProgramBinding<VertexShaderPosTexYUVStretch, FragmentShaderYUVAVideo>
+ VideoYUVAProgram;
// Special purpose / effects shaders.
typedef ProgramBinding<VertexShaderPos, FragmentShaderColor>
@@ -334,6 +336,8 @@ class CC_EXPORT GLRenderer
const VideoYUVProgram* GetVideoYUVProgram(
TexCoordPrecision precision);
+ const VideoYUVAProgram* GetVideoYUVAProgram(
+ TexCoordPrecision precision);
const VideoStreamTextureProgram* GetVideoStreamTextureProgram(
TexCoordPrecision precision);
@@ -390,9 +394,11 @@ class CC_EXPORT GLRenderer
render_pass_mask_color_matrix_program_aa_highp_;
scoped_ptr<VideoYUVProgram> video_yuv_program_;
+ scoped_ptr<VideoYUVAProgram> video_yuva_program_;
scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_;
scoped_ptr<VideoYUVProgram> video_yuv_program_highp_;
+ scoped_ptr<VideoYUVAProgram> video_yuva_program_highp_;
scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_highp_;
scoped_ptr<DebugBorderProgram> debug_border_program_;
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 0f901c5..c1c8842 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -96,6 +96,7 @@ class GLRendererShaderPixelTest : public GLRendererPixelTest {
EXPECT_PROGRAM_VALID(renderer()->GetTextureProgramFlip(precision));
EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision));
EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision));
+ EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision));
// This is unlikely to be ever true in tests due to usage of osmesa.
if (renderer()->Capabilities().using_egl_image)
EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision));
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index 4b0c194..cb91ca6 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -218,6 +218,123 @@ TYPED_TEST(RendererPixelTest, SimpleGreenRect_NonRootRenderPass) {
ExactPixelComparator(true)));
}
+class VideoGLRendererPixelTest : public GLRendererPixelTest {
+ protected:
+ scoped_ptr<YUVVideoDrawQuad> CreateTestYUVVideoDrawQuad(
+ SharedQuadState* shared_state, bool with_alpha) {
+ gfx::Rect rect(this->device_viewport_size_);
+ gfx::Rect opaque_rect(0, 0, 0, 0);
+
+ ResourceProvider::ResourceId y_resource =
+ resource_provider_->CreateResource(
+ this->device_viewport_size_,
+ GL_LUMINANCE,
+ ResourceProvider::TextureUsageAny);
+ ResourceProvider::ResourceId u_resource =
+ resource_provider_->CreateResource(
+ this->device_viewport_size_,
+ GL_LUMINANCE,
+ ResourceProvider::TextureUsageAny);
+ ResourceProvider::ResourceId v_resource =
+ resource_provider_->CreateResource(
+ this->device_viewport_size_,
+ GL_LUMINANCE,
+ ResourceProvider::TextureUsageAny);
+ ResourceProvider::ResourceId a_resource = 0;
+ if (with_alpha) {
+ a_resource = resource_provider_->CreateResource(
+ this->device_viewport_size_,
+ GL_LUMINANCE,
+ ResourceProvider::TextureUsageAny);
+ }
+
+ int w = this->device_viewport_size_.width();
+ int h = this->device_viewport_size_.height();
+ const int y_plane_size = w * h;
+ gfx::Rect uv_rect((w + 1) / 2, (h + 1) / 2);
+ const int uv_plane_size = uv_rect.size().GetArea();
+ scoped_ptr<uint8_t[]> y_plane(new uint8_t[y_plane_size]);
+ scoped_ptr<uint8_t[]> u_plane(new uint8_t[uv_plane_size]);
+ scoped_ptr<uint8_t[]> v_plane(new uint8_t[uv_plane_size]);
+ scoped_ptr<uint8_t[]> a_plane;
+ if (with_alpha)
+ a_plane.reset(new uint8_t[y_plane_size]);
+ // YUV values representing Green.
+ memset(y_plane.get(), 149, y_plane_size);
+ memset(u_plane.get(), 43, uv_plane_size);
+ memset(v_plane.get(), 21, uv_plane_size);
+ if (with_alpha)
+ memset(a_plane.get(), 128, y_plane_size);
+
+ resource_provider_->SetPixels(y_resource, y_plane.get(), rect, rect,
+ gfx::Vector2d());
+ resource_provider_->SetPixels(u_resource, u_plane.get(), uv_rect, uv_rect,
+ gfx::Vector2d());
+ resource_provider_->SetPixels(v_resource, v_plane.get(), uv_rect, uv_rect,
+ gfx::Vector2d());
+ if (with_alpha) {
+ resource_provider_->SetPixels(a_resource, a_plane.get(), rect, rect,
+ gfx::Vector2d());
+ }
+
+ scoped_ptr<YUVVideoDrawQuad> yuv_quad = cc::YUVVideoDrawQuad::Create();
+ yuv_quad->SetNew(shared_state, rect, opaque_rect, gfx::Size(),
+ y_resource, u_resource, v_resource, a_resource);
+ return yuv_quad.Pass();
+ }
+};
+
+TEST_F(VideoGLRendererPixelTest, SimpleYUVRect) {
+ gfx::Rect rect(this->device_viewport_size_);
+
+ RenderPass::Id id(1, 1);
+ scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+ scoped_ptr<SharedQuadState> shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), rect);
+
+ scoped_ptr<YUVVideoDrawQuad> yuv_quad =
+ CreateTestYUVVideoDrawQuad(shared_state.get(), false);
+
+ pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ base::FilePath(FILE_PATH_LITERAL("green.png")),
+ ExactPixelComparator(true)));
+}
+
+TEST_F(VideoGLRendererPixelTest, SimpleYUVARect) {
+ gfx::Rect rect(this->device_viewport_size_);
+
+ RenderPass::Id id(1, 1);
+ scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
+
+ scoped_ptr<SharedQuadState> shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), rect);
+
+ scoped_ptr<YUVVideoDrawQuad> yuv_quad =
+ CreateTestYUVVideoDrawQuad(shared_state.get(), true);
+
+ pass->quad_list.push_back(yuv_quad.PassAs<DrawQuad>());
+
+ scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
+ color_quad->SetNew(shared_state.get(), rect, SK_ColorWHITE, false);
+
+ pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ base::FilePath(FILE_PATH_LITERAL("green_alpha.png")),
+ ExactPixelComparator(true)));
+}
+
TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) {
gfx::Rect viewport_rect(this->device_viewport_size_);
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index 4a97a8e..3181a37 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -1355,6 +1355,79 @@ std::string FragmentShaderYUVVideo::GetShaderString(
); // NOLINT(whitespace/parens)
}
+FragmentShaderYUVAVideo::FragmentShaderYUVAVideo()
+ : y_texture_location_(-1),
+ u_texture_location_(-1),
+ v_texture_location_(-1),
+ a_texture_location_(-1),
+ alpha_location_(-1),
+ yuv_matrix_location_(-1),
+ yuv_adj_location_(-1) {
+}
+
+void FragmentShaderYUVAVideo::Init(WebGraphicsContext3D* context,
+ unsigned program,
+ bool using_bind_uniform,
+ int* base_uniform_index) {
+ static const char* shader_uniforms[] = {
+ "y_texture",
+ "u_texture",
+ "v_texture",
+ "a_texture",
+ "alpha",
+ "cc_matrix",
+ "yuv_adj",
+ };
+ int locations[7];
+
+ GetProgramUniformLocations(context,
+ program,
+ shader_uniforms,
+ arraysize(shader_uniforms),
+ arraysize(locations),
+ locations,
+ using_bind_uniform,
+ base_uniform_index);
+
+ y_texture_location_ = locations[0];
+ u_texture_location_ = locations[1];
+ v_texture_location_ = locations[2];
+ a_texture_location_ = locations[3];
+ alpha_location_ = locations[4];
+ yuv_matrix_location_ = locations[5];
+ yuv_adj_location_ = locations[6];
+
+ DCHECK(y_texture_location_ != -1 && u_texture_location_ != -1 &&
+ v_texture_location_ != -1 && a_texture_location_ != -1 &&
+ alpha_location_ != -1 && yuv_matrix_location_ != -1 &&
+ yuv_adj_location_ != -1);
+}
+
+std::string FragmentShaderYUVAVideo::GetShaderString(
+ TexCoordPrecision precision) const {
+ return FRAGMENT_SHADER(
+ precision mediump float;
+ precision mediump int;
+ varying TexCoordPrecision vec2 v_texCoord;
+ uniform sampler2D y_texture;
+ uniform sampler2D u_texture;
+ uniform sampler2D v_texture;
+ uniform sampler2D a_texture;
+ uniform float alpha;
+ uniform vec3 yuv_adj;
+ uniform mat3 yuv_matrix;
+ void main() {
+ float y_raw = texture2D(y_texture, v_texCoord).x;
+ float u_unsigned = texture2D(u_texture, v_texCoord).x;
+ float v_unsigned = texture2D(v_texture, v_texCoord).x;
+ float a_raw = texture2D(a_texture, v_texCoord).x;
+ vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;
+ vec3 rgb = yuv_matrix * yuv;
+ gl_FragColor = vec4(rgb, a_raw) * alpha;
+ }
+ ); // NOLINT(whitespace/parens)
+}
+
FragmentShaderColor::FragmentShaderColor()
: color_location_(-1) {}
diff --git a/cc/output/shader.h b/cc/output/shader.h
index 9b76ca2c..7200f35 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -575,6 +575,37 @@ class FragmentShaderYUVVideo {
DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo);
};
+
+class FragmentShaderYUVAVideo {
+ public:
+ FragmentShaderYUVAVideo();
+ std::string GetShaderString(TexCoordPrecision precision) const;
+
+ void Init(WebKit::WebGraphicsContext3D* context,
+ unsigned program,
+ bool using_bind_uniform,
+ int* base_uniform_index);
+
+ int y_texture_location() const { return y_texture_location_; }
+ int u_texture_location() const { return u_texture_location_; }
+ int v_texture_location() const { return v_texture_location_; }
+ int a_texture_location() const { return a_texture_location_; }
+ int alpha_location() const { return alpha_location_; }
+ int yuv_matrix_location() const { return yuv_matrix_location_; }
+ int yuv_adj_location() const { return yuv_adj_location_; }
+
+ private:
+ int y_texture_location_;
+ int u_texture_location_;
+ int v_texture_location_;
+ int a_texture_location_;
+ int alpha_location_;
+ int yuv_matrix_location_;
+ int yuv_adj_location_;
+
+ DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVAVideo);
+};
+
class FragmentShaderColor {
public:
FragmentShaderColor();