OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |