summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cc/output/gl_renderer.cc181
-rw-r--r--cc/output/gl_renderer.h47
-rw-r--r--cc/output/gl_renderer_pixeltest.cc208
-rw-r--r--cc/output/gl_renderer_unittest.cc321
-rw-r--r--cc/output/shader.cc281
-rw-r--r--cc/output/shader.h116
-rw-r--r--cc/test/layer_tree_pixel_test.cc2
-rw-r--r--cc/test/pixel_test.cc6
-rw-r--r--cc/test/pixel_test.h3
-rw-r--r--cc/test/pixel_test_utils.cc14
-rw-r--r--cc/test/pixel_test_utils.h6
-rw-r--r--cc/test/render_pass_test_utils.cc22
-rw-r--r--cc/test/render_pass_test_utils.h8
-rw-r--r--ui/compositor/layer_unittest.cc12
14 files changed, 1185 insertions, 42 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 4d630a1..aac1543 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -37,6 +37,7 @@
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/GrTexture.h"
#include "third_party/skia/include/gpu/SkGpuDevice.h"
@@ -663,9 +664,19 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
// FIXME: Cache this value so that we don't have to do it for both the surface
// and its replica. Apply filters to the contents texture.
SkBitmap filter_bitmap;
+ SkScalar color_matrix[20];
+ bool use_color_matrix = false;
if (quad->filter) {
- filter_bitmap =
- ApplyImageFilter(this, quad->filter.get(), contents_texture);
+ SkColorFilter* cf;
+ if ((quad->filter->asColorFilter(&cf)) && cf->asColorMatrix(color_matrix) &&
+ !quad->filter->getInput(0)) {
+ // We have a single color matrix as a filter; apply it locally
+ // in the compositor.
+ use_color_matrix = true;
+ } else {
+ filter_bitmap =
+ ApplyImageFilter(this, quad->filter.get(), contents_texture);
+ }
} else {
filter_bitmap = ApplyFilters(this, quad->filters, contents_texture);
}
@@ -724,10 +735,12 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
int shader_mask_tex_coord_offset_location = -1;
int shader_matrix_location = -1;
int shader_alpha_location = -1;
+ int shader_color_matrix_location = -1;
+ int shader_color_offset_location = -1;
int shader_tex_transform_location = -1;
int shader_tex_scale_location = -1;
- if (use_aa && mask_texture_id) {
+ if (use_aa && mask_texture_id && !use_color_matrix) {
const RenderPassMaskProgramAA* program = GetRenderPassMaskProgramAA();
SetUseProgram(program->program());
GLC(Context(),
@@ -744,7 +757,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
shader_matrix_location = program->vertex_shader().matrix_location();
shader_alpha_location = program->fragment_shader().alpha_location();
shader_tex_scale_location = program->vertex_shader().tex_scale_location();
- } else if (!use_aa && mask_texture_id) {
+ } else if (!use_aa && mask_texture_id && !use_color_matrix) {
const RenderPassMaskProgram* program = GetRenderPassMaskProgram();
SetUseProgram(program->program());
GLC(Context(),
@@ -760,7 +773,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
shader_alpha_location = program->fragment_shader().alpha_location();
shader_tex_transform_location =
program->vertex_shader().tex_transform_location();
- } else if (use_aa && !mask_texture_id) {
+ } else if (use_aa && !mask_texture_id && !use_color_matrix) {
const RenderPassProgramAA* program = GetRenderPassProgramAA();
SetUseProgram(program->program());
GLC(Context(),
@@ -771,6 +784,80 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
shader_matrix_location = program->vertex_shader().matrix_location();
shader_alpha_location = program->fragment_shader().alpha_location();
shader_tex_scale_location = program->vertex_shader().tex_scale_location();
+ } else if (use_aa && mask_texture_id && use_color_matrix) {
+ const RenderPassMaskColorMatrixProgramAA* program =
+ GetRenderPassMaskColorMatrixProgramAA();
+ SetUseProgram(program->program());
+ GLC(Context(),
+ Context()->uniform1i(program->fragment_shader().sampler_location(), 0));
+
+ shader_matrix_location = program->vertex_shader().matrix_location();
+ shader_quad_location = program->vertex_shader().point_location();
+ shader_tex_scale_location = program->vertex_shader().tex_scale_location();
+ shader_edge_location = program->fragment_shader().edge_location();
+ shader_alpha_location = program->fragment_shader().alpha_location();
+ shader_mask_sampler_location =
+ program->fragment_shader().mask_sampler_location();
+ shader_mask_tex_coord_scale_location =
+ program->fragment_shader().mask_tex_coord_scale_location();
+ shader_mask_tex_coord_offset_location =
+ program->fragment_shader().mask_tex_coord_offset_location();
+ shader_color_matrix_location =
+ program->fragment_shader().color_matrix_location();
+ shader_color_offset_location =
+ program->fragment_shader().color_offset_location();
+ } else if (use_aa && !mask_texture_id && use_color_matrix) {
+ const RenderPassColorMatrixProgramAA* program =
+ GetRenderPassColorMatrixProgramAA();
+ SetUseProgram(program->program());
+ GLC(Context(),
+ Context()->uniform1i(program->fragment_shader().sampler_location(), 0));
+
+ shader_matrix_location = program->vertex_shader().matrix_location();
+ shader_quad_location = program->vertex_shader().point_location();
+ shader_tex_scale_location = program->vertex_shader().tex_scale_location();
+ shader_edge_location = program->fragment_shader().edge_location();
+ shader_alpha_location = program->fragment_shader().alpha_location();
+ shader_color_matrix_location =
+ program->fragment_shader().color_matrix_location();
+ shader_color_offset_location =
+ program->fragment_shader().color_offset_location();
+ } else if (!use_aa && mask_texture_id && use_color_matrix) {
+ const RenderPassMaskColorMatrixProgram* program =
+ GetRenderPassMaskColorMatrixProgram();
+ SetUseProgram(program->program());
+ GLC(Context(),
+ Context()->uniform1i(program->fragment_shader().sampler_location(), 0));
+
+ shader_matrix_location = program->vertex_shader().matrix_location();
+ shader_tex_transform_location =
+ program->vertex_shader().tex_transform_location();
+ shader_mask_sampler_location =
+ program->fragment_shader().mask_sampler_location();
+ shader_mask_tex_coord_scale_location =
+ program->fragment_shader().mask_tex_coord_scale_location();
+ shader_mask_tex_coord_offset_location =
+ program->fragment_shader().mask_tex_coord_offset_location();
+ shader_alpha_location = program->fragment_shader().alpha_location();
+ shader_color_matrix_location =
+ program->fragment_shader().color_matrix_location();
+ shader_color_offset_location =
+ program->fragment_shader().color_offset_location();
+ } else if (!use_aa && !mask_texture_id && use_color_matrix) {
+ const RenderPassColorMatrixProgram* program =
+ GetRenderPassColorMatrixProgram();
+ SetUseProgram(program->program());
+ GLC(Context(),
+ Context()->uniform1i(program->fragment_shader().sampler_location(), 0));
+
+ shader_matrix_location = program->vertex_shader().matrix_location();
+ shader_tex_transform_location =
+ program->vertex_shader().tex_transform_location();
+ shader_alpha_location = program->fragment_shader().alpha_location();
+ shader_color_matrix_location =
+ program->fragment_shader().color_matrix_location();
+ shader_color_offset_location =
+ program->fragment_shader().color_offset_location();
} else {
const RenderPassProgram* program = GetRenderPassProgram();
SetUseProgram(program->program());
@@ -782,7 +869,6 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
shader_tex_transform_location =
program->vertex_shader().tex_transform_location();
}
-
float tex_scale_x =
quad->rect.width() / static_cast<float>(contents_texture->size().width());
float tex_scale_y = quad->rect.height() /
@@ -830,6 +916,26 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame& frame,
GLC(Context(), Context()->uniform3fv(shader_edge_location, 8, edge));
}
+ if (shader_color_matrix_location != -1) {
+ float matrix[16];
+ for (int i = 0; i < 4; ++i) {
+ for (int j = 0; j < 4; ++j)
+ matrix[i * 4 + j] = SkScalarToFloat(color_matrix[j * 5 + i]);
+ }
+ GLC(Context(),
+ Context()->uniformMatrix4fv(
+ shader_color_matrix_location, 1, false, matrix));
+ }
+ static const float kScale = 1.0f / 255.0f;
+ if (shader_color_offset_location != -1) {
+ float offset[4];
+ for (int i = 0; i < 4; ++i)
+ offset[i] = SkScalarToFloat(color_matrix[i * 5 + 4]) * kScale;
+
+ GLC(Context(),
+ Context()->uniform4fv(shader_color_offset_location, 1, offset));
+ }
+
// Map device space quad to surface space. contents_device_transform has no 3d
// component since it was flattened, so we don't need to project.
gfx::QuadF surface_quad = MathUtil::MapQuad(contents_device_transform_inverse,
@@ -2060,6 +2166,61 @@ GLRenderer::GetRenderPassMaskProgramAA() {
return render_pass_mask_program_aa_.get();
}
+const GLRenderer::RenderPassColorMatrixProgram*
+GLRenderer::GetRenderPassColorMatrixProgram() {
+ if (!render_pass_color_matrix_program_)
+ render_pass_color_matrix_program_ =
+ make_scoped_ptr(new RenderPassColorMatrixProgram(context_));
+ if (!render_pass_color_matrix_program_->initialized()) {
+ TRACE_EVENT0("cc", "GLRenderer::renderPassColorMatrixProgram::initialize");
+ render_pass_color_matrix_program_->Initialize(context_,
+ is_using_bind_uniform_);
+ }
+ return render_pass_color_matrix_program_.get();
+}
+
+const GLRenderer::RenderPassColorMatrixProgramAA*
+GLRenderer::GetRenderPassColorMatrixProgramAA() {
+ if (!render_pass_color_matrix_program_aa_)
+ render_pass_color_matrix_program_aa_ =
+ make_scoped_ptr(new RenderPassColorMatrixProgramAA(context_));
+ if (!render_pass_color_matrix_program_aa_->initialized()) {
+ TRACE_EVENT0("cc",
+ "GLRenderer::renderPassColorMatrixProgramAA::initialize");
+ render_pass_color_matrix_program_aa_->Initialize(context_,
+ is_using_bind_uniform_);
+ }
+ return render_pass_color_matrix_program_aa_.get();
+}
+
+const GLRenderer::RenderPassMaskColorMatrixProgram*
+GLRenderer::GetRenderPassMaskColorMatrixProgram() {
+ if (!render_pass_mask_color_matrix_program_)
+ render_pass_mask_color_matrix_program_ =
+ make_scoped_ptr(new RenderPassMaskColorMatrixProgram(context_));
+ if (!render_pass_mask_color_matrix_program_->initialized()) {
+ TRACE_EVENT0("cc",
+ "GLRenderer::renderPassMaskColorMatrixProgram::initialize");
+ render_pass_mask_color_matrix_program_->Initialize(context_,
+ is_using_bind_uniform_);
+ }
+ return render_pass_mask_color_matrix_program_.get();
+}
+
+const GLRenderer::RenderPassMaskColorMatrixProgramAA*
+GLRenderer::GetRenderPassMaskColorMatrixProgramAA() {
+ if (!render_pass_mask_color_matrix_program_aa_)
+ render_pass_mask_color_matrix_program_aa_ =
+ make_scoped_ptr(new RenderPassMaskColorMatrixProgramAA(context_));
+ if (!render_pass_mask_color_matrix_program_aa_->initialized()) {
+ TRACE_EVENT0("cc",
+ "GLRenderer::renderPassMaskColorMatrixProgramAA::initialize");
+ render_pass_mask_color_matrix_program_aa_->Initialize(
+ context_, is_using_bind_uniform_);
+ }
+ return render_pass_mask_color_matrix_program_aa_.get();
+}
+
const GLRenderer::TileProgram* GLRenderer::GetTileProgram() {
DCHECK(tile_program_);
if (!tile_program_->initialized()) {
@@ -2205,6 +2366,14 @@ void GLRenderer::CleanupSharedObjects() {
render_pass_mask_program_aa_->Cleanup(context_);
if (render_pass_program_aa_)
render_pass_program_aa_->Cleanup(context_);
+ if (render_pass_color_matrix_program_)
+ render_pass_color_matrix_program_->Cleanup(context_);
+ if (render_pass_mask_color_matrix_program_aa_)
+ render_pass_mask_color_matrix_program_aa_->Cleanup(context_);
+ if (render_pass_color_matrix_program_aa_)
+ render_pass_color_matrix_program_aa_->Cleanup(context_);
+ if (render_pass_mask_color_matrix_program_)
+ render_pass_mask_color_matrix_program_->Cleanup(context_);
if (texture_program_)
texture_program_->Cleanup(context_);
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h
index 8dd2c64..5087e10 100644
--- a/cc/output/gl_renderer.h
+++ b/cc/output/gl_renderer.h
@@ -111,6 +111,7 @@ class CC_EXPORT GLRenderer :
virtual void FinishDrawingQuadList() OVERRIDE;
private:
+ friend class GLRendererShaderPixelTest;
friend class GLRendererShaderTest;
static void ToGLMatrix(float* gl_matrix, const gfx::Transform& transform);
@@ -219,6 +220,15 @@ class CC_EXPORT GLRenderer :
typedef ProgramBinding<VertexShaderPosTex, FragmentShaderCheckerboard>
TileCheckerboardProgram;
+ // Texture shaders.
+ typedef ProgramBinding<VertexShaderPosTexTransform,
+ FragmentShaderRGBATexVaryingAlpha> TextureProgram;
+ typedef ProgramBinding<VertexShaderPosTexTransformFlip,
+ FragmentShaderRGBATexVaryingAlpha> TextureProgramFlip;
+ typedef ProgramBinding<VertexShaderPosTexTransform,
+ FragmentShaderRGBATexRectVaryingAlpha>
+ TextureIOSurfaceProgram;
+
// Render surface shaders.
typedef ProgramBinding<VertexShaderPosTexTransform,
FragmentShaderRGBATexAlpha> RenderPassProgram;
@@ -228,15 +238,18 @@ class CC_EXPORT GLRenderer :
RenderPassProgramAA;
typedef ProgramBinding<VertexShaderQuad, FragmentShaderRGBATexAlphaMaskAA>
RenderPassMaskProgramAA;
-
- // Texture shaders.
typedef ProgramBinding<VertexShaderPosTexTransform,
- FragmentShaderRGBATexVaryingAlpha> TextureProgram;
- typedef ProgramBinding<VertexShaderPosTexTransformFlip,
- FragmentShaderRGBATexVaryingAlpha> TextureProgramFlip;
+ FragmentShaderRGBATexColorMatrixAlpha>
+ RenderPassColorMatrixProgram;
+ typedef ProgramBinding<VertexShaderQuad,
+ FragmentShaderRGBATexAlphaMaskColorMatrixAA>
+ RenderPassMaskColorMatrixProgramAA;
+ typedef ProgramBinding<VertexShaderQuad,
+ FragmentShaderRGBATexAlphaColorMatrixAA>
+ RenderPassColorMatrixProgramAA;
typedef ProgramBinding<VertexShaderPosTexTransform,
- FragmentShaderRGBATexRectVaryingAlpha>
- TextureIOSurfaceProgram;
+ FragmentShaderRGBATexAlphaMaskColorMatrix>
+ RenderPassMaskColorMatrixProgram;
// Video shaders.
typedef ProgramBinding<VertexShaderVideoTransform,
@@ -265,6 +278,11 @@ class CC_EXPORT GLRenderer :
const RenderPassProgramAA* GetRenderPassProgramAA();
const RenderPassMaskProgram* GetRenderPassMaskProgram();
const RenderPassMaskProgramAA* GetRenderPassMaskProgramAA();
+ const RenderPassColorMatrixProgram* GetRenderPassColorMatrixProgram();
+ const RenderPassColorMatrixProgramAA* GetRenderPassColorMatrixProgramAA();
+ const RenderPassMaskColorMatrixProgram* GetRenderPassMaskColorMatrixProgram();
+ const RenderPassMaskColorMatrixProgramAA*
+ GetRenderPassMaskColorMatrixProgramAA();
const TextureProgram* GetTextureProgram();
const TextureProgramFlip* GetTextureProgramFlip();
@@ -285,14 +303,21 @@ class CC_EXPORT GLRenderer :
scoped_ptr<TileProgramSwizzleAA> tile_program_swizzle_aa_;
scoped_ptr<TileCheckerboardProgram> tile_checkerboard_program_;
+ scoped_ptr<TextureProgram> texture_program_;
+ scoped_ptr<TextureProgramFlip> texture_program_flip_;
+ scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_;
+
scoped_ptr<RenderPassProgram> render_pass_program_;
scoped_ptr<RenderPassProgramAA> render_pass_program_aa_;
scoped_ptr<RenderPassMaskProgram> render_pass_mask_program_;
scoped_ptr<RenderPassMaskProgramAA> render_pass_mask_program_aa_;
-
- scoped_ptr<TextureProgram> texture_program_;
- scoped_ptr<TextureProgramFlip> texture_program_flip_;
- scoped_ptr<TextureIOSurfaceProgram> texture_io_surface_program_;
+ scoped_ptr<RenderPassColorMatrixProgram> render_pass_color_matrix_program_;
+ scoped_ptr<RenderPassColorMatrixProgramAA>
+ render_pass_color_matrix_program_aa_;
+ scoped_ptr<RenderPassMaskColorMatrixProgram>
+ render_pass_mask_color_matrix_program_;
+ scoped_ptr<RenderPassMaskColorMatrixProgramAA>
+ render_pass_mask_color_matrix_program_aa_;
scoped_ptr<VideoYUVProgram> video_yuv_program_;
scoped_ptr<VideoStreamTextureProgram> video_stream_texture_program_;
diff --git a/cc/output/gl_renderer_pixeltest.cc b/cc/output/gl_renderer_pixeltest.cc
index fbccce1..fcbe32b 100644
--- a/cc/output/gl_renderer_pixeltest.cc
+++ b/cc/output/gl_renderer_pixeltest.cc
@@ -4,8 +4,13 @@
#include "cc/output/gl_renderer.h"
+#include "cc/layers/append_quads_data.h"
#include "cc/quads/draw_quad.h"
#include "cc/test/pixel_test.h"
+#include "third_party/skia/include/core/SkImageFilter.h"
+#include "third_party/skia/include/core/SkMatrix.h"
+#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
+#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
namespace cc {
namespace {
@@ -90,7 +95,202 @@ TEST_F(GLRendererPixelTest, SimpleGreenRect) {
renderer_->DrawFrame(pass_list);
EXPECT_TRUE(PixelsMatchReference(
- base::FilePath(FILE_PATH_LITERAL("green.png"))));
+ base::FilePath(FILE_PATH_LITERAL("green.png")), true));
+}
+
+TEST_F(GLRendererPixelTest, fastPassColorFilterAlpha) {
+ gfx::Rect viewport_rect(device_viewport_size_);
+
+ RenderPass::Id root_pass_id(1, 1);
+ scoped_ptr<RenderPass> root_pass =
+ CreateTestRootRenderPass(root_pass_id, viewport_rect);
+
+ RenderPass::Id child_pass_id(2, 2);
+ gfx::Rect pass_rect(device_viewport_size_);
+ gfx::Transform transform_to_root;
+ scoped_ptr<RenderPass> child_pass =
+ CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
+
+ gfx::Transform content_to_target_transform;
+ scoped_ptr<SharedQuadState> shared_state =
+ CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+ shared_state->opacity = 0.5f;
+
+ scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
+ blue->SetNew(shared_state.get(),
+ gfx::Rect(0,
+ 0,
+ device_viewport_size_.width() / 2,
+ device_viewport_size_.height()),
+ SK_ColorBLUE);
+ scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
+ yellow->SetNew(shared_state.get(),
+ gfx::Rect(device_viewport_size_.width() / 2,
+ 0,
+ device_viewport_size_.width() / 2,
+ device_viewport_size_.height()),
+ SK_ColorYELLOW);
+
+ scoped_ptr<SharedQuadState> blank_state =
+ CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+
+ scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
+ white->SetNew(blank_state.get(),
+ viewport_rect,
+ SK_ColorWHITE);
+
+ child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
+ child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
+ child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
+
+ scoped_ptr<SharedQuadState> pass_shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+
+ SkScalar matrix[20];
+ float amount = 0.5f;
+ matrix[0] = 0.213f + 0.787f * amount;
+ matrix[1] = 0.715f - 0.715f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0;
+ matrix[5] = 0.213f - 0.213f * amount;
+ matrix[6] = 0.715f + 0.285f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0;
+ matrix[10] = 0.213f - 0.213f * amount;
+ matrix[11] = 0.715f - 0.715f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0;
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+ skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef(
+ new SkColorMatrixFilter(matrix)));
+ skia::RefPtr<SkImageFilter> filter =
+ skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
+
+ scoped_ptr<RenderPassDrawQuad> render_pass_quad = RenderPassDrawQuad::Create();
+ render_pass_quad->SetNew(pass_shared_state.get(),
+ pass_rect,
+ child_pass_id,
+ false,
+ 0,
+ pass_rect,
+ gfx::RectF(),
+ WebKit::WebFilterOperations(),
+ filter,
+ WebKit::WebFilterOperations());
+
+ root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(child_pass.Pass());
+ pass_list.push_back(root_pass.Pass());
+
+ renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
+ renderer_->DecideRenderPassAllocationsForFrame(pass_list);
+ renderer_->DrawFrame(pass_list);
+
+ EXPECT_TRUE(PixelsMatchReference(
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha.png")), false));
+}
+
+TEST_F(GLRendererPixelTest, fastPassColorFilterAlphaTranslation) {
+ gfx::Rect viewport_rect(device_viewport_size_);
+
+ RenderPass::Id root_pass_id(1, 1);
+ scoped_ptr<RenderPass> root_pass =
+ CreateTestRootRenderPass(root_pass_id, viewport_rect);
+
+ RenderPass::Id child_pass_id(2, 2);
+ gfx::Rect pass_rect(device_viewport_size_);
+ gfx::Transform transform_to_root;
+ scoped_ptr<RenderPass> child_pass =
+ CreateTestRenderPass(child_pass_id, pass_rect, transform_to_root);
+
+ gfx::Transform content_to_target_transform;
+ scoped_ptr<SharedQuadState> shared_state =
+ CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+ shared_state->opacity = 0.5f;
+
+ scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
+ blue->SetNew(shared_state.get(),
+ gfx::Rect(0,
+ 0,
+ device_viewport_size_.width() / 2,
+ device_viewport_size_.height()),
+ SK_ColorBLUE);
+ scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
+ yellow->SetNew(shared_state.get(),
+ gfx::Rect(device_viewport_size_.width() / 2,
+ 0,
+ device_viewport_size_.width() / 2,
+ device_viewport_size_.height()),
+ SK_ColorYELLOW);
+
+ scoped_ptr<SharedQuadState> blank_state =
+ CreateTestSharedQuadState(content_to_target_transform, viewport_rect);
+
+ scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
+ white->SetNew(blank_state.get(),
+ viewport_rect,
+ SK_ColorWHITE);
+
+ child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
+ child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
+ child_pass->quad_list.push_back(white.PassAs<DrawQuad>());
+
+ scoped_ptr<SharedQuadState> pass_shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), pass_rect);
+
+ SkScalar matrix[20];
+ float amount = 0.5f;
+ matrix[0] = 0.213f + 0.787f * amount;
+ matrix[1] = 0.715f - 0.715f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = 0;
+ matrix[4] = 20.f;
+ matrix[5] = 0.213f - 0.213f * amount;
+ matrix[6] = 0.715f + 0.285f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = 0;
+ matrix[9] = 200.f;
+ matrix[10] = 0.213f - 0.213f * amount;
+ matrix[11] = 0.715f - 0.715f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = 0;
+ matrix[14] = 1.5f;
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+ skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef(
+ new SkColorMatrixFilter(matrix)));
+ skia::RefPtr<SkImageFilter> filter =
+ skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
+
+ scoped_ptr<RenderPassDrawQuad> render_pass_quad =
+ RenderPassDrawQuad::Create();
+ render_pass_quad->SetNew(pass_shared_state.get(),
+ pass_rect,
+ child_pass_id,
+ false,
+ 0,
+ pass_rect,
+ gfx::RectF(),
+ WebKit::WebFilterOperations(),
+ filter,
+ WebKit::WebFilterOperations());
+
+ root_pass->quad_list.push_back(render_pass_quad.PassAs<DrawQuad>());
+ RenderPassList pass_list;
+
+ pass_list.push_back(child_pass.Pass());
+ pass_list.push_back(root_pass.Pass());
+
+ renderer_->SetEnlargePassTextureAmountForTesting(gfx::Vector2d(50, 75));
+ renderer_->DecideRenderPassAllocationsForFrame(pass_list);
+ renderer_->DrawFrame(pass_list);
+
+ EXPECT_TRUE(PixelsMatchReference(
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow_alpha_translate.png")),
+ false));
}
TEST_F(GLRendererPixelTest, RenderPassChangesSize) {
@@ -144,7 +344,7 @@ TEST_F(GLRendererPixelTest, RenderPassChangesSize) {
renderer_->DrawFrame(pass_list);
EXPECT_TRUE(PixelsMatchReference(
- base::FilePath(FILE_PATH_LITERAL("blue_yellow.png"))));
+ base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")), true));
}
class GLRendererPixelTestWithBackgroundFilter : public GLRendererPixelTest {
@@ -271,7 +471,7 @@ TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
DrawFrame();
EXPECT_TRUE(PixelsMatchReference(
- base::FilePath(FILE_PATH_LITERAL("background_filter.png"))));
+ base::FilePath(FILE_PATH_LITERAL("background_filter.png")), true));
}
TEST_F(GLRendererPixelTest, AntiAliasing) {
@@ -317,7 +517,7 @@ TEST_F(GLRendererPixelTest, AntiAliasing) {
renderer_->DrawFrame(pass_list);
EXPECT_TRUE(PixelsMatchReference(
- base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png"))));
+ base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png")), true));
}
#endif
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index 21a00d0..09e6439 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -5,12 +5,12 @@
#include "cc/output/gl_renderer.h"
#include "cc/output/compositor_frame_metadata.h"
-#include "cc/quads/draw_quad.h"
#include "cc/resources/prioritized_resource_manager.h"
#include "cc/resources/resource_provider.h"
#include "cc/test/fake_impl_proxy.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_output_surface.h"
+#include "cc/test/mock_quad_culler.h"
#include "cc/test/pixel_test.h"
#include "cc/test/render_pass_test_common.h"
#include "cc/test/render_pass_test_utils.h"
@@ -18,6 +18,10 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "third_party/skia/include/core/SkImageFilter.h"
+#include "third_party/skia/include/core/SkMatrix.h"
+#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
+#include "third_party/skia/include/effects/SkColorMatrixFilter.h"
#include "ui/gfx/transform.h"
using namespace WebKit;
@@ -40,7 +44,7 @@ namespace cc {
} while (false)
// Explicitly named to be a friend in GLRenderer for shader access.
-class GLRendererShaderTest : public PixelTest {
+class GLRendererShaderPixelTest : public PixelTest {
public:
void TestShaders() {
ASSERT_FALSE(renderer_->IsContextLost());
@@ -55,6 +59,10 @@ class GLRendererShaderTest : public PixelTest {
EXPECT_PROGRAM_VALID(renderer_->GetRenderPassProgramAA());
EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgram());
EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskProgramAA());
+ EXPECT_PROGRAM_VALID(renderer_->GetRenderPassColorMatrixProgram());
+ EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskColorMatrixProgramAA());
+ EXPECT_PROGRAM_VALID(renderer_->GetRenderPassColorMatrixProgramAA());
+ EXPECT_PROGRAM_VALID(renderer_->GetRenderPassMaskColorMatrixProgram());
EXPECT_PROGRAM_VALID(renderer_->GetTextureProgram());
EXPECT_PROGRAM_VALID(renderer_->GetTextureProgramFlip());
EXPECT_PROGRAM_VALID(renderer_->GetTextureIOSurfaceProgram());
@@ -74,7 +82,7 @@ class GLRendererShaderTest : public PixelTest {
namespace {
#if !defined(OS_ANDROID)
-TEST_F(GLRendererShaderTest, AllShadersCompile) { TestShaders(); }
+TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); }
#endif
class FrameCountingMemoryAllocationSettingContext :
@@ -232,7 +240,77 @@ class GLRendererTest : public testing::Test {
FakeRendererGL renderer_;
};
-// Test GLRenderer DiscardBackbuffer functionality:
+// Closing the namespace here so that GLRendererShaderTest can take advantage
+// of the friend relationship with GLRenderer and all of the mock classes
+// declared above it.
+} // namespace
+
+class GLRendererShaderTest : public testing::Test {
+protected:
+ GLRendererShaderTest()
+ : output_surface_(FakeOutputSurface::Create3d())
+ , resource_provider_(ResourceProvider::Create(output_surface_.get()))
+ , renderer_(GLRenderer::Create(&mock_client_, output_surface_.get(), resource_provider_.get()))
+ {
+ }
+
+ void TestRenderPassProgram() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_program_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_program_->program());
+ }
+
+ void TestRenderPassColorMatrixProgram() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_color_matrix_program_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_color_matrix_program_->program());
+ }
+
+ void TestRenderPassMaskProgram() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_mask_program_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_mask_program_->program());
+ }
+
+ void TestRenderPassMaskColorMatrixProgram() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_mask_color_matrix_program_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_mask_color_matrix_program_->program());
+ }
+
+ void TestRenderPassProgramAA() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_program_aa_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_program_aa_->program());
+ }
+
+ void TestRenderPassColorMatrixProgramAA() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_color_matrix_program_aa_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_color_matrix_program_aa_->program());
+ }
+
+ void TestRenderPassMaskProgramAA() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_mask_program_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_program_aa_->program());
+ }
+
+ void TestRenderPassMaskColorMatrixProgramAA() {
+ EXPECT_PROGRAM_VALID(renderer_->render_pass_mask_color_matrix_program_aa_);
+ EXPECT_TRUE(renderer_->program_shadow_ ==
+ renderer_->render_pass_color_matrix_program_aa_->program());
+ }
+
+ scoped_ptr<OutputSurface> output_surface_;
+ FakeRendererClient mock_client_;
+ scoped_ptr<ResourceProvider> resource_provider_;
+ scoped_ptr<GLRenderer> renderer_;
+};
+
+namespace {
+
+// Test GLRenderer discardBackbuffer functionality:
// Suggest recreating framebuffer when one already exists.
// Expected: it does nothing.
TEST_F(GLRendererTest, SuggestBackbufferYesWhenItAlreadyExistsShouldDoNothing) {
@@ -907,6 +985,241 @@ TEST(GLRendererTest2, ScissorTestWhenClearing) {
renderer.DrawFrame(*mock_client.render_passes_in_draw_order());
}
+TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) {
+ gfx::Rect viewportRect(mock_client_.DeviceViewportSize());
+ ScopedPtrVector<RenderPass>& renderPasses =
+ *mock_client_.render_passes_in_draw_order();
+
+ gfx::Rect grandChildRect(25, 25);
+ RenderPass::Id grandChildPassId(3, 0);
+ TestRenderPass* grandChildPass;
+
+ gfx::Rect childRect(50, 50);
+ RenderPass::Id childPassId(2, 0);
+ TestRenderPass* childPass;
+
+ RenderPass::Id rootPassId(1, 0);
+ TestRenderPass* rootPass;
+
+ cc::ResourceProvider::ResourceId mask =
+ resource_provider_->CreateResource(gfx::Size(20, 12),
+ resource_provider_->best_texture_format(),
+ ResourceProvider::TextureUsageAny);
+ resource_provider_->AllocateForTesting(mask);
+
+ SkScalar matrix[20];
+ float amount = 0.5f;
+ matrix[0] = 0.213f + 0.787f * amount;
+ matrix[1] = 0.715f - 0.715f * amount;
+ matrix[2] = 1.f - (matrix[0] + matrix[1]);
+ matrix[3] = matrix[4] = 0;
+ matrix[5] = 0.213f - 0.213f * amount;
+ matrix[6] = 0.715f + 0.285f * amount;
+ matrix[7] = 1.f - (matrix[5] + matrix[6]);
+ matrix[8] = matrix[9] = 0;
+ matrix[10] = 0.213f - 0.213f * amount;
+ matrix[11] = 0.715f - 0.715f * amount;
+ matrix[12] = 1.f - (matrix[10] + matrix[11]);
+ matrix[13] = matrix[14] = 0;
+ matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0;
+ matrix[18] = 1;
+ skia::RefPtr<SkColorFilter> colorFilter(skia::AdoptRef(
+ new SkColorMatrixFilter(matrix)));
+ skia::RefPtr<SkImageFilter> filter =
+ skia::AdoptRef(SkColorFilterImageFilter::Create(colorFilter.get(), NULL));
+
+ gfx::Transform transform_causing_aa;
+ transform_causing_aa.Rotate(20.0);
+
+ // RenderPassProgram
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ gfx::Transform());
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ gfx::Transform());
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, 0, skia::RefPtr<SkImageFilter>(),
+ gfx::Transform());
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassProgram();
+
+ // RenderPassColorMatrixProgram
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ transform_causing_aa);
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ transform_causing_aa);
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, 0, filter, gfx::Transform());
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassColorMatrixProgram();
+
+ // RenderPassMaskProgram
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ gfx::Transform());
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ gfx::Transform());
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, mask, skia::RefPtr<SkImageFilter>(),
+ gfx::Transform());
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassMaskProgram();
+
+ // RenderPassMaskColorMatrixProgram
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ gfx::Transform());
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ gfx::Transform());
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, mask, filter, gfx::Transform());
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassMaskColorMatrixProgram();
+
+ // RenderPassProgramAA
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ transform_causing_aa);
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ transform_causing_aa);
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, 0, skia::RefPtr<SkImageFilter>(),
+ transform_causing_aa);
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassProgramAA();
+
+ // RenderPassColorMatrixProgramAA
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ transform_causing_aa);
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ transform_causing_aa);
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, 0, filter, transform_causing_aa);
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassColorMatrixProgramAA();
+
+ // RenderPassMaskProgramAA
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ transform_causing_aa);
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ transform_causing_aa);
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ gfx::Transform());
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, mask, skia::RefPtr<SkImageFilter>(),
+ transform_causing_aa);
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassMaskProgramAA();
+
+ // RenderPassMaskColorMatrixProgramAA
+ renderPasses.clear();
+
+ grandChildPass = AddRenderPass(renderPasses, grandChildPassId, grandChildRect,
+ transform_causing_aa);
+ AddClippedQuad(grandChildPass, grandChildRect, SK_ColorYELLOW);
+
+ childPass = AddRenderPass(renderPasses, childPassId, childRect,
+ transform_causing_aa);
+ AddQuad(childPass, childRect, SK_ColorBLUE);
+
+ rootPass = AddRenderPass(renderPasses, rootPassId, viewportRect,
+ transform_causing_aa);
+ AddQuad(rootPass, viewportRect, SK_ColorGREEN);
+
+ AddRenderPassQuad(rootPass, childPass, mask, filter, transform_causing_aa);
+ AddRenderPassQuad(childPass, grandChildPass);
+
+ renderer_->DecideRenderPassAllocationsForFrame(
+ *mock_client_.render_passes_in_draw_order());
+ renderer_->DrawFrame(*mock_client_.render_passes_in_draw_order());
+ TestRenderPassMaskColorMatrixProgramAA();
+}
+
class OutputSurfaceMockContext : public TestWebGraphicsContext3D {
public:
// Specifically override methods even if they are unused (used in conjunction
diff --git a/cc/output/shader.cc b/cc/output/shader.cc
index 0200b6d..142e459 100644
--- a/cc/output/shader.cc
+++ b/cc/output/shader.cc
@@ -420,6 +420,41 @@ void FragmentTexAlphaBinding::Init(WebGraphicsContext3D* context,
DCHECK(sampler_location_ != -1 && alpha_location_ != -1);
}
+FragmentTexColorMatrixAlphaBinding::FragmentTexColorMatrixAlphaBinding()
+ : sampler_location_(-1)
+ , alpha_location_(-1)
+ , color_matrix_location_(-1)
+ , color_offset_location_(-1) {}
+
+void FragmentTexColorMatrixAlphaBinding::Init(WebGraphicsContext3D* context,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex) {
+ static const char* shaderUniforms[] = {
+ "s_texture",
+ "alpha",
+ "colorMatrix",
+ "colorOffset",
+ };
+ int locations[4];
+
+ GetProgramUniformLocations(context,
+ program,
+ shaderUniforms,
+ arraysize(shaderUniforms),
+ arraysize(locations),
+ locations,
+ usingBindUniform,
+ baseUniformIndex);
+
+ sampler_location_ = locations[0];
+ alpha_location_ = locations[1];
+ color_matrix_location_ = locations[2];
+ color_offset_location_ = locations[3];
+ DCHECK(sampler_location_ != -1 && alpha_location_ != -1 &&
+ color_matrix_location_ != -1 && color_offset_location_ != -1);
+}
+
FragmentTexOpaqueBinding::FragmentTexOpaqueBinding()
: sampler_location_(-1) {}
@@ -494,6 +529,26 @@ std::string FragmentShaderRGBATexAlpha::GetShaderString() const {
);
}
+std::string FragmentShaderRGBATexColorMatrixAlpha::GetShaderString() const {
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform float alpha;
+ uniform mat4 colorMatrix;
+ uniform vec4 colorOffset;
+ void main() {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ float nonZeroAlpha = max(texColor.a, 0.00001);
+ texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
+ texColor = colorMatrix * texColor + colorOffset;
+ texColor.rgb *= texColor.a;
+ texColor = clamp(texColor, 0.0, 1.0);
+ gl_FragColor = texColor * alpha;
+ }
+ );
+}
+
std::string FragmentShaderRGBATexVaryingAlpha::GetShaderString() const {
return SHADER(
precision mediump float;
@@ -847,6 +902,232 @@ std::string FragmentShaderRGBATexAlphaMaskAA::GetShaderString() const {
);
}
+FragmentShaderRGBATexAlphaMaskColorMatrixAA::FragmentShaderRGBATexAlphaMaskColorMatrixAA()
+ : sampler_location_(-1)
+ , mask_sampler_location_(-1)
+ , alpha_location_(-1)
+ , edge_location_(-1)
+ , mask_tex_coord_scale_location_(-1)
+ , color_matrix_location_(-1)
+ , color_offset_location_(-1) {}
+
+void FragmentShaderRGBATexAlphaMaskColorMatrixAA::Init(
+ WebGraphicsContext3D* context,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex) {
+ static const char* shaderUniforms[] = {
+ "s_texture",
+ "s_mask",
+ "alpha",
+ "edge",
+ "maskTexCoordScale",
+ "maskTexCoordOffset",
+ "colorMatrix",
+ "colorOffset",
+ };
+ int locations[8];
+
+ GetProgramUniformLocations(context,
+ program,
+ shaderUniforms,
+ arraysize(shaderUniforms),
+ arraysize(locations),
+ locations,
+ usingBindUniform,
+ baseUniformIndex);
+
+ sampler_location_ = locations[0];
+ mask_sampler_location_ = locations[1];
+ alpha_location_ = locations[2];
+ edge_location_ = locations[3];
+ mask_tex_coord_scale_location_ = locations[4];
+ mask_tex_coord_offset_location_ = locations[5];
+ color_matrix_location_ = locations[6];
+ color_offset_location_ = locations[7];
+ DCHECK(sampler_location_ != -1 && mask_sampler_location_ != -1 &&
+ alpha_location_ != -1 && edge_location_ != -1 &&
+ color_matrix_location_ != -1 && color_offset_location_ != -1);
+}
+
+std::string FragmentShaderRGBATexAlphaMaskColorMatrixAA::GetShaderString() const {
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform sampler2D s_mask;
+ uniform vec2 maskTexCoordScale;
+ uniform vec2 maskTexCoordOffset;
+ uniform mat4 colorMatrix;
+ uniform vec4 colorOffset;
+ uniform float alpha;
+ uniform vec3 edge[8];
+ void main() {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ float nonZeroAlpha = max(texColor.a, 0.00001);
+ texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
+ texColor = colorMatrix * texColor + colorOffset;
+ texColor.rgb *= texColor.a;
+ texColor = clamp(texColor, 0.0, 1.0);
+ vec2 maskTexCoord =
+ vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
+ maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
+ vec4 maskColor = texture2D(s_mask, maskTexCoord);
+ vec3 pos = vec3(gl_FragCoord.xy, 1);
+ float a0 = clamp(dot(edge[0], pos), 0.0, 1.0);
+ float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
+ float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
+ float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
+ float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
+ float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
+ float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
+ float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
+ gl_FragColor =
+ vec4(texColor.x, texColor.y, texColor.z, texColor.w) *
+ alpha * maskColor.w * min(min(a0, a2) * min(a1, a3), min(a4, a6) *
+ min(a5, a7));
+ }
+ );
+}
+
+FragmentShaderRGBATexAlphaColorMatrixAA::FragmentShaderRGBATexAlphaColorMatrixAA()
+ : sampler_location_(-1)
+ , alpha_location_(-1)
+ , edge_location_(-1)
+ , color_matrix_location_(-1)
+ , color_offset_location_(-1) {}
+
+void FragmentShaderRGBATexAlphaColorMatrixAA::Init(
+ WebGraphicsContext3D* context, unsigned program, bool usingBindUniform,
+ int* baseUniformIndex) {
+ static const char* shaderUniforms[] = {
+ "s_texture",
+ "alpha",
+ "edge",
+ "colorMatrix",
+ "colorOffset",
+ };
+ int locations[5];
+
+ GetProgramUniformLocations(context,
+ program,
+ shaderUniforms,
+ arraysize(shaderUniforms),
+ arraysize(locations),
+ locations,
+ usingBindUniform,
+ baseUniformIndex);
+
+ sampler_location_ = locations[0];
+ alpha_location_ = locations[1];
+ edge_location_ = locations[2];
+ color_matrix_location_ = locations[3];
+ color_offset_location_ = locations[4];
+ DCHECK(sampler_location_ != -1 && alpha_location_ != -1 &&
+ edge_location_ != -1 && color_matrix_location_ != -1 &&
+ color_offset_location_ != -1);
+}
+
+std::string FragmentShaderRGBATexAlphaColorMatrixAA::GetShaderString() const {
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform float alpha;
+ uniform mat4 colorMatrix;
+ uniform vec4 colorOffset;
+ uniform vec3 edge[8];
+ void main() {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ float nonZeroAlpha = max(texColor.a, 0.00001);
+ texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
+ texColor = colorMatrix * texColor + colorOffset;
+ texColor.rgb *= texColor.a;
+ texColor = clamp(texColor, 0.0, 1.0);
+ vec3 pos = vec3(gl_FragCoord.xy, 1);
+ float a0 = clamp(dot(edge[0], pos), 0.0, 1.0);
+ float a1 = clamp(dot(edge[1], pos), 0.0, 1.0);
+ float a2 = clamp(dot(edge[2], pos), 0.0, 1.0);
+ float a3 = clamp(dot(edge[3], pos), 0.0, 1.0);
+ float a4 = clamp(dot(edge[4], pos), 0.0, 1.0);
+ float a5 = clamp(dot(edge[5], pos), 0.0, 1.0);
+ float a6 = clamp(dot(edge[6], pos), 0.0, 1.0);
+ float a7 = clamp(dot(edge[7], pos), 0.0, 1.0);
+ gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) *
+ alpha * min(min(a0, a2) * min(a1, a3), min(a4, a6) * min(a5, a7));
+ }
+ );
+}
+
+FragmentShaderRGBATexAlphaMaskColorMatrix::FragmentShaderRGBATexAlphaMaskColorMatrix()
+ : sampler_location_(-1)
+ , mask_sampler_location_(-1)
+ , alpha_location_(-1)
+ , mask_tex_coord_scale_location_(-1) {}
+
+void FragmentShaderRGBATexAlphaMaskColorMatrix::Init(
+ WebGraphicsContext3D* context, unsigned program, bool usingBindUniform,
+ int* baseUniformIndex) {
+ static const char* shaderUniforms[] = {
+ "s_texture",
+ "s_mask",
+ "alpha",
+ "maskTexCoordScale",
+ "maskTexCoordOffset",
+ "colorMatrix",
+ "colorOffset",
+ };
+ int locations[7];
+
+ GetProgramUniformLocations(context,
+ program,
+ shaderUniforms,
+ arraysize(shaderUniforms),
+ arraysize(locations),
+ locations,
+ usingBindUniform,
+ baseUniformIndex);
+
+ sampler_location_ = locations[0];
+ mask_sampler_location_ = locations[1];
+ alpha_location_ = locations[2];
+ mask_tex_coord_scale_location_ = locations[3];
+ mask_tex_coord_offset_location_ = locations[4];
+ color_matrix_location_ = locations[5];
+ color_offset_location_ = locations[6];
+ DCHECK(sampler_location_ != -1 && mask_sampler_location_ != -1 &&
+ alpha_location_ != -1 && color_matrix_location_ != -1 &&
+ color_offset_location_ != -1);
+}
+
+std::string FragmentShaderRGBATexAlphaMaskColorMatrix::GetShaderString() const {
+ return SHADER(
+ precision mediump float;
+ varying vec2 v_texCoord;
+ uniform sampler2D s_texture;
+ uniform sampler2D s_mask;
+ uniform vec2 maskTexCoordScale;
+ uniform vec2 maskTexCoordOffset;
+ uniform mat4 colorMatrix;
+ uniform vec4 colorOffset;
+ uniform float alpha;
+ void main() {
+ vec4 texColor = texture2D(s_texture, v_texCoord);
+ float nonZeroAlpha = max(texColor.a, 0.00001);
+ texColor = vec4(texColor.rgb / nonZeroAlpha, nonZeroAlpha);
+ texColor = colorMatrix * texColor + colorOffset;
+ texColor.rgb *= texColor.a;
+ texColor = clamp(texColor, 0.0, 1.0);
+ vec2 maskTexCoord =
+ vec2(maskTexCoordOffset.x + v_texCoord.x * maskTexCoordScale.x,
+ maskTexCoordOffset.y + v_texCoord.y * maskTexCoordScale.y);
+ vec4 maskColor = texture2D(s_mask, maskTexCoord);
+ gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) *
+ alpha * maskColor.w;
+ }
+ );
+}
+
FragmentShaderYUVVideo::FragmentShaderYUVVideo()
: y_texture_location_(-1),
u_texture_location_(-1),
diff --git a/cc/output/shader.h b/cc/output/shader.h
index fb8d658..3dc265d 100644
--- a/cc/output/shader.h
+++ b/cc/output/shader.h
@@ -103,7 +103,7 @@ class VertexShaderQuad {
VertexShaderQuad();
void Init(WebKit::WebGraphicsContext3D*,
- unsigned program,
+ unsigned program,
bool using_bind_uniform,
int* base_uniform_index);
std::string GetShaderString() const;
@@ -176,6 +176,28 @@ class FragmentTexAlphaBinding {
int alpha_location_;
};
+class FragmentTexColorMatrixAlphaBinding {
+public:
+ FragmentTexColorMatrixAlphaBinding();
+
+ void Init(WebKit::WebGraphicsContext3D*,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex);
+ int alpha_location() const { return alpha_location_; }
+ int color_matrix_location() const { return color_matrix_location_; }
+ int color_offset_location() const { return color_offset_location_; }
+ int edge_location() const { return -1; }
+ int fragment_tex_transform_location() const { return -1; }
+ int sampler_location() const { return sampler_location_; }
+
+private:
+ int sampler_location_;
+ int alpha_location_;
+ int color_matrix_location_;
+ int color_offset_location_;
+};
+
class FragmentTexOpaqueBinding {
public:
FragmentTexOpaqueBinding();
@@ -203,6 +225,11 @@ class FragmentShaderRGBATexAlpha : public FragmentTexAlphaBinding {
std::string GetShaderString() const;
};
+class FragmentShaderRGBATexColorMatrixAlpha : public FragmentTexColorMatrixAlphaBinding {
+public:
+ std::string GetShaderString() const;
+};
+
class FragmentShaderRGBATexRectVaryingAlpha : public FragmentTexAlphaBinding {
public:
std::string GetShaderString() const;
@@ -353,6 +380,93 @@ class FragmentShaderRGBATexAlphaMaskAA {
int mask_tex_coord_offset_location_;
};
+class FragmentShaderRGBATexAlphaMaskColorMatrixAA {
+public:
+ FragmentShaderRGBATexAlphaMaskColorMatrixAA();
+ std::string GetShaderString() const;
+
+ void Init(WebKit::WebGraphicsContext3D*,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex);
+ int alpha_location() const { return alpha_location_; }
+ int sampler_location() const { return sampler_location_; }
+ int mask_sampler_location() const { return mask_sampler_location_; }
+ int edge_location() const { return edge_location_; }
+ int mask_tex_coord_scale_location() const {
+ return mask_tex_coord_scale_location_;
+ }
+ int mask_tex_coord_offset_location() const {
+ return mask_tex_coord_offset_location_;
+ }
+ int color_matrix_location() const { return color_matrix_location_; }
+ int color_offset_location() const { return color_offset_location_; }
+
+private:
+ int sampler_location_;
+ int mask_sampler_location_;
+ int alpha_location_;
+ int edge_location_;
+ int mask_tex_coord_scale_location_;
+ int mask_tex_coord_offset_location_;
+ int color_matrix_location_;
+ int color_offset_location_;
+};
+
+class FragmentShaderRGBATexAlphaColorMatrixAA {
+public:
+ FragmentShaderRGBATexAlphaColorMatrixAA();
+ std::string GetShaderString() const;
+
+ void Init(WebKit::WebGraphicsContext3D*,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex);
+ int alpha_location() const { return alpha_location_; }
+ int sampler_location() const { return sampler_location_; }
+ int edge_location() const { return edge_location_; }
+ int color_matrix_location() const { return color_matrix_location_; }
+ int color_offset_location() const { return color_offset_location_; }
+
+private:
+ int sampler_location_;
+ int alpha_location_;
+ int edge_location_;
+ int color_matrix_location_;
+ int color_offset_location_;
+};
+
+class FragmentShaderRGBATexAlphaMaskColorMatrix {
+public:
+ FragmentShaderRGBATexAlphaMaskColorMatrix();
+ std::string GetShaderString() const;
+
+ void Init(WebKit::WebGraphicsContext3D*,
+ unsigned program,
+ bool usingBindUniform,
+ int* baseUniformIndex);
+ int alpha_location() const { return alpha_location_; }
+ int sampler_location() const { return sampler_location_; }
+ int mask_sampler_location() const { return mask_sampler_location_; }
+ int mask_tex_coord_scale_location() const {
+ return mask_tex_coord_scale_location_;
+ }
+ int mask_tex_coord_offset_location() const {
+ return mask_tex_coord_offset_location_;
+ }
+ int color_matrix_location() const { return color_matrix_location_; }
+ int color_offset_location() const { return color_offset_location_; }
+
+private:
+ int sampler_location_;
+ int mask_sampler_location_;
+ int alpha_location_;
+ int mask_tex_coord_scale_location_;
+ int mask_tex_coord_offset_location_;
+ int color_matrix_location_;
+ int color_offset_location_;
+};
+
class FragmentShaderYUVVideo {
public:
FragmentShaderYUVVideo();
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index bb8e64e..e68cd79 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -66,7 +66,7 @@ void LayerTreePixelTest::SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
// To rebaseline:
// EXPECT_TRUE(WritePNGFile(bitmap, test_data_dir.Append(ref_file_)));
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, test_data_dir.Append(ref_file_)));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, test_data_dir.Append(ref_file_), true));
EndTest();
}
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 4b44ecb..040f5f3 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -75,7 +75,8 @@ void PixelTest::SetUp() {
resource_provider_->set_offscreen_context_provider(offscreen_contexts);
}
-bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file) {
+bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
+ bool discard_transparency) {
gfx::Rect device_viewport_rect(device_viewport_size_);
SkBitmap bitmap;
@@ -93,7 +94,8 @@ bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file) {
// To rebaseline:
// return WritePNGFile(bitmap, test_data_dir.Append(ref_file));
- return IsSameAsPNGFile(bitmap, test_data_dir.Append(ref_file));
+ return IsSameAsPNGFile(bitmap, test_data_dir.Append(ref_file),
+ discard_transparency);
}
} // namespace cc
diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h
index 40acb33..3762d60 100644
--- a/cc/test/pixel_test.h
+++ b/cc/test/pixel_test.h
@@ -21,7 +21,8 @@ class PixelTest : public testing::Test {
virtual void SetUp() OVERRIDE;
- bool PixelsMatchReference(const base::FilePath& ref_file);
+ bool PixelsMatchReference(const base::FilePath& ref_file,
+ bool discard_transparency);
gfx::Size device_viewport_size_;
scoped_ptr<OutputSurface> output_surface_;
diff --git a/cc/test/pixel_test_utils.cc b/cc/test/pixel_test_utils.cc
index ead2f6f..cedb386 100644
--- a/cc/test/pixel_test_utils.cc
+++ b/cc/test/pixel_test_utils.cc
@@ -14,9 +14,9 @@
namespace cc {
-bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path) {
+bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
+ bool discard_transparency) {
std::vector<unsigned char> png_data;
- const bool discard_transparency = true;
if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap,
discard_transparency,
&png_data) &&
@@ -37,7 +37,8 @@ bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap) {
bitmap);
}
-bool IsSameAsPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path) {
+bool IsSameAsPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path,
+ bool discard_transparency) {
SkBitmap ref_bmp;
if (!ReadPNGFile(ref_img_path, &ref_bmp)) {
LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value();
@@ -60,7 +61,12 @@ bool IsSameAsPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path) {
SkAutoLockPixels lock_ref_bmp(ref_bmp);
// The reference images were saved with no alpha channel. Use the mask to
// set alpha to 0.
- uint32_t kAlphaMask = 0x00FFFFFF;
+ uint32_t kAlphaMask;
+ if (discard_transparency)
+ kAlphaMask = 0x00FFFFFF;
+ else
+ kAlphaMask = 0xFFFFFFFF;
+
for (int x = 0; x < gen_bmp.width(); ++x) {
for (int y = 0; y < gen_bmp.height(); ++y) {
if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) !=
diff --git a/cc/test/pixel_test_utils.h b/cc/test/pixel_test_utils.h
index 29dad87..2ee2ecd 100644
--- a/cc/test/pixel_test_utils.h
+++ b/cc/test/pixel_test_utils.h
@@ -13,7 +13,8 @@ namespace cc {
// Encodes a bitmap into a PNG and write to disk. Returns true on success. The
// parent directory does not have to exist.
-bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path);
+bool WritePNGFile(const SkBitmap& bitmap, const base::FilePath& file_path,
+ bool discard_transparency);
// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG
// should have been encoded using |gfx::PNGCodec::Encode|.
@@ -21,7 +22,8 @@ bool ReadPNGFile(const base::FilePath& file_path, SkBitmap* bitmap);
// Compares with a PNG file on disk, and returns true if it is the same as
// the given image. |ref_img_path| is absolute.
-bool IsSameAsPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path);
+bool IsSameAsPNGFile(const SkBitmap& gen_bmp, base::FilePath ref_img_path,
+ bool discard_transparency);
} // namespace cc
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc
index 94d0f64..24cb778 100644
--- a/cc/test/render_pass_test_utils.cc
+++ b/cc/test/render_pass_test_utils.cc
@@ -9,6 +9,7 @@
#include "cc/quads/render_pass_draw_quad.h"
#include "cc/quads/shared_quad_state.h"
#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/resources/resource_provider.h"
#include "cc/test/mock_quad_culler.h"
#include "cc/test/render_pass_test_common.h"
#include "ui/gfx/rect.h"
@@ -73,4 +74,25 @@ void AddRenderPassQuad(TestRenderPass* to_pass,
quad_sink.Append(quad.PassAs<DrawQuad>(), &data);
}
+void AddRenderPassQuad(TestRenderPass* to_pass,
+ TestRenderPass* contributing_pass,
+ ResourceProvider::ResourceId mask_resource_id,
+ skia::RefPtr<SkImageFilter> filter,
+ gfx::Transform transform) {
+ MockQuadCuller quad_sink(&to_pass->quad_list,
+ &to_pass->shared_quad_state_list);
+ AppendQuadsData data(to_pass->id);
+ gfx::Rect output_rect = contributing_pass->output_rect;
+ SharedQuadState* shared_state =
+ quad_sink.UseSharedQuadState(SharedQuadState::Create());
+ shared_state->SetAll(
+ transform, output_rect.size(), output_rect, output_rect, false, 1);
+ scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
+ quad->SetNew(shared_state, output_rect, contributing_pass->id, false,
+ mask_resource_id, output_rect, gfx::RectF(),
+ WebKit::WebFilterOperations(),
+ filter, WebKit::WebFilterOperations());
+ quad_sink.Append(quad.PassAs<DrawQuad>(), &data);
+}
+
} // namespace cc
diff --git a/cc/test/render_pass_test_utils.h b/cc/test/render_pass_test_utils.h
index 83e5d90..fdc6366 100644
--- a/cc/test/render_pass_test_utils.h
+++ b/cc/test/render_pass_test_utils.h
@@ -7,6 +7,7 @@
#include "cc/base/scoped_ptr_vector.h"
#include "cc/quads/render_pass.h"
+#include "cc/resources/resource_provider.h"
#include "third_party/skia/include/core/SkColor.h"
namespace gfx {
@@ -41,6 +42,13 @@ SolidColorDrawQuad* AddClippedQuad(TestRenderPass* pass,
void AddRenderPassQuad(TestRenderPass* to_pass,
TestRenderPass* contributing_pass);
+// Adds a render pass quad with the given mask resource, filter, and transform.
+void AddRenderPassQuad(TestRenderPass* toPass,
+ TestRenderPass* contributingPass,
+ ResourceProvider::ResourceId mask_resource_id,
+ skia::RefPtr<SkImageFilter> filter,
+ gfx::Transform transform);
+
} // namespace cc
#endif // CC_TEST_RENDER_PASS_TEST_UTILS_H_
diff --git a/ui/compositor/layer_unittest.cc b/ui/compositor/layer_unittest.cc
index aaba292..5dda85f 100644
--- a/ui/compositor/layer_unittest.cc
+++ b/ui/compositor/layer_unittest.cc
@@ -919,35 +919,35 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_ModifyHierarchy) {
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img1);
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1, true));
l0->StackAtTop(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img2);
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2, true));
// l11 is already at the front, should have no effect.
l0->StackAtTop(l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2, true));
// l11 is already at the front, should have no effect.
l0->StackAbove(l11.get(), l12.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img2, true));
// should restore to original configuration
l0->StackAbove(l12.get(), l11.get());
DrawTree(l0.get());
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img1, true));
}
// Opacity is rendered correctly.
@@ -971,7 +971,7 @@ TEST_F(LayerWithRealCompositorTest, MAYBE_Opacity) {
ASSERT_TRUE(ReadPixels(&bitmap));
ASSERT_FALSE(bitmap.empty());
// WritePNGFile(bitmap, ref_img);
- EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img));
+ EXPECT_TRUE(IsSameAsPNGFile(bitmap, ref_img, true));
}
namespace {