Commit fbfb39d1 authored by senorblanco's avatar senorblanco Committed by Commit bot

cc: make partially-resident textures use 1 - y, not h - y.

In Skia, partially-resident textures of "flipped" textures
occupy texcoords 1 to 1 - h (in Y). In cc, they occupy h to
0. In order to ease interop, we should pick a convention and unify.

I chose the Skia model, since coords can flipped with a
simple 1 - y, which doesn't require knowing the height
of the active region. I also added a new test case for
masks, since the math is a little hinky.

CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel

Review URL: https://codereview.chromium.org/1643653002

Cr-Commit-Position: refs/heads/master@{#371930}
parent 61a56fdf
...@@ -550,7 +550,7 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, ...@@ -550,7 +550,7 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame,
if (BindFramebufferToTexture(frame, texture)) { if (BindFramebufferToTexture(frame, texture)) {
InitializeViewport(frame, render_pass->output_rect, InitializeViewport(frame, render_pass->output_rect,
gfx::Rect(render_pass->output_rect.size()), gfx::Rect(render_pass->output_rect.size()),
render_pass->output_rect.size()); texture->size());
return true; return true;
} }
......
...@@ -645,11 +645,6 @@ static skia::RefPtr<SkImage> ApplyImageFilter( ...@@ -645,11 +645,6 @@ static skia::RefPtr<SkImage> ApplyImageFilter(
return skia::RefPtr<SkImage>(); return skia::RefPtr<SkImage>();
} }
// The origin of the filter is top-left and the origin of the source is
// bottom-left, but the orientation is the same, so we must translate the
// filter so that it renders at the bottom of the texture to avoid
// misregistration.
float y_offset = source_texture_resource->size().height() - src_rect.height();
SkMatrix local_matrix; SkMatrix local_matrix;
local_matrix.setScale(scale.x(), scale.y()); local_matrix.setScale(scale.x(), scale.y());
skia::RefPtr<SkImageFilter> filter_with_local_scale = skia::RefPtr<SkImageFilter> filter_with_local_scale =
...@@ -658,8 +653,8 @@ static skia::RefPtr<SkImage> ApplyImageFilter( ...@@ -658,8 +653,8 @@ static skia::RefPtr<SkImage> ApplyImageFilter(
SkPaint paint; SkPaint paint;
paint.setImageFilter(filter_with_local_scale.get()); paint.setImageFilter(filter_with_local_scale.get());
surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y());
surface->getCanvas()->drawImage(srcImage.get(), src_rect.x(), surface->getCanvas()->drawImage(srcImage.get(), src_rect.x(), src_rect.y(),
src_rect.y() - y_offset, &paint); &paint);
skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot());
if (!image || !image->isTextureBacked()) { if (!image || !image->isTextureBacked()) {
...@@ -1143,7 +1138,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1143,7 +1138,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
// Flip the content vertically in the shader, as the RenderPass input // Flip the content vertically in the shader, as the RenderPass input
// texture is already oriented the same way as the framebuffer, but the // texture is already oriented the same way as the framebuffer, but the
// projection transform does a flip. // projection transform does a flip.
gl_->Uniform4f(locations.tex_transform, 0.0f, tex_scale_y, tex_scale_x, gl_->Uniform4f(locations.tex_transform, 0.0f, 1.0f, tex_scale_x,
-tex_scale_y); -tex_scale_y);
GLint last_texture_unit = 0; GLint last_texture_unit = 0;
...@@ -1162,7 +1157,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, ...@@ -1162,7 +1157,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame,
// and the RenderPass contents texture, so we flip the tex coords from the // and the RenderPass contents texture, so we flip the tex coords from the
// RenderPass texture to find the mask texture coords. // RenderPass texture to find the mask texture coords.
gl_->Uniform2f(locations.mask_tex_coord_offset, mask_uv_rect.x(), gl_->Uniform2f(locations.mask_tex_coord_offset, mask_uv_rect.x(),
mask_uv_rect.bottom()); mask_uv_rect.height() / tex_scale_y + mask_uv_rect.y());
gl_->Uniform2f(locations.mask_tex_coord_scale, gl_->Uniform2f(locations.mask_tex_coord_scale,
mask_uv_rect.width() / tex_scale_x, mask_uv_rect.width() / tex_scale_x,
-mask_uv_rect.height() / tex_scale_y); -mask_uv_rect.height() / tex_scale_y);
......
...@@ -1733,6 +1733,95 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) { ...@@ -1733,6 +1733,95 @@ TYPED_TEST(RendererPixelTest, RenderPassAndMaskWithPartialQuad) {
ExactPixelComparator(true))); ExactPixelComparator(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, RenderPassAndMaskWithPartialQuad2) {
gfx::Rect viewport_rect(this->device_viewport_size_);
RenderPassId root_pass_id(1, 1);
scoped_ptr<RenderPass> root_pass =
CreateTestRootRenderPass(root_pass_id, viewport_rect);
SharedQuadState* root_pass_shared_state = CreateTestSharedQuadState(
gfx::Transform(), viewport_rect, root_pass.get());
RenderPassId child_pass_id(2, 2);
gfx::Transform transform_to_root;
scoped_ptr<RenderPass> child_pass =
CreateTestRenderPass(child_pass_id, viewport_rect, transform_to_root);
SharedQuadState* child_pass_shared_state = CreateTestSharedQuadState(
gfx::Transform(), viewport_rect, child_pass.get());
// The child render pass is just a green box.
static const SkColor kCSSGreen = 0xff008000;
SolidColorDrawQuad* green =
child_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
green->SetNew(child_pass_shared_state, viewport_rect, viewport_rect,
kCSSGreen, false);
// Make a mask.
gfx::Rect mask_rect = viewport_rect;
SkBitmap bitmap;
bitmap.allocPixels(
SkImageInfo::MakeN32Premul(mask_rect.width(), mask_rect.height()));
SkCanvas canvas(bitmap);
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);
}
ResourceId mask_resource_id = this->resource_provider_->CreateResource(
mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888);
{
SkAutoLockPixels lock(bitmap);
this->resource_provider_->CopyToResource(
mask_resource_id, reinterpret_cast<uint8_t*>(bitmap.getPixels()),
mask_rect.size());
}
// 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, 20, 200, 60);
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());
// Set up a mask on the RenderPassDrawQuad.
RenderPassDrawQuad* mask_quad =
root_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
mask_quad->SetNew(root_pass_shared_state, sub_rect, sub_rect, child_pass_id,
mask_resource_id,
gfx::Vector2dF(2.f / mask_rect.width(),
2.f / mask_rect.height()), // mask_uv_scale
gfx::Size(mask_rect.size()), // mask_texture_size
FilterOperations(), // foreground filters
gfx::Vector2dF(), // filters scale
FilterOperations()); // background filters
// White background behind the masked render pass.
SolidColorDrawQuad* white =
root_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
white->SetNew(root_pass_shared_state, viewport_rect, viewport_rect,
SK_ColorWHITE, false);
RenderPassList pass_list;
pass_list.push_back(std::move(child_pass));
pass_list.push_back(std::move(root_pass));
EXPECT_TRUE(this->RunPixelTest(
&pass_list, base::FilePath(FILE_PATH_LITERAL("mask_middle.png")),
ExactPixelComparator(true)));
}
template <typename RendererType> template <typename RendererType>
class RendererPixelTestWithBackgroundFilter class RendererPixelTestWithBackgroundFilter
: public RendererPixelTest<RendererType> { : public RendererPixelTest<RendererType> {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment