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

Side by Side Diff: cc/output/gl_renderer.cc

Issue 1959033002: cc: optimize Skia image filter application via SkImage::makeWithFilter(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Win pixeltest tweakage Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | cc/test/data/blur_filter_with_clip_gl.png » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/output/gl_renderer.h" 5 #include "cc/output/gl_renderer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 #include "gpu/command_buffer/client/context_support.h" 46 #include "gpu/command_buffer/client/context_support.h"
47 #include "gpu/command_buffer/client/gles2_interface.h" 47 #include "gpu/command_buffer/client/gles2_interface.h"
48 #include "gpu/command_buffer/common/gpu_memory_allocation.h" 48 #include "gpu/command_buffer/common/gpu_memory_allocation.h"
49 #include "skia/ext/texture_handle.h" 49 #include "skia/ext/texture_handle.h"
50 #include "third_party/skia/include/core/SkBitmap.h" 50 #include "third_party/skia/include/core/SkBitmap.h"
51 #include "third_party/skia/include/core/SkColor.h" 51 #include "third_party/skia/include/core/SkColor.h"
52 #include "third_party/skia/include/core/SkColorFilter.h" 52 #include "third_party/skia/include/core/SkColorFilter.h"
53 #include "third_party/skia/include/core/SkImage.h" 53 #include "third_party/skia/include/core/SkImage.h"
54 #include "third_party/skia/include/core/SkSurface.h" 54 #include "third_party/skia/include/core/SkSurface.h"
55 #include "third_party/skia/include/gpu/GrContext.h" 55 #include "third_party/skia/include/gpu/GrContext.h"
56 #include "third_party/skia/include/gpu/GrTexture.h"
57 #include "third_party/skia/include/gpu/GrTextureProvider.h"
58 #include "third_party/skia/include/gpu/gl/GrGLInterface.h" 56 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
59 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" 57 #include "third_party/skia/include/gpu/gl/GrGLTypes.h"
60 #include "ui/gfx/geometry/quad_f.h" 58 #include "ui/gfx/geometry/quad_f.h"
61 #include "ui/gfx/geometry/rect_conversions.h" 59 #include "ui/gfx/geometry/rect_conversions.h"
62 #include "ui/gfx/skia_util.h" 60 #include "ui/gfx/skia_util.h"
63 61
64 using gpu::gles2::GLES2Interface; 62 using gpu::gles2::GLES2Interface;
65 63
66 namespace cc { 64 namespace cc {
67 namespace { 65 namespace {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 case SkXfermode::kColor_Mode: 132 case SkXfermode::kColor_Mode:
135 return BLEND_MODE_COLOR; 133 return BLEND_MODE_COLOR;
136 case SkXfermode::kLuminosity_Mode: 134 case SkXfermode::kLuminosity_Mode:
137 return BLEND_MODE_LUMINOSITY; 135 return BLEND_MODE_LUMINOSITY;
138 default: 136 default:
139 NOTREACHED(); 137 NOTREACHED();
140 return BLEND_MODE_NONE; 138 return BLEND_MODE_NONE;
141 } 139 }
142 } 140 }
143 141
144 void RoundUpToPow2(gfx::RectF* rect) {
145 float w, h;
146 for (w = 1.f; w < rect->width(); w *= 2.f) {
147 }
148 for (h = 1.f; h < rect->height(); h *= 2.f) {
149 }
150 rect->set_width(w);
151 rect->set_height(h);
152 }
153
154 // Smallest unit that impact anti-aliasing output. We use this to 142 // Smallest unit that impact anti-aliasing output. We use this to
155 // determine when anti-aliasing is unnecessary. 143 // determine when anti-aliasing is unnecessary.
156 const float kAntiAliasingEpsilon = 1.0f / 1024.0f; 144 const float kAntiAliasingEpsilon = 1.0f / 1024.0f;
157 145
158 // Block or crash if the number of pending sync queries reach this high as 146 // Block or crash if the number of pending sync queries reach this high as
159 // something is seriously wrong on the service side if this happens. 147 // something is seriously wrong on the service side if this happens.
160 const size_t kMaxPendingSyncQueries = 16; 148 const size_t kMaxPendingSyncQueries = 16;
161 149
162 } // anonymous namespace 150 } // anonymous namespace
163 151
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 (SkColorGetG(color) * (1.0f / 255.0f)) * alpha, 580 (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
593 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, alpha); 581 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, alpha);
594 582
595 gl_->LineWidth(quad->width); 583 gl_->LineWidth(quad->width);
596 584
597 // The indices for the line are stored in the same array as the triangle 585 // The indices for the line are stored in the same array as the triangle
598 // indices. 586 // indices.
599 gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0); 587 gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0);
600 } 588 }
601 589
590 static sk_sp<SkImage> WrapTexture(
591 const ResourceProvider::ScopedReadLockGL& lock,
592 GrContext* context) {
593 // Wrap a given texture in a Ganesh platform texture.
594 GrBackendTextureDesc backend_texture_description;
595 GrGLTextureInfo texture_info;
596 texture_info.fTarget = lock.target();
597 texture_info.fID = lock.texture_id();
598 backend_texture_description.fWidth = lock.texture_size().width();
599 backend_texture_description.fHeight = lock.texture_size().height();
600 backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
601 backend_texture_description.fTextureHandle =
602 skia::GrGLTextureInfoToGrBackendObject(texture_info);
603 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
604
605 return SkImage::MakeFromTexture(context, backend_texture_description);
606 }
607
602 static sk_sp<SkImage> ApplyImageFilter( 608 static sk_sp<SkImage> ApplyImageFilter(
603 std::unique_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, 609 std::unique_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
604 ResourceProvider* resource_provider, 610 ResourceProvider* resource_provider,
605 const gfx::RectF& src_rect, 611 const gfx::RectF& src_rect,
606 const gfx::RectF& dst_rect, 612 const gfx::RectF& dst_rect,
607 const gfx::Vector2dF& scale, 613 const gfx::Vector2dF& scale,
608 sk_sp<SkImageFilter> filter, 614 sk_sp<SkImageFilter> filter,
609 ScopedResource* source_texture_resource) { 615 ScopedResource* source_texture_resource,
610 if (!filter) 616 SkIPoint* offset,
611 return nullptr; 617 SkIRect* subset) {
612 618 if (!filter || !use_gr_context)
613 if (!use_gr_context)
614 return nullptr; 619 return nullptr;
615 620
616 ResourceProvider::ScopedReadLockGL lock(resource_provider, 621 ResourceProvider::ScopedReadLockGL lock(resource_provider,
617 source_texture_resource->id()); 622 source_texture_resource->id());
618 623
619 // Wrap the source texture in a Ganesh platform texture. 624 sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context());
620 GrBackendTextureDesc backend_texture_description;
621 GrGLTextureInfo texture_info;
622 texture_info.fTarget = lock.target();
623 texture_info.fID = lock.texture_id();
624 backend_texture_description.fWidth = source_texture_resource->size().width();
625 backend_texture_description.fHeight =
626 source_texture_resource->size().height();
627 backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
628 backend_texture_description.fTextureHandle =
629 skia::GrGLTextureInfoToGrBackendObject(texture_info);
630 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
631
632 sk_sp<SkImage> src_image = SkImage::MakeFromTexture(
633 use_gr_context->context(), backend_texture_description);
634 if (!src_image) { 625 if (!src_image) {
635 TRACE_EVENT_INSTANT0("cc", 626 TRACE_EVENT_INSTANT0("cc",
636 "ApplyImageFilter wrap background texture failed", 627 "ApplyImageFilter wrap background texture failed",
637 TRACE_EVENT_SCOPE_THREAD); 628 TRACE_EVENT_SCOPE_THREAD);
638 return nullptr; 629 return nullptr;
639 } 630 }
640 631
641 // Create surface to draw into.
642 SkImageInfo dst_info =
643 SkImageInfo::MakeN32Premul(dst_rect.width(), dst_rect.height());
644 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
645 use_gr_context->context(), SkBudgeted::kYes, dst_info);
646 if (!surface) {
647 TRACE_EVENT_INSTANT0("cc", "ApplyImageFilter surface allocation failed",
648 TRACE_EVENT_SCOPE_THREAD);
649 return nullptr;
650 }
651
652 SkMatrix local_matrix; 632 SkMatrix local_matrix;
653 local_matrix.setScale(scale.x(), scale.y()); 633 local_matrix.setTranslate(-src_rect.x(), -src_rect.y());
634 local_matrix.postScale(scale.x(), scale.y());
654 635
655 SkPaint paint; 636 SkIRect clip_bounds = gfx::RectFToSkRect(dst_rect).roundOut();
656 paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix)); 637 clip_bounds.offset(-src_rect.x(), -src_rect.y());
657 surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); 638 filter = filter->makeWithLocalMatrix(local_matrix);
658 surface->getCanvas()->drawImage(src_image, src_rect.x(), src_rect.y(), 639 SkIRect in_subset = SkIRect::MakeWH(src_image->width(), src_image->height());
659 &paint); 640 sk_sp<SkImage> image = src_image->makeWithFilter(filter.get(), in_subset,
660 // Flush the drawing before source texture read lock goes out of scope. 641 clip_bounds, subset, offset);
661 // Skia API does not guarantee that when the SkImage goes out of scope, 642
662 // its externally referenced resources would force the rendering to be
663 // flushed.
664 surface->getCanvas()->flush();
665 sk_sp<SkImage> image = surface->makeImageSnapshot();
666 if (!image || !image->isTextureBacked()) { 643 if (!image || !image->isTextureBacked()) {
667 return nullptr; 644 return nullptr;
668 } 645 }
669 646
647 // Force a flush of the Skia pipeline before we switch back to the compositor
648 // context.
649 image->getTextureHandle(true);
670 CHECK(image->isTextureBacked()); 650 CHECK(image->isTextureBacked());
671 return image; 651 return image;
672 } 652 }
673 653
674 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { 654 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
675 return use_blend_equation_advanced_ || 655 return use_blend_equation_advanced_ ||
676 blend_mode == SkXfermode::kScreen_Mode || 656 blend_mode == SkXfermode::kScreen_Mode ||
677 blend_mode == SkXfermode::kSrcOver_Mode; 657 blend_mode == SkXfermode::kSrcOver_Mode;
678 } 658 }
679 659
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 } 832 }
853 return device_background_texture; 833 return device_background_texture;
854 } 834 }
855 835
856 sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters( 836 sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters(
857 DrawingFrame* frame, 837 DrawingFrame* frame,
858 const RenderPassDrawQuad* quad, 838 const RenderPassDrawQuad* quad,
859 ScopedResource* background_texture, 839 ScopedResource* background_texture,
860 const gfx::RectF& rect) { 840 const gfx::RectF& rect) {
861 DCHECK(ShouldApplyBackgroundFilters(quad)); 841 DCHECK(ShouldApplyBackgroundFilters(quad));
842 auto use_gr_context = ScopedUseGrContext::Create(this, frame);
862 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( 843 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
863 quad->background_filters, gfx::SizeF(background_texture->size())); 844 quad->background_filters, gfx::SizeF(background_texture->size()));
864 845
865 sk_sp<SkImage> background_with_filters = ApplyImageFilter( 846 // TODO(senorblanco): background filters should be moved to the
866 ScopedUseGrContext::Create(this, frame), resource_provider_, rect, rect, 847 // makeWithFilter fast-path, and go back to calling ApplyImageFilter().
867 quad->filters_scale, std::move(filter), background_texture); 848 // See http://crbug.com/613233.
868 return background_with_filters; 849 if (!filter || !use_gr_context)
850 return nullptr;
851
852 ResourceProvider::ScopedReadLockGL lock(resource_provider_,
853 background_texture->id());
854
855 sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context());
856 if (!src_image) {
857 TRACE_EVENT_INSTANT0(
858 "cc", "ApplyBackgroundFilters wrap background texture failed",
859 TRACE_EVENT_SCOPE_THREAD);
860 return nullptr;
861 }
862
863 // Create surface to draw into.
864 SkImageInfo dst_info =
865 SkImageInfo::MakeN32Premul(rect.width(), rect.height());
866 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
867 use_gr_context->context(), SkBudgeted::kYes, dst_info);
868 if (!surface) {
869 TRACE_EVENT_INSTANT0("cc",
870 "ApplyBackgroundFilters surface allocation failed",
871 TRACE_EVENT_SCOPE_THREAD);
872 return nullptr;
873 }
874
875 SkMatrix local_matrix;
876 local_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y());
877
878 SkPaint paint;
879 paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix));
880 surface->getCanvas()->translate(-rect.x(), -rect.y());
881 surface->getCanvas()->drawImage(src_image, rect.x(), rect.y(), &paint);
882 // Flush the drawing before source texture read lock goes out of scope.
883 // Skia API does not guarantee that when the SkImage goes out of scope,
884 // its externally referenced resources would force the rendering to be
885 // flushed.
886 surface->getCanvas()->flush();
887 sk_sp<SkImage> image = surface->makeImageSnapshot();
888 if (!image || !image->isTextureBacked()) {
889 return nullptr;
890 }
891
892 return image;
869 } 893 }
870 894
871 // Map device space quad to local space. Device_transform has no 3d 895 // Map device space quad to local space. Device_transform has no 3d
872 // component since it was flattened, so we don't need to project. We should 896 // component since it was flattened, so we don't need to project. We should
873 // have already checked that the transform was uninvertible before this call. 897 // have already checked that the transform was uninvertible before this call.
874 gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform, 898 gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform,
875 const gfx::QuadF& device_quad) { 899 const gfx::QuadF& device_quad) {
876 gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization); 900 gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
877 DCHECK(device_transform.IsInvertible()); 901 DCHECK(device_transform.IsInvertible());
878 bool did_invert = device_transform.GetInverse(&inverse_device_transform); 902 bool did_invert = device_transform.GetInverse(&inverse_device_transform);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 SetBlendEnabled( 1014 SetBlendEnabled(
991 !use_shaders_for_blending && 1015 !use_shaders_for_blending &&
992 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode))); 1016 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
993 1017
994 // TODO(senorblanco): Cache this value so that we don't have to do it for both 1018 // TODO(senorblanco): Cache this value so that we don't have to do it for both
995 // the surface and its replica. Apply filters to the contents texture. 1019 // the surface and its replica. Apply filters to the contents texture.
996 sk_sp<SkImage> filter_image; 1020 sk_sp<SkImage> filter_image;
997 GLuint filter_image_id = 0; 1021 GLuint filter_image_id = 0;
998 SkScalar color_matrix[20]; 1022 SkScalar color_matrix[20];
999 bool use_color_matrix = false; 1023 bool use_color_matrix = false;
1000 gfx::RectF rect = gfx::RectF(quad->rect); 1024 gfx::Size texture_size = contents_texture->size();
1025 bool flip_texture = true;
1026 gfx::Point src_offset;
1001 if (!quad->filters.IsEmpty()) { 1027 if (!quad->filters.IsEmpty()) {
1002 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( 1028 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
1003 quad->filters, gfx::SizeF(contents_texture->size())); 1029 quad->filters, gfx::SizeF(contents_texture->size()));
1004 if (filter) { 1030 if (filter) {
1005 SkColorFilter* colorfilter_rawptr = NULL; 1031 SkColorFilter* colorfilter_rawptr = NULL;
1006 filter->asColorFilter(&colorfilter_rawptr); 1032 filter->asColorFilter(&colorfilter_rawptr);
1007 sk_sp<SkColorFilter> cf(colorfilter_rawptr); 1033 sk_sp<SkColorFilter> cf(colorfilter_rawptr);
1008 1034
1009 if (cf && cf->asColorMatrix(color_matrix)) { 1035 if (cf && cf->asColorMatrix(color_matrix)) {
1010 // We have a color matrix at the root of the filter DAG; apply it 1036 // We have a color matrix at the root of the filter DAG; apply it
(...skipping 10 matching lines...) Expand all
1021 gfx::Transform transform = 1047 gfx::Transform transform =
1022 quad->shared_quad_state->quad_to_target_transform; 1048 quad->shared_quad_state->quad_to_target_transform;
1023 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); 1049 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect));
1024 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); 1050 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad);
1025 dst_rect.Intersect(local_clip.BoundingBox()); 1051 dst_rect.Intersect(local_clip.BoundingBox());
1026 // If we've been fully clipped out (by crop rect or clipping), there's 1052 // If we've been fully clipped out (by crop rect or clipping), there's
1027 // nothing to draw. 1053 // nothing to draw.
1028 if (dst_rect.IsEmpty()) { 1054 if (dst_rect.IsEmpty()) {
1029 return; 1055 return;
1030 } 1056 }
1031 // Expand dst_rect size to the nearest power of 2, in order to get 1057 SkIPoint offset;
1032 // more cache hits in Skia's texture cache. 1058 SkIRect subset;
1033 RoundUpToPow2(&dst_rect); 1059 gfx::RectF src_rect(quad->rect);
1034 filter_image = ApplyImageFilter( 1060 filter_image = ApplyImageFilter(ScopedUseGrContext::Create(this, frame),
1035 ScopedUseGrContext::Create(this, frame), resource_provider_, rect, 1061 resource_provider_, src_rect, dst_rect,
1036 dst_rect, quad->filters_scale, std::move(filter), contents_texture); 1062 quad->filters_scale, std::move(filter),
1063 contents_texture, &offset, &subset);
1037 if (!filter_image) { 1064 if (!filter_image) {
1038 return; 1065 return;
1039 } 1066 }
1040 filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( 1067 filter_image_id = skia::GrBackendObjectToGrGLTextureInfo(
1041 filter_image->getTextureHandle(true)) 1068 filter_image->getTextureHandle(true))
1042 ->fID; 1069 ->fID;
1070 texture_size.set_width(filter_image->width());
1071 texture_size.set_height(filter_image->height());
1043 DCHECK(filter_image_id); 1072 DCHECK(filter_image_id);
1073 dst_rect =
1074 gfx::RectF(src_rect.x() + offset.fX, src_rect.y() + offset.fY,
1075 subset.width(), subset.height());
1076 src_offset.SetPoint(subset.x(), subset.y());
1077 flip_texture =
1078 filter_image->getTexture()->origin() == kBottomLeft_GrSurfaceOrigin;
1044 } 1079 }
1045 } 1080 }
1046 } 1081 }
1047 1082
1048 std::unique_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; 1083 std::unique_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
1049 unsigned mask_texture_id = 0; 1084 unsigned mask_texture_id = 0;
1050 SamplerType mask_sampler = SAMPLER_TYPE_NA; 1085 SamplerType mask_sampler = SAMPLER_TYPE_NA;
1051 if (quad->mask_resource_id()) { 1086 if (quad->mask_resource_id()) {
1052 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL( 1087 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL(
1053 resource_provider_, quad->mask_resource_id(), GL_TEXTURE1, GL_LINEAR)); 1088 resource_provider_, quad->mask_resource_id(), GL_TEXTURE1, GL_LINEAR));
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1145 program->fragment_shader().FillLocations(&locations); 1180 program->fragment_shader().FillLocations(&locations);
1146 gl_->Uniform1i(locations.sampler, 0); 1181 gl_->Uniform1i(locations.sampler, 0);
1147 } else { 1182 } else {
1148 const RenderPassProgram* program = 1183 const RenderPassProgram* program =
1149 GetRenderPassProgram(tex_coord_precision, shader_blend_mode); 1184 GetRenderPassProgram(tex_coord_precision, shader_blend_mode);
1150 SetUseProgram(program->program()); 1185 SetUseProgram(program->program());
1151 program->vertex_shader().FillLocations(&locations); 1186 program->vertex_shader().FillLocations(&locations);
1152 program->fragment_shader().FillLocations(&locations); 1187 program->fragment_shader().FillLocations(&locations);
1153 gl_->Uniform1i(locations.sampler, 0); 1188 gl_->Uniform1i(locations.sampler, 0);
1154 } 1189 }
1155 float tex_scale_x, tex_scale_y; 1190 gfx::RectF tex_rect(src_offset.x(), src_offset.y(), dst_rect.width(),
1156 if (filter_image) { 1191 dst_rect.height());
1157 // Skia filters always return SkImages with snug textures. 1192 tex_rect.Scale(1.0f / texture_size.width(), 1.0f / texture_size.height());
1158 tex_scale_x = tex_scale_y = 1.0f;
1159 } else {
1160 tex_scale_x = quad->rect.width() /
1161 static_cast<float>(contents_texture->size().width());
1162 tex_scale_y = quad->rect.height() /
1163 static_cast<float>(contents_texture->size().height());
1164 }
1165 DCHECK_LE(tex_scale_x, 1.0f);
1166 DCHECK_LE(tex_scale_y, 1.0f);
1167 1193
1168 DCHECK(locations.tex_transform != -1 || IsContextLost()); 1194 DCHECK(locations.tex_transform != -1 || IsContextLost());
1169 // Flip the content vertically in the shader, as the RenderPass input 1195 if (flip_texture) {
1170 // texture is already oriented the same way as the framebuffer, but the 1196 // Flip the content vertically in the shader, as the RenderPass input
1171 // projection transform does a flip. 1197 // texture is already oriented the same way as the framebuffer, but the
1172 gl_->Uniform4f(locations.tex_transform, 0.0f, 1.0f, tex_scale_x, 1198 // projection transform does a flip.
1173 -tex_scale_y); 1199 gl_->Uniform4f(locations.tex_transform, tex_rect.x(), 1.0f - tex_rect.y(),
1200 tex_rect.width(), -tex_rect.height());
1201 } else {
1202 gl_->Uniform4f(locations.tex_transform, tex_rect.x(), tex_rect.y(),
1203 tex_rect.width(), tex_rect.height());
1204 }
1174 1205
1175 GLint last_texture_unit = 0; 1206 GLint last_texture_unit = 0;
1176 if (locations.mask_sampler != -1) { 1207 if (locations.mask_sampler != -1) {
1177 DCHECK_NE(locations.mask_tex_coord_scale, 1); 1208 DCHECK_NE(locations.mask_tex_coord_scale, 1);
1178 DCHECK_NE(locations.mask_tex_coord_offset, 1); 1209 DCHECK_NE(locations.mask_tex_coord_offset, 1);
1179 gl_->Uniform1i(locations.mask_sampler, 1); 1210 gl_->Uniform1i(locations.mask_sampler, 1);
1180 1211
1181 gfx::RectF mask_uv_rect = quad->MaskUVRect(); 1212 gfx::RectF mask_uv_rect = quad->MaskUVRect();
1182 if (mask_sampler != SAMPLER_TYPE_2D) { 1213 if (mask_sampler != SAMPLER_TYPE_2D) {
1183 mask_uv_rect.Scale(quad->mask_texture_size.width(), 1214 mask_uv_rect.Scale(quad->mask_texture_size.width(),
1184 quad->mask_texture_size.height()); 1215 quad->mask_texture_size.height());
1185 } 1216 }
1186 1217
1187 // Mask textures are oriented vertically flipped relative to the framebuffer 1218 // Mask textures are oriented vertically flipped relative to the framebuffer
1188 // and the RenderPass contents texture, so we flip the tex coords from the 1219 // and the RenderPass contents texture, so we flip the tex coords from the
1189 // RenderPass texture to find the mask texture coords. 1220 // RenderPass texture to find the mask texture coords.
1190 gl_->Uniform2f(locations.mask_tex_coord_offset, mask_uv_rect.x(), 1221 gl_->Uniform2f(
1191 mask_uv_rect.height() / tex_scale_y + mask_uv_rect.y()); 1222 locations.mask_tex_coord_offset, mask_uv_rect.x(),
1223 mask_uv_rect.height() / tex_rect.height() + mask_uv_rect.y());
1192 gl_->Uniform2f(locations.mask_tex_coord_scale, 1224 gl_->Uniform2f(locations.mask_tex_coord_scale,
1193 mask_uv_rect.width() / tex_scale_x, 1225 mask_uv_rect.width() / tex_rect.width(),
1194 -mask_uv_rect.height() / tex_scale_y); 1226 -mask_uv_rect.height() / tex_rect.height());
1195 1227
1196 last_texture_unit = 1; 1228 last_texture_unit = 1;
1197 } 1229 }
1198 1230
1199 if (locations.edge != -1) 1231 if (locations.edge != -1)
1200 gl_->Uniform3fv(locations.edge, 8, edge); 1232 gl_->Uniform3fv(locations.edge, 8, edge);
1201 1233
1202 if (locations.viewport != -1) { 1234 if (locations.viewport != -1) {
1203 float viewport[4] = { 1235 float viewport[4] = {
1204 static_cast<float>(current_window_space_viewport_.x()), 1236 static_cast<float>(current_window_space_viewport_.x()),
(...skipping 2407 matching lines...) Expand 10 before | Expand all | Expand 10 after
3612 texture_id = pending_overlay_resources_.back()->GetTextureId(); 3644 texture_id = pending_overlay_resources_.back()->GetTextureId();
3613 } 3645 }
3614 3646
3615 context_support_->ScheduleOverlayPlane( 3647 context_support_->ScheduleOverlayPlane(
3616 overlay.plane_z_order, overlay.transform, texture_id, 3648 overlay.plane_z_order, overlay.transform, texture_id,
3617 ToNearestRect(overlay.display_rect), overlay.uv_rect); 3649 ToNearestRect(overlay.display_rect), overlay.uv_rect);
3618 } 3650 }
3619 } 3651 }
3620 3652
3621 } // namespace cc 3653 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/test/data/blur_filter_with_clip_gl.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698