blob: 71e89b37cb4388a540174a615480c8279a9b1495 [file] [log] [blame]
// Copyright 2012 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.
#include "cc/gl_renderer.h"
#include "cc/draw_quad.h"
#include "cc/test/pixel_test.h"
namespace cc {
namespace {
class GLRendererPixelTest : public PixelTest {};
scoped_ptr<RenderPass> CreateTestRootRenderPass(RenderPass::Id id,
gfx::Rect rect) {
scoped_ptr<RenderPass> pass = RenderPass::Create();
const gfx::Rect output_rect = rect;
const gfx::RectF damage_rect = rect;
const gfx::Transform transform_to_root_target;
pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
return pass.Pass();
}
scoped_ptr<RenderPass> CreateTestRenderPass(
RenderPass::Id id,
gfx::Rect rect,
const gfx::Transform& transform_to_root_target) {
scoped_ptr<RenderPass> pass = RenderPass::Create();
const gfx::Rect output_rect = rect;
const gfx::RectF damage_rect = rect;
pass->SetNew(id, output_rect, damage_rect, transform_to_root_target);
return pass.Pass();
}
scoped_ptr<SharedQuadState> CreateTestSharedQuadState(
gfx::Transform content_to_target_transform, gfx::Rect rect) {
const gfx::Size content_bounds = rect.size();
const gfx::Rect visible_content_rect = rect;
const gfx::Rect clip_rect = rect;
const bool is_clipped = false;
const float opacity = 1.0f;
scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create();
shared_state->SetAll(content_to_target_transform,
content_bounds,
visible_content_rect,
clip_rect,
is_clipped,
opacity);
return shared_state.Pass();
}
scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad(
SharedQuadState* shared_state, gfx::Rect rect, RenderPass::Id pass_id) {
scoped_ptr<RenderPassDrawQuad> quad = RenderPassDrawQuad::Create();
quad->SetNew(shared_state,
rect,
pass_id,
false, // is_replica
0, // mask_resource_id
rect, // contents_changed_since_last_frame
gfx::RectF(), // mask_uv_rect
WebKit::WebFilterOperations(), // foreground filters
skia::RefPtr<SkImageFilter>(), // foreground filter
WebKit::WebFilterOperations()); // background filters
return quad.PassAs<DrawQuad>();
}
#if !defined(OS_ANDROID)
TEST_F(GLRendererPixelTest, simpleGreenRect) {
gfx::Rect rect(device_viewport_size_);
RenderPass::Id id(1, 1);
scoped_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect);
gfx::Transform content_to_target_transform;
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(content_to_target_transform, rect);
scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN);
pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
renderer_->DrawFrame(pass_list);
EXPECT_TRUE(PixelsMatchReference(
base::FilePath(FILE_PATH_LITERAL("green.png"))));
}
TEST_F(GLRendererPixelTest, RenderPassChangesSize) {
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);
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);
child_pass->quad_list.push_back(blue.PassAs<DrawQuad>());
child_pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
scoped_ptr<SharedQuadState> pass_shared_state =
CreateTestSharedQuadState(gfx::Transform(), pass_rect);
root_pass->quad_list.push_back(
CreateTestRenderPassDrawQuad(pass_shared_state.get(),
pass_rect,
child_pass_id));
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.png"))));
}
class GLRendererPixelTestWithBackgroundFilter : public GLRendererPixelTest {
protected:
void DrawFrame() {
gfx::Rect device_viewport_rect(device_viewport_size_);
RenderPass::Id root_id(1, 1);
scoped_ptr<RenderPass> root_pass =
CreateTestRootRenderPass(root_id, device_viewport_rect);
root_pass->has_transparent_background = false;
gfx::Transform identity_content_to_target_transform;
RenderPass::Id filter_pass_id(2, 1);
gfx::Transform transform_to_root;
scoped_ptr<RenderPass> filter_pass =
CreateTestRenderPass(filter_pass_id,
filter_pass_content_rect_,
transform_to_root);
// A non-visible quad in the filtering render pass.
{
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(identity_content_to_target_transform,
filter_pass_content_rect_);
scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
color_quad->SetNew(shared_state.get(),
filter_pass_content_rect_,
SK_ColorTRANSPARENT);
filter_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
filter_pass->shared_quad_state_list.push_back(shared_state.Pass());
}
{
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(filter_pass_to_target_transform_,
filter_pass_content_rect_);
scoped_ptr<RenderPassDrawQuad> filter_pass_quad =
RenderPassDrawQuad::Create();
filter_pass_quad->SetNew(
shared_state.get(),
filter_pass_content_rect_,
filter_pass_id,
false, // is_replica
0, // mask_resource_id
filter_pass_content_rect_, // contents_changed_since_last_frame
gfx::RectF(), // mask_uv_rect
WebKit::WebFilterOperations(), // filters
skia::RefPtr<SkImageFilter>(), // filter
background_filters_);
root_pass->quad_list.push_back(filter_pass_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_state.Pass());
}
const int kColumnWidth = device_viewport_rect.width() / 3;
gfx::Rect left_rect = gfx::Rect(0, 0, kColumnWidth, 20);
for (int i = 0; left_rect.y() < device_viewport_rect.height(); ++i) {
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(identity_content_to_target_transform,
left_rect);
scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
color_quad->SetNew(shared_state.get(), left_rect, SK_ColorGREEN);
root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_state.Pass());
left_rect += gfx::Vector2d(0, left_rect.height() + 1);
}
gfx::Rect middle_rect = gfx::Rect(kColumnWidth+1, 0, kColumnWidth, 20);
for (int i = 0; middle_rect.y() < device_viewport_rect.height(); ++i) {
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(identity_content_to_target_transform,
middle_rect);
scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
color_quad->SetNew(shared_state.get(), middle_rect, SK_ColorRED);
root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_state.Pass());
middle_rect += gfx::Vector2d(0, middle_rect.height() + 1);
}
gfx::Rect right_rect = gfx::Rect((kColumnWidth+1)*2, 0, kColumnWidth, 20);
for (int i = 0; right_rect.y() < device_viewport_rect.height(); ++i) {
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(identity_content_to_target_transform,
right_rect);
scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create();
color_quad->SetNew(shared_state.get(), right_rect, SK_ColorBLUE);
root_pass->quad_list.push_back(color_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_state.Pass());
right_rect += gfx::Vector2d(0, right_rect.height() + 1);
}
scoped_ptr<SharedQuadState> shared_state =
CreateTestSharedQuadState(identity_content_to_target_transform,
device_viewport_rect);
scoped_ptr<SolidColorDrawQuad> background_quad =
SolidColorDrawQuad::Create();
background_quad->SetNew(shared_state.get(),
device_viewport_rect,
SK_ColorWHITE);
root_pass->quad_list.push_back(background_quad.PassAs<DrawQuad>());
root_pass->shared_quad_state_list.push_back(shared_state.Pass());
RenderPassList pass_list;
pass_list.push_back(filter_pass.Pass());
pass_list.push_back(root_pass.Pass());
renderer_->DecideRenderPassAllocationsForFrame(pass_list);
renderer_->DrawFrame(pass_list);
}
WebKit::WebFilterOperations background_filters_;
gfx::Transform filter_pass_to_target_transform_;
gfx::Rect filter_pass_content_rect_;
};
TEST_F(GLRendererPixelTestWithBackgroundFilter, InvertFilter) {
background_filters_.append(
WebKit::WebFilterOperation::createInvertFilter(1.f));
filter_pass_content_rect_ = gfx::Rect(device_viewport_size_);
filter_pass_content_rect_.Inset(12, 14, 16, 18);
DrawFrame();
EXPECT_TRUE(PixelsMatchReference(
base::FilePath(FILE_PATH_LITERAL("background_filter.png"))));
}
TEST_F(GLRendererPixelTest, AntiAliasing) {
gfx::Rect rect(0, 0, 200, 200);
RenderPass::Id id(1, 1);
gfx::Transform transform_to_root;
scoped_ptr<RenderPass> pass =
CreateTestRenderPass(id, rect, transform_to_root);
gfx::Transform red_content_to_target_transform;
red_content_to_target_transform.Rotate(10);
scoped_ptr<SharedQuadState> red_shared_state =
CreateTestSharedQuadState(red_content_to_target_transform, rect);
scoped_ptr<SolidColorDrawQuad> red = SolidColorDrawQuad::Create();
red->SetNew(red_shared_state.get(), rect, SK_ColorRED);
pass->quad_list.push_back(red.PassAs<DrawQuad>());
gfx::Transform yellow_content_to_target_transform;
yellow_content_to_target_transform.Rotate(5);
scoped_ptr<SharedQuadState> yellow_shared_state =
CreateTestSharedQuadState(yellow_content_to_target_transform, rect);
scoped_ptr<SolidColorDrawQuad> yellow = SolidColorDrawQuad::Create();
yellow->SetNew(yellow_shared_state.get(), rect, SK_ColorYELLOW);
pass->quad_list.push_back(yellow.PassAs<DrawQuad>());
gfx::Transform blue_content_to_target_transform;
scoped_ptr<SharedQuadState> blue_shared_state =
CreateTestSharedQuadState(blue_content_to_target_transform, rect);
scoped_ptr<SolidColorDrawQuad> blue = SolidColorDrawQuad::Create();
blue->SetNew(blue_shared_state.get(), rect, SK_ColorBLUE);
pass->quad_list.push_back(blue.PassAs<DrawQuad>());
RenderPassList pass_list;
pass_list.push_back(pass.Pass());
renderer_->DrawFrame(pass_list);
EXPECT_TRUE(PixelsMatchReference(
base::FilePath(FILE_PATH_LITERAL("anti_aliasing.png"))));
}
#endif
} // namespace
} // namespace cc