summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 19:51:46 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-12 19:51:46 +0000
commit4bdeb9865d23bec03b7a16dfb7d74dc69d5f399e (patch)
treea52f2f39053e073b4aa26c9879d79bd4a7b17d22
parentb6a6de7a7d4b2b8a1a2fe8abf0b910646a112139 (diff)
downloadchromium_src-4bdeb9865d23bec03b7a16dfb7d74dc69d5f399e.zip
chromium_src-4bdeb9865d23bec03b7a16dfb7d74dc69d5f399e.tar.gz
chromium_src-4bdeb9865d23bec03b7a16dfb7d74dc69d5f399e.tar.bz2
cc: Fix masks when the RenderPassDrawQuad does not cover the whole pass
If the RenderPassDrawQuad is not the same size as the texture backing the RenderPass, then we have to scale the texture coordinates when reading the pass texture. If the pass has a mask as well, we have to scale those coordinates as well. However the coordinates given to the mask shader are already scaled to the size of the contents texture. We further scale and offset the coordinates but the offset was incorrect. Tested by: RendererPixelTest.RenderPassAndMaskWithPartialQuad LayerTreeHostMasksPixelTest.MaskOfClippedLayer R=enne BUG=264534 Review URL: https://codereview.chromium.org/27040003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@228376 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--cc/output/gl_renderer.cc7
-rw-r--r--cc/output/renderer_pixeltest.cc113
2 files changed, 111 insertions, 9 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index 04c1158..bf76071 100644
--- a/cc/output/gl_renderer.cc
+++ b/cc/output/gl_renderer.cc
@@ -1011,9 +1011,10 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
// and the RenderPass contents texture, so we flip the tex coords from the
// RenderPass texture to find the mask texture coords.
GLC(Context(),
- Context()->uniform2f(shader_mask_tex_coord_offset_location,
- quad->mask_uv_rect.x(),
- quad->mask_uv_rect.y() + mask_tex_scale_y));
+ Context()->uniform2f(
+ shader_mask_tex_coord_offset_location,
+ quad->mask_uv_rect.x(),
+ quad->mask_uv_rect.y() + quad->mask_uv_rect.height()));
GLC(Context(),
Context()->uniform2f(shader_mask_tex_coord_scale_location,
mask_tex_scale_x,
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc
index 278b30a..a98ab84 100644
--- a/cc/output/renderer_pixeltest.cc
+++ b/cc/output/renderer_pixeltest.cc
@@ -84,12 +84,12 @@ scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad(
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
- FilterOperations(), // foreground filters
- FilterOperations()); // background filters
+ false, // is_replica
+ 0, // mask_resource_id
+ rect, // contents_changed_since_last_frame
+ gfx::RectF(1.f, 1.f), // mask_uv_rect
+ FilterOperations(), // foreground filters
+ FilterOperations()); // background filters
return quad.PassAs<DrawQuad>();
}
@@ -882,6 +882,107 @@ TYPED_TEST(RendererPixelTest, EnlargedRenderPassTextureWithAntiAliasing) {
FuzzyPixelOffByOneComparator(true)));
}
+// This tests the case where we have a RenderPass with a mask, but the quad
+// for the masked surface does not include the full surface texture.
+TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
+ gfx::Rect viewport_rect(this->device_viewport_size_);
+
+ RenderPass::Id root_pass_id(1, 1);
+ scoped_ptr<RenderPass> root_pass =
+ CreateTestRootRenderPass(root_pass_id, viewport_rect);
+ scoped_ptr<SharedQuadState> root_pass_shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
+
+ RenderPass::Id child_pass_id(2, 2);
+ gfx::Transform transform_to_root;
+ scoped_ptr<RenderPass> child_pass =
+ CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
+ scoped_ptr<SharedQuadState> child_pass_shared_state =
+ CreateTestSharedQuadState(gfx::Transform(), viewport_rect);
+
+ // The child render pass is just a green box.
+ static const SkColor kCSSGreen = 0xff008000;
+ scoped_ptr<SolidColorDrawQuad> green = SolidColorDrawQuad::Create();
+ green->SetNew(child_pass_shared_state.get(), viewport_rect, kCSSGreen, false);
+ child_pass->quad_list.push_back(green.PassAs<DrawQuad>());
+
+ // Make a mask.
+ gfx::Rect mask_rect = viewport_rect;
+ SkBitmap bitmap;
+ bitmap.setConfig(
+ SkBitmap::kARGB_8888_Config, mask_rect.width(), mask_rect.height());
+ bitmap.allocPixels();
+ SkBitmapDevice bitmap_device(bitmap);
+ skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(&bitmap_device));
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(SkIntToScalar(4));
+ paint.setColor(SK_ColorWHITE);
+ canvas->clear(SK_ColorTRANSPARENT);
+ gfx::Rect rect = mask_rect;
+ while (!rect.IsEmpty()) {
+ rect.Inset(6, 6, 4, 4);
+ canvas->drawRect(
+ SkRect::MakeXYWH(rect.x(), rect.y(), rect.width(), rect.height()),
+ paint);
+ rect.Inset(6, 6, 4, 4);
+ }
+
+ ResourceProvider::ResourceId mask_resource_id =
+ this->resource_provider_->CreateResource(
+ mask_rect.size(),
+ GL_CLAMP_TO_EDGE,
+ ResourceProvider::TextureUsageAny,
+ RGBA_8888);
+ {
+ SkAutoLockPixels lock(bitmap);
+ this->resource_provider_->SetPixels(
+ mask_resource_id,
+ reinterpret_cast<uint8_t*>(bitmap.getPixels()),
+ mask_rect,
+ mask_rect,
+ gfx::Vector2d());
+ }
+
+ // This RenderPassDrawQuad does not include the full |viewport_rect| which is
+ // the size of the child render pass.
+ gfx::Rect sub_rect = gfx::Rect(50, 50, 100, 100);
+ EXPECT_NE(sub_rect.x(), child_pass->output_rect.x());
+ EXPECT_NE(sub_rect.y(), child_pass->output_rect.y());
+ EXPECT_NE(sub_rect.right(), child_pass->output_rect.right());
+ EXPECT_NE(sub_rect.bottom(), child_pass->output_rect.bottom());
+ EXPECT_TRUE(child_pass->output_rect.Contains(sub_rect));
+
+ // Set up a mask on the RenderPassDrawQuad.
+ scoped_ptr<RenderPassDrawQuad> mask_quad = RenderPassDrawQuad::Create();
+ mask_quad->SetNew(root_pass_shared_state.get(),
+ sub_rect,
+ child_pass_id,
+ false, // is_replica
+ mask_resource_id,
+ sub_rect, // contents_changed_since_last_frame
+ gfx::RectF(1.f, 1.f), // mask_uv_rect
+ FilterOperations(), // foreground filters
+ FilterOperations()); // background filters
+ root_pass->quad_list.push_back(mask_quad.PassAs<DrawQuad>());
+
+ // White background behind the masked render pass.
+ scoped_ptr<SolidColorDrawQuad> white = SolidColorDrawQuad::Create();
+ white->SetNew(
+ root_pass_shared_state.get(), viewport_rect, SK_ColorWHITE, false);
+ root_pass->quad_list.push_back(white.PassAs<DrawQuad>());
+
+ RenderPassList pass_list;
+ pass_list.push_back(child_pass.Pass());
+ pass_list.push_back(root_pass.Pass());
+
+ EXPECT_TRUE(this->RunPixelTest(
+ &pass_list,
+ PixelTest::NoOffscreenContext,
+ base::FilePath(FILE_PATH_LITERAL("image_mask_of_layer.png")),
+ ExactPixelComparator(true)));
+}
+
template <typename RendererType>
class RendererPixelTestWithBackgroundFilter
: public RendererPixelTest<RendererType> {