Chromium Code Reviews| 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 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |