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 <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 #include <set> | 9 #include <set> |
10 #include <string> | 10 #include <string> |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "cc/output/compositor_frame.h" | 21 #include "cc/output/compositor_frame.h" |
22 #include "cc/output/compositor_frame_metadata.h" | 22 #include "cc/output/compositor_frame_metadata.h" |
23 #include "cc/output/context_provider.h" | 23 #include "cc/output/context_provider.h" |
24 #include "cc/output/copy_output_request.h" | 24 #include "cc/output/copy_output_request.h" |
25 #include "cc/output/dynamic_geometry_binding.h" | 25 #include "cc/output/dynamic_geometry_binding.h" |
26 #include "cc/output/gl_frame_data.h" | 26 #include "cc/output/gl_frame_data.h" |
27 #include "cc/output/output_surface.h" | 27 #include "cc/output/output_surface.h" |
28 #include "cc/output/render_surface_filters.h" | 28 #include "cc/output/render_surface_filters.h" |
29 #include "cc/output/static_geometry_binding.h" | 29 #include "cc/output/static_geometry_binding.h" |
30 #include "cc/quads/draw_polygon.h" | 30 #include "cc/quads/draw_polygon.h" |
31 #include "cc/quads/picture_draw_quad.h" | |
32 #include "cc/quads/render_pass.h" | 31 #include "cc/quads/render_pass.h" |
33 #include "cc/quads/stream_video_draw_quad.h" | 32 #include "cc/quads/stream_video_draw_quad.h" |
34 #include "cc/quads/texture_draw_quad.h" | 33 #include "cc/quads/texture_draw_quad.h" |
35 #include "cc/resources/layer_quad.h" | 34 #include "cc/resources/layer_quad.h" |
36 #include "cc/resources/scoped_gpu_raster.h" | |
37 #include "cc/resources/scoped_resource.h" | 35 #include "cc/resources/scoped_resource.h" |
38 #include "cc/resources/texture_mailbox_deleter.h" | 36 #include "cc/resources/texture_mailbox_deleter.h" |
39 #include "gpu/GLES2/gl2extchromium.h" | 37 #include "gpu/GLES2/gl2extchromium.h" |
40 #include "gpu/command_buffer/client/context_support.h" | 38 #include "gpu/command_buffer/client/context_support.h" |
41 #include "gpu/command_buffer/client/gles2_interface.h" | 39 #include "gpu/command_buffer/client/gles2_interface.h" |
42 #include "gpu/command_buffer/common/gpu_memory_allocation.h" | 40 #include "gpu/command_buffer/common/gpu_memory_allocation.h" |
43 #include "third_party/skia/include/core/SkBitmap.h" | 41 #include "third_party/skia/include/core/SkBitmap.h" |
44 #include "third_party/skia/include/core/SkColor.h" | 42 #include "third_party/skia/include/core/SkColor.h" |
45 #include "third_party/skia/include/core/SkColorFilter.h" | 43 #include "third_party/skia/include/core/SkColorFilter.h" |
46 #include "third_party/skia/include/core/SkImage.h" | 44 #include "third_party/skia/include/core/SkImage.h" |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
151 const size_t kMaxPendingSyncQueries = 16; | 149 const size_t kMaxPendingSyncQueries = 16; |
152 | 150 |
153 } // anonymous namespace | 151 } // anonymous namespace |
154 | 152 |
155 static GLint GetActiveTextureUnit(GLES2Interface* gl) { | 153 static GLint GetActiveTextureUnit(GLES2Interface* gl) { |
156 GLint active_unit = 0; | 154 GLint active_unit = 0; |
157 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); | 155 gl->GetIntegerv(GL_ACTIVE_TEXTURE, &active_unit); |
158 return active_unit; | 156 return active_unit; |
159 } | 157 } |
160 | 158 |
161 class GLRenderer::ScopedUseGrContext { | |
162 public: | |
163 static scoped_ptr<ScopedUseGrContext> Create(GLRenderer* renderer, | |
164 DrawingFrame* frame) { | |
165 return make_scoped_ptr(new ScopedUseGrContext(renderer, frame)); | |
166 } | |
167 | |
168 ~ScopedUseGrContext() { | |
169 // Pass context control back to GLrenderer. | |
170 scoped_gpu_raster_ = nullptr; | |
171 renderer_->RestoreGLState(); | |
172 renderer_->RestoreFramebuffer(frame_); | |
173 } | |
174 | |
175 GrContext* context() const { | |
176 return renderer_->output_surface_->context_provider()->GrContext(); | |
177 } | |
178 | |
179 private: | |
180 ScopedUseGrContext(GLRenderer* renderer, DrawingFrame* frame) | |
181 : scoped_gpu_raster_( | |
182 new ScopedGpuRaster(renderer->output_surface_->context_provider())), | |
183 renderer_(renderer), | |
184 frame_(frame) { | |
185 // scoped_gpu_raster_ passes context control to Skia. | |
186 } | |
187 | |
188 scoped_ptr<ScopedGpuRaster> scoped_gpu_raster_; | |
189 GLRenderer* renderer_; | |
190 DrawingFrame* frame_; | |
191 | |
192 DISALLOW_COPY_AND_ASSIGN(ScopedUseGrContext); | |
193 }; | |
194 | |
195 struct GLRenderer::PendingAsyncReadPixels { | 159 struct GLRenderer::PendingAsyncReadPixels { |
196 PendingAsyncReadPixels() : buffer(0) {} | 160 PendingAsyncReadPixels() : buffer(0) {} |
197 | 161 |
198 scoped_ptr<CopyOutputRequest> copy_request; | 162 scoped_ptr<CopyOutputRequest> copy_request; |
199 base::CancelableClosure finished_read_pixels_callback; | 163 base::CancelableClosure finished_read_pixels_callback; |
200 unsigned buffer; | 164 unsigned buffer; |
201 | 165 |
202 private: | 166 private: |
203 DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels); | 167 DISALLOW_COPY_AND_ASSIGN(PendingAsyncReadPixels); |
204 }; | 168 }; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 void GLRenderer::DoDrawQuad(DrawingFrame* frame, | 478 void GLRenderer::DoDrawQuad(DrawingFrame* frame, |
515 const DrawQuad* quad, | 479 const DrawQuad* quad, |
516 const gfx::QuadF* clip_region) { | 480 const gfx::QuadF* clip_region) { |
517 DCHECK(quad->rect.Contains(quad->visible_rect)); | 481 DCHECK(quad->rect.Contains(quad->visible_rect)); |
518 if (quad->material != DrawQuad::TEXTURE_CONTENT) { | 482 if (quad->material != DrawQuad::TEXTURE_CONTENT) { |
519 FlushTextureQuadCache(SHARED_BINDING); | 483 FlushTextureQuadCache(SHARED_BINDING); |
520 } | 484 } |
521 | 485 |
522 switch (quad->material) { | 486 switch (quad->material) { |
523 case DrawQuad::INVALID: | 487 case DrawQuad::INVALID: |
| 488 case DrawQuad::UNUSED_SPACE_FOR_PICTURE_CONTENT: |
524 NOTREACHED(); | 489 NOTREACHED(); |
525 break; | 490 break; |
526 case DrawQuad::CHECKERBOARD: | 491 case DrawQuad::CHECKERBOARD: |
527 DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad), | 492 DrawCheckerboardQuad(frame, CheckerboardDrawQuad::MaterialCast(quad), |
528 clip_region); | 493 clip_region); |
529 break; | 494 break; |
530 case DrawQuad::DEBUG_BORDER: | 495 case DrawQuad::DEBUG_BORDER: |
531 DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad)); | 496 DrawDebugBorderQuad(frame, DebugBorderDrawQuad::MaterialCast(quad)); |
532 break; | 497 break; |
533 case DrawQuad::IO_SURFACE_CONTENT: | 498 case DrawQuad::IO_SURFACE_CONTENT: |
534 DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad), | 499 DrawIOSurfaceQuad(frame, IOSurfaceDrawQuad::MaterialCast(quad), |
535 clip_region); | 500 clip_region); |
536 break; | 501 break; |
537 case DrawQuad::PICTURE_CONTENT: | |
538 // PictureDrawQuad should only be used for resourceless software draws. | |
539 NOTREACHED(); | |
540 break; | |
541 case DrawQuad::RENDER_PASS: | 502 case DrawQuad::RENDER_PASS: |
542 DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad), | 503 DrawRenderPassQuad(frame, RenderPassDrawQuad::MaterialCast(quad), |
543 clip_region); | 504 clip_region); |
544 break; | 505 break; |
545 case DrawQuad::SOLID_COLOR: | 506 case DrawQuad::SOLID_COLOR: |
546 DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad), | 507 DrawSolidColorQuad(frame, SolidColorDrawQuad::MaterialCast(quad), |
547 clip_region); | 508 clip_region); |
548 break; | 509 break; |
549 case DrawQuad::STREAM_VIDEO_CONTENT: | 510 case DrawQuad::STREAM_VIDEO_CONTENT: |
550 DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad), | 511 DrawStreamVideoQuad(frame, StreamVideoDrawQuad::MaterialCast(quad), |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, | 615 (SkColorGetB(color) * (1.0f / 255.0f)) * alpha, |
655 alpha)); | 616 alpha)); |
656 | 617 |
657 GLC(gl_, gl_->LineWidth(quad->width)); | 618 GLC(gl_, gl_->LineWidth(quad->width)); |
658 | 619 |
659 // The indices for the line are stored in the same array as the triangle | 620 // The indices for the line are stored in the same array as the triangle |
660 // indices. | 621 // indices. |
661 GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0)); | 622 GLC(gl_, gl_->DrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, 0)); |
662 } | 623 } |
663 | 624 |
664 static skia::RefPtr<SkImage> ApplyImageFilter( | |
665 scoped_ptr<GLRenderer::ScopedUseGrContext> use_gr_context, | |
666 ResourceProvider* resource_provider, | |
667 const gfx::Rect& rect, | |
668 const gfx::Vector2dF& scale, | |
669 SkImageFilter* filter, | |
670 ScopedResource* source_texture_resource) { | |
671 if (!filter) | |
672 return skia::RefPtr<SkImage>(); | |
673 | |
674 if (!use_gr_context) | |
675 return skia::RefPtr<SkImage>(); | |
676 | |
677 ResourceProvider::ScopedReadLockGL lock(resource_provider, | |
678 source_texture_resource->id()); | |
679 | |
680 // Wrap the source texture in a Ganesh platform texture. | |
681 GrBackendTextureDesc backend_texture_description; | |
682 backend_texture_description.fWidth = source_texture_resource->size().width(); | |
683 backend_texture_description.fHeight = | |
684 source_texture_resource->size().height(); | |
685 backend_texture_description.fConfig = kSkia8888_GrPixelConfig; | |
686 backend_texture_description.fTextureHandle = lock.texture_id(); | |
687 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
688 skia::RefPtr<GrTexture> texture = | |
689 skia::AdoptRef(use_gr_context->context()->wrapBackendTexture( | |
690 backend_texture_description)); | |
691 if (!texture) { | |
692 TRACE_EVENT_INSTANT0("cc", | |
693 "ApplyImageFilter wrap background texture failed", | |
694 TRACE_EVENT_SCOPE_THREAD); | |
695 return skia::RefPtr<SkImage>(); | |
696 } | |
697 | |
698 SkImageInfo info = | |
699 SkImageInfo::MakeN32Premul(source_texture_resource->size().width(), | |
700 source_texture_resource->size().height()); | |
701 // Place the platform texture inside an SkBitmap. | |
702 SkBitmap source; | |
703 source.setInfo(info); | |
704 skia::RefPtr<SkGrPixelRef> pixel_ref = | |
705 skia::AdoptRef(new SkGrPixelRef(info, texture.get())); | |
706 source.setPixelRef(pixel_ref.get()); | |
707 | |
708 // Create a scratch texture for backing store. | |
709 GrTextureDesc desc; | |
710 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
711 desc.fSampleCnt = 0; | |
712 desc.fWidth = source.width(); | |
713 desc.fHeight = source.height(); | |
714 desc.fConfig = kSkia8888_GrPixelConfig; | |
715 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
716 skia::RefPtr<GrTexture> backing_store = | |
717 skia::AdoptRef(use_gr_context->context()->refScratchTexture( | |
718 desc, GrContext::kExact_ScratchTexMatch)); | |
719 if (!backing_store) { | |
720 TRACE_EVENT_INSTANT0("cc", | |
721 "ApplyImageFilter scratch texture allocation failed", | |
722 TRACE_EVENT_SCOPE_THREAD); | |
723 return skia::RefPtr<SkImage>(); | |
724 } | |
725 | |
726 // Create surface to draw into. | |
727 skia::RefPtr<SkSurface> surface = skia::AdoptRef( | |
728 SkSurface::NewRenderTargetDirect(backing_store->asRenderTarget())); | |
729 skia::RefPtr<SkCanvas> canvas = skia::SharePtr(surface->getCanvas()); | |
730 | |
731 // Draw the source bitmap through the filter to the canvas. | |
732 SkPaint paint; | |
733 paint.setImageFilter(filter); | |
734 canvas->clear(SK_ColorTRANSPARENT); | |
735 | |
736 // The origin of the filter is top-left and the origin of the source is | |
737 // bottom-left, but the orientation is the same, so we must translate the | |
738 // filter so that it renders at the bottom of the texture to avoid | |
739 // misregistration. | |
740 int y_translate = source.height() - rect.height() - rect.origin().y(); | |
741 canvas->translate(-rect.origin().x(), y_translate); | |
742 canvas->scale(scale.x(), scale.y()); | |
743 canvas->drawSprite(source, 0, 0, &paint); | |
744 | |
745 skia::RefPtr<SkImage> image = skia::AdoptRef(surface->newImageSnapshot()); | |
746 if (!image || !image->getTexture()) { | |
747 return skia::RefPtr<SkImage>(); | |
748 } | |
749 | |
750 // Flush the GrContext to ensure all buffered GL calls are drawn to the | |
751 // backing store before we access and return it, and have cc begin using the | |
752 // GL context again. | |
753 canvas->flush(); | |
754 | |
755 return image; | |
756 } | |
757 | |
758 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { | 625 bool GLRenderer::CanApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
759 return use_blend_equation_advanced_ || | 626 return use_blend_equation_advanced_ || |
760 blend_mode == SkXfermode::kScreen_Mode || | 627 blend_mode == SkXfermode::kScreen_Mode || |
761 blend_mode == SkXfermode::kSrcOver_Mode; | 628 blend_mode == SkXfermode::kSrcOver_Mode; |
762 } | 629 } |
763 | 630 |
764 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { | 631 void GLRenderer::ApplyBlendModeUsingBlendFunc(SkXfermode::Mode blend_mode) { |
765 DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode)); | 632 DCHECK(CanApplyBlendModeUsingBlendFunc(blend_mode)); |
766 | 633 |
767 // Any modes set here must be reset in RestoreBlendFuncToDefault | 634 // Any modes set here must be reset in RestoreBlendFuncToDefault |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 if (blend_mode == SkXfermode::kSrcOver_Mode) | 697 if (blend_mode == SkXfermode::kSrcOver_Mode) |
831 return; | 698 return; |
832 | 699 |
833 if (use_blend_equation_advanced_) { | 700 if (use_blend_equation_advanced_) { |
834 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); | 701 GLC(gl_, gl_->BlendEquation(GL_FUNC_ADD)); |
835 } else { | 702 } else { |
836 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); | 703 GLC(gl_, gl_->BlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); |
837 } | 704 } |
838 } | 705 } |
839 | 706 |
840 bool GLRenderer::ShouldApplyBackgroundFilters(DrawingFrame* frame, | |
841 const RenderPassDrawQuad* quad) { | |
842 if (quad->background_filters.IsEmpty()) | |
843 return false; | |
844 | |
845 // TODO(danakj): We only allow background filters on an opaque render surface | |
846 // because other surfaces may contain translucent pixels, and the contents | |
847 // behind those translucent pixels wouldn't have the filter applied. | |
848 if (frame->current_render_pass->has_transparent_background) | |
849 return false; | |
850 | |
851 // TODO(ajuma): Add support for reference filters once | |
852 // FilterOperations::GetOutsets supports reference filters. | |
853 if (quad->background_filters.HasReferenceFilter()) | |
854 return false; | |
855 return true; | |
856 } | |
857 | |
858 // This takes a gfx::Rect and a clip region quad in the same space, | 707 // This takes a gfx::Rect and a clip region quad in the same space, |
859 // and returns a quad with the same proportions in the space -0.5->0.5. | 708 // and returns a quad with the same proportions in the space -0.5->0.5. |
860 bool GetScaledRegion(const gfx::Rect& rect, | 709 bool GetScaledRegion(const gfx::Rect& rect, |
861 const gfx::QuadF* clip, | 710 const gfx::QuadF* clip, |
862 gfx::QuadF* scaled_region) { | 711 gfx::QuadF* scaled_region) { |
863 if (!clip) | 712 if (!clip) |
864 return false; | 713 return false; |
865 | 714 |
866 gfx::PointF p1(((clip->p1().x() - rect.x()) / rect.width()) - 0.5f, | 715 gfx::PointF p1(((clip->p1().x() - rect.x()) / rect.width()) - 0.5f, |
867 ((clip->p1().y() - rect.y()) / rect.height()) - 0.5f); | 716 ((clip->p1().y() - rect.y()) / rect.height()) - 0.5f); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 const gfx::QuadF* clip_region, | 748 const gfx::QuadF* clip_region, |
900 bool use_aa) { | 749 bool use_aa) { |
901 gfx::QuadF scaled_region; | 750 gfx::QuadF scaled_region; |
902 if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) { | 751 if (!GetScaledRegion(quad->rect, clip_region, &scaled_region)) { |
903 scaled_region = SharedGeometryQuad().BoundingBox(); | 752 scaled_region = SharedGeometryQuad().BoundingBox(); |
904 } | 753 } |
905 | 754 |
906 gfx::Rect backdrop_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 755 gfx::Rect backdrop_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
907 contents_device_transform, scaled_region.BoundingBox())); | 756 contents_device_transform, scaled_region.BoundingBox())); |
908 | 757 |
909 if (ShouldApplyBackgroundFilters(frame, quad)) { | |
910 int top, right, bottom, left; | |
911 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); | |
912 backdrop_rect.Inset(-left, -top, -right, -bottom); | |
913 } | |
914 | |
915 if (!backdrop_rect.IsEmpty() && use_aa) { | 758 if (!backdrop_rect.IsEmpty() && use_aa) { |
916 const int kOutsetForAntialiasing = 1; | 759 const int kOutsetForAntialiasing = 1; |
917 backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing); | 760 backdrop_rect.Inset(-kOutsetForAntialiasing, -kOutsetForAntialiasing); |
918 } | 761 } |
919 | 762 |
920 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( | 763 backdrop_rect.Intersect(MoveFromDrawToWindowSpace( |
921 frame, frame->current_render_pass->output_rect)); | 764 frame, frame->current_render_pass->output_rect)); |
922 return backdrop_rect; | 765 return backdrop_rect; |
923 } | 766 } |
924 | 767 |
925 scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( | 768 scoped_ptr<ScopedResource> GLRenderer::GetBackdropTexture( |
926 const gfx::Rect& bounding_rect) { | 769 const gfx::Rect& bounding_rect) { |
927 scoped_ptr<ScopedResource> device_background_texture = | 770 scoped_ptr<ScopedResource> device_background_texture = |
928 ScopedResource::Create(resource_provider_); | 771 ScopedResource::Create(resource_provider_); |
929 // CopyTexImage2D fails when called on a texture having immutable storage. | 772 // CopyTexImage2D fails when called on a texture having immutable storage. |
930 device_background_texture->Allocate( | 773 device_background_texture->Allocate( |
931 bounding_rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888); | 774 bounding_rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888); |
932 { | 775 { |
933 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, | 776 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, |
934 device_background_texture->id()); | 777 device_background_texture->id()); |
935 GetFramebufferTexture( | 778 GetFramebufferTexture( |
936 lock.texture_id(), device_background_texture->format(), bounding_rect); | 779 lock.texture_id(), device_background_texture->format(), bounding_rect); |
937 } | 780 } |
938 return device_background_texture.Pass(); | 781 return device_background_texture.Pass(); |
939 } | 782 } |
940 | 783 |
941 skia::RefPtr<SkImage> GLRenderer::ApplyBackgroundFilters( | |
942 DrawingFrame* frame, | |
943 const RenderPassDrawQuad* quad, | |
944 ScopedResource* background_texture) { | |
945 DCHECK(ShouldApplyBackgroundFilters(frame, quad)); | |
946 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | |
947 quad->background_filters, background_texture->size()); | |
948 | |
949 skia::RefPtr<SkImage> background_with_filters = ApplyImageFilter( | |
950 ScopedUseGrContext::Create(this, frame), resource_provider_, quad->rect, | |
951 quad->filters_scale, filter.get(), background_texture); | |
952 return background_with_filters; | |
953 } | |
954 | |
955 void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, | 784 void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, |
956 const RenderPassDrawQuad* quad, | 785 const RenderPassDrawQuad* quad, |
957 const gfx::QuadF* clip_region) { | 786 const gfx::QuadF* clip_region) { |
958 ScopedResource* contents_texture = | 787 ScopedResource* contents_texture = |
959 render_pass_textures_.get(quad->render_pass_id); | 788 render_pass_textures_.get(quad->render_pass_id); |
960 if (!contents_texture || !contents_texture->id()) | 789 if (!contents_texture || !contents_texture->id()) |
961 return; | 790 return; |
962 | 791 |
963 gfx::Transform quad_rect_matrix; | 792 gfx::Transform quad_rect_matrix; |
964 QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect); | 793 QuadRectTransform(&quad_rect_matrix, quad->quadTransform(), quad->rect); |
965 gfx::Transform contents_device_transform = | 794 gfx::Transform contents_device_transform = |
966 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 795 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
967 contents_device_transform.FlattenTo2d(); | 796 contents_device_transform.FlattenTo2d(); |
968 | 797 |
969 // Can only draw surface if device matrix is invertible. | 798 // Can only draw surface if device matrix is invertible. |
970 if (!contents_device_transform.IsInvertible()) | 799 if (!contents_device_transform.IsInvertible()) |
971 return; | 800 return; |
972 | 801 |
973 gfx::QuadF surface_quad = SharedGeometryQuad(); | 802 gfx::QuadF surface_quad = SharedGeometryQuad(); |
974 float edge[24]; | 803 float edge[24]; |
975 bool use_aa = settings_->allow_antialiasing && | 804 bool use_aa = settings_->allow_antialiasing && |
976 ShouldAntialiasQuad(contents_device_transform, quad, | 805 ShouldAntialiasQuad(contents_device_transform, quad, |
977 settings_->force_antialiasing); | 806 settings_->force_antialiasing); |
978 | 807 |
979 SetupQuadForClippingAndAntialiasing(contents_device_transform, quad, use_aa, | 808 SetupQuadForClippingAndAntialiasing(contents_device_transform, quad, use_aa, |
980 clip_region, &surface_quad, edge); | 809 clip_region, &surface_quad, edge); |
981 SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode; | 810 SkXfermode::Mode blend_mode = quad->shared_quad_state->blend_mode; |
982 bool use_shaders_for_blending = | 811 bool use_shaders_for_blending = |
983 !CanApplyBlendModeUsingBlendFunc(blend_mode) || | 812 !CanApplyBlendModeUsingBlendFunc(blend_mode) || |
984 ShouldApplyBackgroundFilters(frame, quad) || | |
985 settings_->force_blending_with_shaders; | 813 settings_->force_blending_with_shaders; |
986 | 814 |
987 scoped_ptr<ScopedResource> background_texture; | 815 scoped_ptr<ScopedResource> background_texture; |
988 skia::RefPtr<SkImage> background_image; | 816 skia::RefPtr<SkImage> background_image; |
989 gfx::Rect background_rect; | 817 gfx::Rect background_rect; |
990 if (use_shaders_for_blending) { | 818 if (use_shaders_for_blending) { |
991 // Compute a bounding box around the pixels that will be visible through | 819 // Compute a bounding box around the pixels that will be visible through |
992 // the quad. | 820 // the quad. |
993 background_rect = GetBackdropBoundingBoxForRenderPassQuad( | 821 background_rect = GetBackdropBoundingBoxForRenderPassQuad( |
994 frame, quad, contents_device_transform, clip_region, use_aa); | 822 frame, quad, contents_device_transform, clip_region, use_aa); |
995 | 823 |
996 if (!background_rect.IsEmpty()) { | 824 if (!background_rect.IsEmpty()) { |
997 // The pixels from the filtered background should completely replace the | 825 // The pixels from the filtered background should completely replace the |
998 // current pixel values. | 826 // current pixel values. |
999 if (blend_enabled()) | 827 if (blend_enabled()) |
1000 SetBlendEnabled(false); | 828 SetBlendEnabled(false); |
1001 | 829 |
1002 // Read the pixels in the bounding box into a buffer R. | 830 // Read the pixels in the bounding box into a buffer R. |
1003 // This function allocates a texture, which should contribute to the | 831 // This function allocates a texture, which should contribute to the |
1004 // amount of memory used by render surfaces: | 832 // amount of memory used by render surfaces: |
1005 // LayerTreeHost::CalculateMemoryForRenderSurfaces. | 833 // LayerTreeHost::CalculateMemoryForRenderSurfaces. |
1006 background_texture = GetBackdropTexture(background_rect); | 834 background_texture = GetBackdropTexture(background_rect); |
1007 | |
1008 if (ShouldApplyBackgroundFilters(frame, quad) && background_texture) { | |
1009 // Apply the background filters to R, so that it is applied in the | |
1010 // pixels' coordinate space. | |
1011 background_image = | |
1012 ApplyBackgroundFilters(frame, quad, background_texture.get()); | |
1013 } | |
1014 } | 835 } |
1015 | 836 |
1016 if (!background_texture) { | 837 if (!background_texture) { |
1017 // Something went wrong with reading the backdrop. | 838 // Something went wrong with reading the backdrop. |
1018 DCHECK(!background_image); | 839 DCHECK(!background_image); |
1019 use_shaders_for_blending = false; | 840 use_shaders_for_blending = false; |
1020 } else if (background_image) { | 841 } else if (background_image) { |
1021 // Reset original background texture if there is not any mask | 842 // Reset original background texture if there is not any mask |
1022 if (!quad->mask_resource_id) | 843 if (!quad->mask_resource_id) |
1023 background_texture.reset(); | 844 background_texture.reset(); |
1024 } else if (CanApplyBlendModeUsingBlendFunc(blend_mode) && | |
1025 ShouldApplyBackgroundFilters(frame, quad)) { | |
1026 // Something went wrong with applying background filters to the backdrop. | |
1027 use_shaders_for_blending = false; | |
1028 background_texture.reset(); | |
1029 } | 845 } |
1030 } | 846 } |
1031 // Need original background texture for mask? | 847 // Need original background texture for mask? |
1032 bool mask_for_background = | 848 bool mask_for_background = |
1033 background_texture && // Have original background texture | 849 background_texture && // Have original background texture |
1034 background_image && // Have filtered background texture | 850 background_image && // Have filtered background texture |
1035 quad->mask_resource_id; // Have mask texture | 851 quad->mask_resource_id; // Have mask texture |
1036 SetBlendEnabled( | 852 SetBlendEnabled( |
1037 !use_shaders_for_blending && | 853 !use_shaders_for_blending && |
1038 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode))); | 854 (quad->ShouldDrawWithBlending() || !IsDefaultBlendMode(blend_mode))); |
1039 | 855 |
1040 // TODO(senorblanco): Cache this value so that we don't have to do it for both | 856 // TODO(senorblanco): Cache this value so that we don't have to do it for both |
1041 // the surface and its replica. Apply filters to the contents texture. | 857 // the surface and its replica. Apply filters to the contents texture. |
1042 skia::RefPtr<SkImage> filter_image; | 858 skia::RefPtr<SkImage> filter_image; |
1043 SkScalar color_matrix[20]; | 859 SkScalar color_matrix[20]; |
1044 bool use_color_matrix = false; | 860 bool use_color_matrix = false; |
1045 if (!quad->filters.IsEmpty()) { | 861 DCHECK(quad->filters.IsEmpty()); |
1046 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | |
1047 quad->filters, contents_texture->size()); | |
1048 if (filter) { | |
1049 skia::RefPtr<SkColorFilter> cf; | |
1050 | |
1051 { | |
1052 SkColorFilter* colorfilter_rawptr = NULL; | |
1053 filter->asColorFilter(&colorfilter_rawptr); | |
1054 cf = skia::AdoptRef(colorfilter_rawptr); | |
1055 } | |
1056 | |
1057 if (cf && cf->asColorMatrix(color_matrix) && !filter->getInput(0)) { | |
1058 // We have a single color matrix as a filter; apply it locally | |
1059 // in the compositor. | |
1060 use_color_matrix = true; | |
1061 } else { | |
1062 filter_image = ApplyImageFilter( | |
1063 ScopedUseGrContext::Create(this, frame), resource_provider_, | |
1064 quad->rect, quad->filters_scale, filter.get(), contents_texture); | |
1065 } | |
1066 } | |
1067 } | |
1068 | 862 |
1069 scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; | 863 scoped_ptr<ResourceProvider::ScopedSamplerGL> mask_resource_lock; |
1070 unsigned mask_texture_id = 0; | 864 unsigned mask_texture_id = 0; |
1071 SamplerType mask_sampler = SAMPLER_TYPE_NA; | 865 SamplerType mask_sampler = SAMPLER_TYPE_NA; |
1072 if (quad->mask_resource_id) { | 866 if (quad->mask_resource_id) { |
1073 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL( | 867 mask_resource_lock.reset(new ResourceProvider::ScopedSamplerGL( |
1074 resource_provider_, quad->mask_resource_id, GL_TEXTURE1, GL_LINEAR)); | 868 resource_provider_, quad->mask_resource_id, GL_TEXTURE1, GL_LINEAR)); |
1075 mask_texture_id = mask_resource_lock->texture_id(); | 869 mask_texture_id = mask_resource_lock->texture_id(); |
1076 mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target()); | 870 mask_sampler = SamplerTypeFromTextureTarget(mask_resource_lock->target()); |
1077 } | 871 } |
(...skipping 2451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3529 context_support_->ScheduleOverlayPlane( | 3323 context_support_->ScheduleOverlayPlane( |
3530 overlay.plane_z_order, | 3324 overlay.plane_z_order, |
3531 overlay.transform, | 3325 overlay.transform, |
3532 pending_overlay_resources_.back()->texture_id(), | 3326 pending_overlay_resources_.back()->texture_id(), |
3533 overlay.display_rect, | 3327 overlay.display_rect, |
3534 overlay.uv_rect); | 3328 overlay.uv_rect); |
3535 } | 3329 } |
3536 } | 3330 } |
3537 | 3331 |
3538 } // namespace cc | 3332 } // namespace cc |
OLD | NEW |