Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2167)

Unified Diff: cc/output/gl_renderer.cc

Issue 1517693002: Accelerated filters should filter unpadded primitives. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Do background rect outsetting before window intersection Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/renderer_pixeltest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: cc/output/gl_renderer.cc
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
index acd7bf2c2d86a5679bd4f9584e35f4d7061ab350..b2502d9bcbc2086b0619b838c319f90fc17ad09a 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();
- SkMatrix localM;
- localM.setTranslate(-rect.origin().x(), y_translate);
- localM.preScale(scale.x(), scale.y());
- skia::RefPtr<SkImageFilter> localIMF =
- skia::AdoptRef(filter->newWithLocalMatrix(localM));
+ float y_offset = source_texture_resource->size().height() - src_rect.height();
+ SkMatrix local_matrix;
+ local_matrix.setScale(scale.x(), scale.y());
+ skia::RefPtr<SkImageFilter> filter_with_local_scale =
+ skia::AdoptRef(filter->newWithLocalMatrix(local_matrix));
SkPaint paint;
- paint.setImageFilter(localIMF.get());
- surface->getCanvas()->drawImage(srcImage.get(), 0, 0, &paint);
+ paint.setImageFilter(filter_with_local_scale.get());
+ 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()) {
@@ -822,6 +824,13 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad(
backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing);
}
+ if (!quad->filters.IsEmpty()) {
+ // If we have filters, grab an extra one-pixel border around the
+ // background, so texture edge clamping gives us a transparent border
+ // in case the filter expands the result.
+ backdrop_rect.Inset(-1, -1, -1, -1);
+ }
+
backdrop_rect.Intersect(MoveFromDrawToWindowSpace(
frame, frame->current_render_pass->output_rect));
return backdrop_rect;
@@ -846,13 +855,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 +935,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 +973,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 +991,28 @@ 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;
+ // Compute the destination rect for the filtered output.
+ // Note that we leave the dest rect equal to the src rect when
+ // a filter chain cannot compute its bounds. This is correct
+ // behaviour, but Skia is a little conservative at the moment.
+ // Once Skia makes the fast-bounds traversal crop-rect aware
+ // (http://skbug.com/4627), this won't be a problem
+ // for Chrome since Blink always sets a crop rect on the leaf nodes
+ // of the DAG, making it always computable.
+ // TODO(senorblanco): remove this comment when http://skbug.com/4627
enne (OOO) 2016/01/20 22:59:29 Thanks for this. :)
+ // is fixed.
+ if (filter->canComputeFastBounds()) {
+ 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 +1126,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 +1233,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.
« no previous file with comments | « cc/output/gl_renderer.h ('k') | cc/output/renderer_pixeltest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698