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

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: Refactor wrapping of background texture 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/rotated_drop_shadow_filter_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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 (SkColorGetG(color) * (1.0f / 255.0f)) * alpha, 581 (SkColorGetG(color) * (1.0f / 255.0f)) * alpha,
594 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, alpha); 582 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, alpha);
595 583
596 gl_->LineWidth(quad->width); 584 gl_->LineWidth(quad->width);
597 585
598 // The indices for the line are stored in the same array as the triangle 586 // The indices for the line are stored in the same array as the triangle
599 // indices. 587 // indices.
600 gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0); 588 gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0);
601 } 589 }
602 590
591 static sk_sp<SkImage> WrapTexture(
592 const ResourceProvider::ScopedReadLockGL& lock,
593 GrContext* context) {
594 // Wrap a given texture in a Ganesh platform texture.
595 GrBackendTextureDesc backend_texture_description;
596 GrGLTextureInfo texture_info;
597 texture_info.fTarget = lock.target();
598 texture_info.fID = lock.texture_id();
599 backend_texture_description.fWidth = lock.texture_size().width();
600 backend_texture_description.fHeight = lock.texture_size().height();
601 backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
602 backend_texture_description.fTextureHandle =
603 skia::GrGLTextureInfoToGrBackendObject(texture_info);
604 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
605
606 return SkImage::MakeFromTexture(context, backend_texture_description);
607 }
608
603 static sk_sp<SkImage> ApplyImageFilter( 609 static sk_sp<SkImage> ApplyImageFilter(
604 std::unique_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, 610 std::unique_ptr<GLRenderer::ScopedUseGrContext> use_gr_context,
605 ResourceProvider* resource_provider, 611 ResourceProvider* resource_provider,
606 const gfx::RectF& src_rect, 612 const gfx::RectF& src_rect,
607 const gfx::RectF& dst_rect, 613 const gfx::RectF& dst_rect,
608 const gfx::Vector2dF& scale, 614 const gfx::Vector2dF& scale,
609 sk_sp<SkImageFilter> filter, 615 sk_sp<SkImageFilter> filter,
610 ScopedResource* source_texture_resource) { 616 ScopedResource* source_texture_resource,
611 if (!filter) 617 SkIPoint* offset,
612 return nullptr; 618 SkIRect* subset,
613 619 bool* flip_texture) {
614 if (!use_gr_context) 620 if (!filter || !use_gr_context)
615 return nullptr; 621 return nullptr;
616 622
617 ResourceProvider::ScopedReadLockGL lock(resource_provider, 623 ResourceProvider::ScopedReadLockGL lock(resource_provider,
618 source_texture_resource->id()); 624 source_texture_resource->id());
619 625
620 // Wrap the source texture in a Ganesh platform texture. 626 sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context());
621 GrBackendTextureDesc backend_texture_description;
622 GrGLTextureInfo texture_info;
623 texture_info.fTarget = lock.target();
624 texture_info.fID = lock.texture_id();
625 backend_texture_description.fWidth = source_texture_resource->size().width();
626 backend_texture_description.fHeight =
627 source_texture_resource->size().height();
628 backend_texture_description.fConfig = kSkia8888_GrPixelConfig;
629 backend_texture_description.fTextureHandle =
630 skia::GrGLTextureInfoToGrBackendObject(texture_info);
631 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin;
632
633 sk_sp<SkImage> src_image = SkImage::MakeFromTexture(
634 use_gr_context->context(), backend_texture_description);
635 if (!src_image) { 627 if (!src_image) {
636 TRACE_EVENT_INSTANT0("cc", 628 TRACE_EVENT_INSTANT0("cc",
637 "ApplyImageFilter wrap background texture failed", 629 "ApplyImageFilter wrap background texture failed",
638 TRACE_EVENT_SCOPE_THREAD); 630 TRACE_EVENT_SCOPE_THREAD);
639 return nullptr; 631 return nullptr;
640 } 632 }
641 633
642 // Create surface to draw into.
643 SkImageInfo dst_info =
644 SkImageInfo::MakeN32Premul(dst_rect.width(), dst_rect.height());
645 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
646 use_gr_context->context(), SkBudgeted::kYes, dst_info);
647 if (!surface) {
648 TRACE_EVENT_INSTANT0("cc", "ApplyImageFilter surface allocation failed",
649 TRACE_EVENT_SCOPE_THREAD);
650 return nullptr;
651 }
652
653 SkMatrix local_matrix; 634 SkMatrix local_matrix;
654 local_matrix.setScale(scale.x(), scale.y()); 635 local_matrix.setTranslate(-src_rect.x(), -src_rect.y());
636 local_matrix.postScale(scale.x(), scale.y());
655 637
656 SkPaint paint; 638 SkIRect clip_bounds = gfx::RectFToSkRect(dst_rect).roundOut();
657 paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix)); 639 clip_bounds.offset(-src_rect.x(), -src_rect.y());
658 surface->getCanvas()->translate(-dst_rect.x(), -dst_rect.y()); 640 filter = filter->makeWithLocalMatrix(local_matrix);
659 surface->getCanvas()->drawImage(src_image, src_rect.x(), src_rect.y(), 641 SkIRect in_subset = SkIRect::MakeWH(src_image->width(), src_image->height());
660 &paint); 642 sk_sp<SkImage> image = src_image->makeWithFilter(filter.get(), in_subset,
661 // Flush the drawing before source texture read lock goes out of scope. 643 clip_bounds, subset, offset);
662 // Skia API does not guarantee that when the SkImage goes out of scope, 644
663 // its externally referenced resources would force the rendering to be
664 // flushed.
665 surface->getCanvas()->flush();
666 sk_sp<SkImage> image = surface->makeImageSnapshot();
667 if (!image || !image->isTextureBacked()) { 645 if (!image || !image->isTextureBacked()) {
668 return nullptr; 646 return nullptr;
669 } 647 }
670 648
649 // Force a flush of the Skia pipeline before we switch back to the compositor
650 // context.
651 image->getTextureHandle(true);
671 CHECK(image->isTextureBacked()); 652 CHECK(image->isTextureBacked());
653 *flip_texture = image->getTexture()->origin() == kBottomLeft_GrSurfaceOrigin;
enne (OOO) 2016/05/20 00:53:45 Is this ever different? Also, it seems like if you
Stephen White 2016/05/20 03:31:39 Yep: with SVG filters, you can have an feImage whi
672 return image; 654 return image;
673 } 655 }
674 656
675 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { 657 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
676 return use_blend_equation_advanced_ || 658 return use_blend_equation_advanced_ ||
677 blend_mode == SkXfermode::kScreen_Mode || 659 blend_mode == SkXfermode::kScreen_Mode ||
678 blend_mode == SkXfermode::kSrcOver_Mode; 660 blend_mode == SkXfermode::kSrcOver_Mode;
679 } 661 }
680 662
681 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { 663 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 } 835 }
854 return device_background_texture; 836 return device_background_texture;
855 } 837 }
856 838
857 sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters( 839 sk_sp<SkImage> GLRenderer::ApplyBackgroundFilters(
858 DrawingFrame* frame, 840 DrawingFrame* frame,
859 const RenderPassDrawQuad* quad, 841 const RenderPassDrawQuad* quad,
860 ScopedResource* background_texture, 842 ScopedResource* background_texture,
861 const gfx::RectF& rect) { 843 const gfx::RectF& rect) {
862 DCHECK(ShouldApplyBackgroundFilters(quad)); 844 DCHECK(ShouldApplyBackgroundFilters(quad));
845 auto use_gr_context = ScopedUseGrContext::Create(this, frame);
863 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( 846 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
864 quad->background_filters, gfx::SizeF(background_texture->size())); 847 quad->background_filters, gfx::SizeF(background_texture->size()));
865 848
866 sk_sp<SkImage> background_with_filters = ApplyImageFilter( 849 // TODO(senorblanco): background filters should be moved to the
867 ScopedUseGrContext::Create(this, frame), resource_provider_, rect, rect, 850 // makeWithFilter fast-path, and go back to calling ApplyImageFilter().
868 quad->filters_scale, std::move(filter), background_texture); 851 // See http://crbug.com/613233.
869 return background_with_filters; 852 if (!filter || !use_gr_context)
853 return nullptr;
854
855 ResourceProvider::ScopedReadLockGL lock(resource_provider_,
856 background_texture->id());
857
858 sk_sp<SkImage> src_image = WrapTexture(lock, use_gr_context->context());
859 if (!src_image) {
860 TRACE_EVENT_INSTANT0(
861 "cc", "ApplyBackgroundFilters wrap background texture failed",
862 TRACE_EVENT_SCOPE_THREAD);
863 return nullptr;
864 }
865
866 // Create surface to draw into.
867 SkImageInfo dst_info =
868 SkImageInfo::MakeN32Premul(rect.width(), rect.height());
869 sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(
870 use_gr_context->context(), SkBudgeted::kYes, dst_info);
871 if (!surface) {
872 TRACE_EVENT_INSTANT0("cc",
873 "ApplyBackgroundFilters surface allocation failed",
874 TRACE_EVENT_SCOPE_THREAD);
875 return nullptr;
876 }
877
878 SkMatrix local_matrix;
879 local_matrix.setScale(quad->filters_scale.x(), quad->filters_scale.y());
880
881 SkPaint paint;
882 paint.setImageFilter(filter->makeWithLocalMatrix(local_matrix));
883 surface->getCanvas()->translate(-rect.x(), -rect.y());
884 surface->getCanvas()->drawImage(src_image, rect.x(), rect.y(), &paint);
885 // Flush the drawing before source texture read lock goes out of scope.
886 // Skia API does not guarantee that when the SkImage goes out of scope,
887 // its externally referenced resources would force the rendering to be
888 // flushed.
889 surface->getCanvas()->flush();
890 sk_sp<SkImage> image = surface->makeImageSnapshot();
891 if (!image || !image->isTextureBacked()) {
892 return nullptr;
893 }
894
895 return image;
870 } 896 }
871 897
872 // Map device space quad to local space. Device_transform has no 3d 898 // Map device space quad to local space. Device_transform has no 3d
873 // component since it was flattened, so we don't need to project. We should 899 // component since it was flattened, so we don't need to project. We should
874 // have already checked that the transform was uninvertible before this call. 900 // have already checked that the transform was uninvertible before this call.
875 gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform, 901 gfx::QuadF MapQuadToLocalSpace(const gfx::Transform& device_transform,
876 const gfx::QuadF& device_quad) { 902 const gfx::QuadF& device_quad) {
877 gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization); 903 gfx::Transform inverse_device_transform(gfx::Transform::kSkipInitialization);
878 DCHECK(device_transform.IsInvertible()); 904 DCHECK(device_transform.IsInvertible());
879 bool did_invert = device_transform.GetInverse(&inverse_device_transform); 905 bool did_invert = device_transform.GetInverse(&inverse_device_transform);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 SetBlendEnabled( 1017 SetBlendEnabled(
992 !use_shaders_for_blending && 1018 !use_shaders_for_blending &&
993 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode))); 1019 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode)));
994 1020
995 // TODO(senorblanco): Cache this value so that we don't have to do it for both 1021 // TODO(senorblanco): Cache this value so that we don't have to do it for both
996 // the surface and its replica. Apply filters to the contents texture. 1022 // the surface and its replica. Apply filters to the contents texture.
997 sk_sp<SkImage> filter_image; 1023 sk_sp<SkImage> filter_image;
998 GLuint filter_image_id = 0; 1024 GLuint filter_image_id = 0;
999 SkScalar color_matrix[20]; 1025 SkScalar color_matrix[20];
1000 bool use_color_matrix = false; 1026 bool use_color_matrix = false;
1001 gfx::RectF rect = gfx::RectF(quad->rect); 1027 gfx::Size texture_size = contents_texture->size();
1028 bool flip_texture = true;
1029 gfx::Point src_offset;
1002 if (!quad->filters.IsEmpty()) { 1030 if (!quad->filters.IsEmpty()) {
1003 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( 1031 sk_sp<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter(
1004 quad->filters, gfx::SizeF(contents_texture->size())); 1032 quad->filters, gfx::SizeF(contents_texture->size()));
1005 if (filter) { 1033 if (filter) {
1006 SkColorFilter* colorfilter_rawptr = NULL; 1034 SkColorFilter* colorfilter_rawptr = NULL;
1007 filter->asColorFilter(&colorfilter_rawptr); 1035 filter->asColorFilter(&colorfilter_rawptr);
1008 sk_sp<SkColorFilter> cf(colorfilter_rawptr); 1036 sk_sp<SkColorFilter> cf(colorfilter_rawptr);
1009 1037
1010 if (cf && cf->asColorMatrix(color_matrix)) { 1038 if (cf && cf->asColorMatrix(color_matrix)) {
1011 // We have a color matrix at the root of the filter DAG; apply it 1039 // We have a color matrix at the root of the filter DAG; apply it
(...skipping 10 matching lines...) Expand all
1022 gfx::Transform transform = 1050 gfx::Transform transform =
1023 quad->shared_quad_state->quad_to_target_transform; 1051 quad->shared_quad_state->quad_to_target_transform;
1024 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect)); 1052 gfx::QuadF clip_quad = gfx::QuadF(gfx::RectF(clip_rect));
1025 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad); 1053 gfx::QuadF local_clip = MapQuadToLocalSpace(transform, clip_quad);
1026 dst_rect.Intersect(local_clip.BoundingBox()); 1054 dst_rect.Intersect(local_clip.BoundingBox());
1027 // If we've been fully clipped out (by crop rect or clipping), there's 1055 // If we've been fully clipped out (by crop rect or clipping), there's
1028 // nothing to draw. 1056 // nothing to draw.
1029 if (dst_rect.IsEmpty()) { 1057 if (dst_rect.IsEmpty()) {
1030 return; 1058 return;
1031 } 1059 }
1032 // Expand dst_rect size to the nearest power of 2, in order to get 1060 SkIPoint offset;
1033 // more cache hits in Skia's texture cache. 1061 SkIRect subset;
1034 RoundUpToPow2(&dst_rect); 1062 gfx::RectF src_rect(quad->rect);
1035 filter_image = ApplyImageFilter( 1063 filter_image = ApplyImageFilter(
1036 ScopedUseGrContext::Create(this, frame), resource_provider_, rect, 1064 ScopedUseGrContext::Create(this, frame), resource_provider_,
1037 dst_rect, quad->filters_scale, std::move(filter), contents_texture); 1065 src_rect, dst_rect, quad->filters_scale, std::move(filter),
1066 contents_texture, &offset, &subset, &flip_texture);
1038 if (!filter_image) { 1067 if (!filter_image) {
1039 return; 1068 return;
1040 } 1069 }
1041 filter_image_id = skia::GrBackendObjectToGrGLTextureInfo( 1070 filter_image_id = skia::GrBackendObjectToGrGLTextureInfo(
1042 filter_image->getTextureHandle(true)) 1071 filter_image->getTextureHandle(true))
1043 ->fID; 1072 ->fID;
1073 texture_size.set_width(filter_image->width());
1074 texture_size.set_height(filter_image->height());
1044 DCHECK(filter_image_id); 1075 DCHECK(filter_image_id);
1076 dst_rect =
1077 gfx::RectF(src_rect.x() + offset.fX, src_rect.y() + offset.fY,
1078 subset.width(), subset.height());
1079 src_offset.SetPoint(subset.x(), subset.y());
1045 } 1080 }
1046 } 1081 }
1047 } 1082 }
1048 1083
1049 std::unique_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; 1084 std::unique_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock;
1050 unsigned mask_texture_id = 0; 1085 unsigned mask_texture_id = 0;
1051 SamplerType mask_sampler = SAMPLER_TYPE_NA; 1086 SamplerType mask_sampler = SAMPLER_TYPE_NA;
1052 if (quad->mask_resource_id()) { 1087 if (quad->mask_resource_id()) {
1053 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL( 1088 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL(
1054 resource_provider_, quad->mask_resource_id(), GL_TEXTURE1, GL_LINEAR)); 1089 resource_provider_, quad->mask_resource_id(), GL_TEXTURE1, GL_LINEAR));
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 program->fragment_shader().FillLocations(&locations); 1181 program->fragment_shader().FillLocations(&locations);
1147 gl_->Uniform1i(locations.sampler, 0); 1182 gl_->Uniform1i(locations.sampler, 0);
1148 } else { 1183 } else {
1149 const RenderPassProgram* program = 1184 const RenderPassProgram* program =
1150 GetRenderPassProgram(tex_coord_precision, shader_blend_mode); 1185 GetRenderPassProgram(tex_coord_precision, shader_blend_mode);
1151 SetUseProgram(program->program()); 1186 SetUseProgram(program->program());
1152 program->vertex_shader().FillLocations(&locations); 1187 program->vertex_shader().FillLocations(&locations);
1153 program->fragment_shader().FillLocations(&locations); 1188 program->fragment_shader().FillLocations(&locations);
1154 gl_->Uniform1i(locations.sampler, 0); 1189 gl_->Uniform1i(locations.sampler, 0);
1155 } 1190 }
1156 float tex_scale_x, tex_scale_y; 1191 gfx::RectF tex_rect(src_offset.x(), src_offset.y(), dst_rect.width(),
1157 if (filter_image) { 1192 dst_rect.height());
1158 // Skia filters always return SkImages with snug textures. 1193 tex_rect.Scale(1.0f / texture_size.width(), 1.0f / texture_size.height());
1159 tex_scale_x = tex_scale_y = 1.0f;
1160 } else {
1161 tex_scale_x = quad->rect.width() /
1162 static_cast<float>(contents_texture->size().width());
1163 tex_scale_y = quad->rect.height() /
1164 static_cast<float>(contents_texture->size().height());
1165 }
1166 DCHECK_LE(tex_scale_x, 1.0f);
1167 DCHECK_LE(tex_scale_y, 1.0f);
1168 1194
1169 DCHECK(locations.tex_transform != -1 || IsContextLost()); 1195 DCHECK(locations.tex_transform != -1 || IsContextLost());
1170 // Flip the content vertically in the shader, as the RenderPass input 1196 if (flip_texture) {
1171 // texture is already oriented the same way as the framebuffer, but the 1197 // Flip the content vertically in the shader, as the RenderPass input
1172 // projection transform does a flip. 1198 // texture is already oriented the same way as the framebuffer, but the
1173 gl_->Uniform4f(locations.tex_transform, 0.0f, 1.0f, tex_scale_x, 1199 // projection transform does a flip.
1174 -tex_scale_y); 1200 gl_->Uniform4f(locations.tex_transform, tex_rect.x(), 1.0f - tex_rect.y(),
1201 tex_rect.width(), -tex_rect.height());
1202 } else {
1203 gl_->Uniform4f(locations.tex_transform, tex_rect.x(), tex_rect.y(),
1204 tex_rect.width(), tex_rect.height());
1205 }
1175 1206
1176 GLint last_texture_unit = 0; 1207 GLint last_texture_unit = 0;
1177 if (locations.mask_sampler != -1) { 1208 if (locations.mask_sampler != -1) {
1178 DCHECK_NE(locations.mask_tex_coord_scale, 1); 1209 DCHECK_NE(locations.mask_tex_coord_scale, 1);
1179 DCHECK_NE(locations.mask_tex_coord_offset, 1); 1210 DCHECK_NE(locations.mask_tex_coord_offset, 1);
1180 gl_->Uniform1i(locations.mask_sampler, 1); 1211 gl_->Uniform1i(locations.mask_sampler, 1);
1181 1212
1182 gfx::RectF mask_uv_rect = quad->MaskUVRect(); 1213 gfx::RectF mask_uv_rect = quad->MaskUVRect();
1183 if (mask_sampler != SAMPLER_TYPE_2D) { 1214 if (mask_sampler != SAMPLER_TYPE_2D) {
1184 mask_uv_rect.Scale(quad->mask_texture_size.width(), 1215 mask_uv_rect.Scale(quad->mask_texture_size.width(),
1185 quad->mask_texture_size.height()); 1216 quad->mask_texture_size.height());
1186 } 1217 }
1187 1218
1188 // Mask textures are oriented vertically flipped relative to the framebuffer 1219 // Mask textures are oriented vertically flipped relative to the framebuffer
1189 // and the RenderPass contents texture, so we flip the tex coords from the 1220 // and the RenderPass contents texture, so we flip the tex coords from the
1190 // RenderPass texture to find the mask texture coords. 1221 // RenderPass texture to find the mask texture coords.
1191 gl_->Uniform2f(locations.mask_tex_coord_offset, mask_uv_rect.x(), 1222 gl_->Uniform2f(
1192 mask_uv_rect.height() / tex_scale_y + mask_uv_rect.y()); 1223 locations.mask_tex_coord_offset, mask_uv_rect.x(),
1224 mask_uv_rect.height() / tex_rect.height() + mask_uv_rect.y());
1193 gl_->Uniform2f(locations.mask_tex_coord_scale, 1225 gl_->Uniform2f(locations.mask_tex_coord_scale,
1194 mask_uv_rect.width() / tex_scale_x, 1226 mask_uv_rect.width() / tex_rect.width(),
1195 -mask_uv_rect.height() / tex_scale_y); 1227 -mask_uv_rect.height() / tex_rect.height());
1196 1228
1197 last_texture_unit = 1; 1229 last_texture_unit = 1;
1198 } 1230 }
1199 1231
1200 if (locations.edge != -1) 1232 if (locations.edge != -1)
1201 gl_->Uniform3fv(locations.edge, 8, edge); 1233 gl_->Uniform3fv(locations.edge, 8, edge);
1202 1234
1203 if (locations.viewport != -1) { 1235 if (locations.viewport != -1) {
1204 float viewport[4] = { 1236 float viewport[4] = {
1205 static_cast<float>(current_window_space_viewport_.x()), 1237 static_cast<float>(current_window_space_viewport_.x()),
(...skipping 2379 matching lines...) Expand 10 before | Expand all | Expand 10 after
3585 texture_id = pending_overlay_resources_.back()->texture_id(); 3617 texture_id = pending_overlay_resources_.back()->texture_id();
3586 } 3618 }
3587 3619
3588 context_support_->ScheduleOverlayPlane( 3620 context_support_->ScheduleOverlayPlane(
3589 overlay.plane_z_order, overlay.transform, texture_id, 3621 overlay.plane_z_order, overlay.transform, texture_id,
3590 ToNearestRect(overlay.display_rect), overlay.uv_rect); 3622 ToNearestRect(overlay.display_rect), overlay.uv_rect);
3591 } 3623 }
3592 } 3624 }
3593 3625
3594 } // namespace cc 3626 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/test/data/rotated_drop_shadow_filter_gl.png » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698