Index: cc/output/gl_renderer.cc |
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
index acd7bf2c2d86a5679bd4f9584e35f4d7061ab350..1de89d10fe7192592a0550a36e2bd87c3dca6582 100644 |
--- a/cc/output/gl_renderer.cc |
+++ b/cc/output/gl_renderer.cc |
@@ -56,6 +56,7 @@ |
#include "third_party/skia/include/gpu/gl/GrGLInterface.h" |
#include "ui/gfx/geometry/quad_f.h" |
#include "ui/gfx/geometry/rect_conversions.h" |
+#include "ui/gfx/skia_util.h" |
using gpu::gles2::GLES2Interface; |
@@ -601,7 +602,8 @@ void GLRenderer::DrawDebugBorderQuad(const DrawingFrame* frame, |
static skia::RefPtr<SkImage> ApplyImageFilter( |
scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, |
ResourceProvider* resource_provider, |
- const gfx::Rect& rect, |
+ const gfx::RectF& src_rect, |
+ const gfx::RectF& dst_rect, |
const gfx::Vector2dF& scale, |
SkImageFilter* filter, |
ScopedResource* source_texture_resource) { |
@@ -634,7 +636,7 @@ static skia::RefPtr<SkImage> ApplyImageFilter( |
// Create surface to draw into. |
SkImageInfo dst_info = |
- SkImageInfo::MakeN32Premul(srcImage->width(), srcImage->height()); |
+ SkImageInfo::MakeN32Premul(dst_rect.width(), dst_rect.height()); |
skia::RefPtr<SkSurface> surface = skia::AdoptRef(SkSurface::NewRenderTarget( |
use_gr_context->context(), SkSurface::kYes_Budgeted, dst_info, 0)); |
if (!surface) { |
@@ -647,17 +649,17 @@ static skia::RefPtr<SkImage> ApplyImageFilter( |
// 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. |
- int y_translate = source_texture_resource->size().height() - rect.height() - |
- rect.origin().y(); |
+ float y_offset = source_texture_resource->size().height() - src_rect.height(); |
SkMatrix localM; |
enne (OOO)
2016/01/19 23:21:19
localM and localIMF are not chrome style. Could y
Stephen White
2016/01/19 23:59:10
Done.
|
- localM.setTranslate(-rect.origin().x(), y_translate); |
- localM.preScale(scale.x(), scale.y()); |
+ localM.setScale(scale.x(), scale.y()); |
skia::RefPtr<SkImageFilter> localIMF = |
skia::AdoptRef(filter->newWithLocalMatrix(localM)); |
SkPaint paint; |
paint.setImageFilter(localIMF.get()); |
- surface->getCanvas()->drawImage(srcImage.get(), 0, 0, &paint); |
+ surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); |
+ surface->getCanvas()->drawImage(srcImage.get(), src_rect.x(), |
+ src_rect.y() - y_offset, &paint); |
skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); |
if (!image || !image->isTextureBacked()) { |
@@ -846,13 +848,14 @@ scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( |
skia::RefPtr<SkImage> GLRenderer::ApplyBackgroundFilters( |
DrawingFrame* frame, |
const RenderPassDrawQuad* quad, |
- ScopedResource* background_texture) { |
+ ScopedResource* background_texture, |
+ const gfx::RectF& rect) { |
DCHECK(ShouldApplyBackgroundFilters(quad)); |
skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
quad->background_filters, gfx::SizeF(background_texture->size())); |
skia::RefPtr<SkImage> background_with_filters = ApplyImageFilter( |
- ScopedUseGrContext::Create(this, frame), resource_provider_, quad->rect, |
+ ScopedUseGrContext::Create(this, frame), resource_provider_, rect, rect, |
quad->filters_scale, filter.get(), background_texture); |
return background_with_filters; |
} |
@@ -925,8 +928,8 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
if (ShouldApplyBackgroundFilters(quad) && background_texture) { |
// Apply the background filters to R, so that it is applied in the |
// pixels' coordinate space. |
- background_image = |
- ApplyBackgroundFilters(frame, quad, background_texture.get()); |
+ background_image = ApplyBackgroundFilters( |
+ frame, quad, background_texture.get(), gfx::RectF(background_rect)); |
if (background_image) |
background_image_id = background_image->getTextureHandle(true); |
DCHECK(background_image_id); |
@@ -963,6 +966,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
GLuint filter_image_id = 0; |
SkScalar color_matrix[20]; |
bool use_color_matrix = false; |
+ gfx::RectF rect = gfx::RectF(quad->rect); |
if (!quad->filters.IsEmpty()) { |
skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
quad->filters, gfx::SizeF(contents_texture->size())); |
@@ -980,9 +984,18 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
// in the compositor. |
use_color_matrix = true; |
} else { |
- filter_image = ApplyImageFilter( |
- ScopedUseGrContext::Create(this, frame), resource_provider_, |
- quad->rect, quad->filters_scale, filter.get(), contents_texture); |
+ gfx::RectF src_rect = rect; |
+ gfx::Vector2dF scale = quad->filters_scale; |
+ if (filter->canComputeFastBounds()) { |
enne (OOO)
2016/01/19 23:21:19
What if it can't? Does it just not expand at all?
Stephen White
2016/01/19 23:59:10
That's actually current behaviour (even though it'
|
+ SkRect result_rect; |
+ rect.Scale(1.0f / scale.x(), 1.0f / scale.y()); |
+ filter->computeFastBounds(gfx::RectFToSkRect(rect), &result_rect); |
+ rect = gfx::SkRectToRectF(result_rect); |
+ rect.Scale(scale.x(), scale.y()); |
+ } |
+ filter_image = ApplyImageFilter(ScopedUseGrContext::Create(this, frame), |
+ resource_provider_, src_rect, rect, |
+ scale, filter.get(), contents_texture); |
if (filter_image) { |
filter_image_id = filter_image->getTextureHandle(true); |
DCHECK(filter_image_id); |
@@ -1096,10 +1109,16 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
program->fragment_shader().FillLocations(&locations); |
gl_->Uniform1i(locations.sampler, 0); |
} |
- float tex_scale_x = |
- quad->rect.width() / static_cast<float>(contents_texture->size().width()); |
- float tex_scale_y = quad->rect.height() / |
- static_cast<float>(contents_texture->size().height()); |
+ float tex_scale_x, tex_scale_y; |
+ if (filter_image) { |
+ // Skia filters always return SkImages with snug textures. |
+ tex_scale_x = tex_scale_y = 1.0f; |
+ } else { |
+ tex_scale_x = quad->rect.width() / |
+ static_cast<float>(contents_texture->size().width()); |
+ tex_scale_y = quad->rect.height() / |
+ static_cast<float>(contents_texture->size().height()); |
+ } |
DCHECK_LE(tex_scale_x, 1.0f); |
DCHECK_LE(tex_scale_y, 1.0f); |
@@ -1197,7 +1216,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
SetShaderOpacity(quad->shared_quad_state->opacity, locations.alpha); |
SetShaderQuadF(surface_quad, locations.quad); |
DrawQuadGeometry(frame, quad->shared_quad_state->quad_to_target_transform, |
- gfx::RectF(quad->rect), locations.matrix); |
+ rect, locations.matrix); |
// Flush the compositor context before the filter bitmap goes out of |
// scope, so the draw gets processed before the filter texture gets deleted. |