| 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 |