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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 160 TextureMailboxDeleter* texture_mailbox_deleter, | 160 TextureMailboxDeleter* texture_mailbox_deleter, |
| 161 int highp_threshold_min) | 161 int highp_threshold_min) |
| 162 : DirectRenderer(client, settings, output_surface, resource_provider), | 162 : DirectRenderer(client, settings, output_surface, resource_provider), |
| 163 offscreen_framebuffer_id_(0), | 163 offscreen_framebuffer_id_(0), |
| 164 shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)), | 164 shared_geometry_quad_(gfx::RectF(-0.5f, -0.5f, 1.0f, 1.0f)), |
| 165 context_(output_surface->context_provider()->Context3d()), | 165 context_(output_surface->context_provider()->Context3d()), |
| 166 context_support_(output_surface->context_provider()->ContextSupport()), | 166 context_support_(output_surface->context_provider()->ContextSupport()), |
| 167 texture_mailbox_deleter_(texture_mailbox_deleter), | 167 texture_mailbox_deleter_(texture_mailbox_deleter), |
| 168 is_backbuffer_discarded_(false), | 168 is_backbuffer_discarded_(false), |
| 169 is_using_bind_uniform_(false), | 169 is_using_bind_uniform_(false), |
| 170 is_using_texture_storage_(false), | |
| 170 visible_(true), | 171 visible_(true), |
| 171 is_scissor_enabled_(false), | 172 is_scissor_enabled_(false), |
| 172 stencil_shadow_(false), | 173 stencil_shadow_(false), |
| 173 blend_shadow_(false), | 174 blend_shadow_(false), |
| 174 highp_threshold_min_(highp_threshold_min), | 175 highp_threshold_min_(highp_threshold_min), |
| 175 highp_threshold_cache_(0), | 176 highp_threshold_cache_(0), |
| 176 on_demand_tile_raster_resource_id_(0) { | 177 on_demand_tile_raster_resource_id_(0) { |
| 177 DCHECK(context_); | 178 DCHECK(context_); |
| 178 DCHECK(context_support_); | 179 DCHECK(context_support_); |
| 179 } | 180 } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 206 | 207 |
| 207 capabilities_.using_offscreen_context3d = true; | 208 capabilities_.using_offscreen_context3d = true; |
| 208 | 209 |
| 209 capabilities_.using_map_image = | 210 capabilities_.using_map_image = |
| 210 settings_->use_map_image && context_caps.map_image; | 211 settings_->use_map_image && context_caps.map_image; |
| 211 | 212 |
| 212 capabilities_.using_discard_framebuffer = | 213 capabilities_.using_discard_framebuffer = |
| 213 context_caps.discard_framebuffer; | 214 context_caps.discard_framebuffer; |
| 214 | 215 |
| 215 is_using_bind_uniform_ = context_caps.bind_uniform_location; | 216 is_using_bind_uniform_ = context_caps.bind_uniform_location; |
| 217 is_using_texture_storage_ = context_caps.texture_storage; | |
| 216 | 218 |
| 217 if (!InitializeSharedObjects()) | 219 if (!InitializeSharedObjects()) |
| 218 return false; | 220 return false; |
| 219 | 221 |
| 220 // Make sure the viewport and context gets initialized, even if it is to zero. | 222 // Make sure the viewport and context gets initialized, even if it is to zero. |
| 221 ViewportChanged(); | 223 ViewportChanged(); |
| 222 return true; | 224 return true; |
| 223 } | 225 } |
| 224 | 226 |
| 225 void GLRenderer::InitializeGrContext() { | 227 void GLRenderer::InitializeGrContext() { |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 558 // Flush the GL context so rendering results from this context are | 560 // Flush the GL context so rendering results from this context are |
| 559 // visible in the compositor's context. | 561 // visible in the compositor's context. |
| 560 offscreen_contexts->Context3d()->flush(); | 562 offscreen_contexts->Context3d()->flush(); |
| 561 | 563 |
| 562 // Use the compositor's GL context again. | 564 // Use the compositor's GL context again. |
| 563 renderer->Context()->makeContextCurrent(); | 565 renderer->Context()->makeContextCurrent(); |
| 564 | 566 |
| 565 return device.accessBitmap(false); | 567 return device.accessBitmap(false); |
| 566 } | 568 } |
| 567 | 569 |
| 568 scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters( | 570 static SkBitmap ApplyBlendModeWithBackdrop( |
| 571 GLRenderer* renderer, | |
| 572 ContextProvider* offscreen_contexts, | |
| 573 SkBitmap source_bitmap_with_filters, | |
| 574 ScopedResource* source_texture_resource, | |
| 575 ScopedResource* background_texture_resource, | |
| 576 SkXfermode::Mode blend_mode) { | |
| 577 if (!offscreen_contexts || !offscreen_contexts->GrContext()) | |
| 578 return source_bitmap_with_filters; | |
| 579 | |
| 580 DCHECK(background_texture_resource); | |
| 581 DCHECK(source_texture_resource); | |
| 582 | |
| 583 gfx::Size source_size = source_texture_resource->size(); | |
| 584 gfx::Size background_size = background_texture_resource->size(); | |
| 585 | |
| 586 DCHECK_LE(background_size.width(), source_size.width()); | |
| 587 DCHECK_LE(background_size.height(), source_size.height()); | |
| 588 | |
| 589 int source_texture_with_filters_id; | |
| 590 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; | |
| 591 if (source_bitmap_with_filters.getTexture()) { | |
| 592 DCHECK_EQ(source_size.width(), source_bitmap_with_filters.width()); | |
| 593 DCHECK_EQ(source_size.height(), source_bitmap_with_filters.height()); | |
| 594 GrTexture* texture = | |
| 595 reinterpret_cast<GrTexture*>(source_bitmap_with_filters.getTexture()); | |
| 596 source_texture_with_filters_id = texture->getTextureHandle(); | |
| 597 } else { | |
| 598 lock.reset(new ResourceProvider::ScopedReadLockGL( | |
| 599 renderer->resource_provider(), source_texture_resource->id())); | |
| 600 source_texture_with_filters_id = lock->texture_id(); | |
| 601 } | |
| 602 | |
| 603 ResourceProvider::ScopedReadLockGL lock_background( | |
| 604 renderer->resource_provider(), background_texture_resource->id()); | |
| 605 | |
| 606 // Flush the compositor context to ensure that textures there are available | |
| 607 // in the shared context. Do this after locking/creating the compositor | |
| 608 // texture. | |
| 609 renderer->resource_provider()->Flush(); | |
| 610 | |
| 611 // Make sure skia uses the correct GL context. | |
| 612 offscreen_contexts->Context3d()->makeContextCurrent(); | |
| 613 | |
| 614 // Wrap the source texture in a Ganesh platform texture. | |
| 615 GrBackendTextureDesc backend_texture_description; | |
| 616 backend_texture_description.fConfig = kSkia8888_GrPixelConfig; | |
| 617 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
| 618 | |
| 619 backend_texture_description.fWidth = source_size.width(); | |
| 620 backend_texture_description.fHeight = source_size.height(); | |
| 621 backend_texture_description.fTextureHandle = source_texture_with_filters_id; | |
| 622 skia::RefPtr<GrTexture> source_texture = | |
| 623 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( | |
| 624 backend_texture_description)); | |
| 625 | |
| 626 backend_texture_description.fWidth = background_size.width(); | |
| 627 backend_texture_description.fHeight = background_size.height(); | |
| 628 backend_texture_description.fTextureHandle = lock_background.texture_id(); | |
| 629 skia::RefPtr<GrTexture> background_texture = | |
| 630 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( | |
| 631 backend_texture_description)); | |
| 632 | |
| 633 // Place the platform texture inside an SkBitmap. | |
| 634 SkBitmap source; | |
| 635 source.setConfig( | |
| 636 SkBitmap::kARGB_8888_Config, source_size.width(), source_size.height()); | |
| 637 skia::RefPtr<SkGrPixelRef> source_pixel_ref = | |
| 638 skia::AdoptRef(new SkGrPixelRef(source_texture.get())); | |
| 639 source.setPixelRef(source_pixel_ref.get()); | |
| 640 | |
| 641 SkBitmap background; | |
| 642 background.setConfig(SkBitmap::kARGB_8888_Config, | |
| 643 background_size.width(), | |
| 644 background_size.height()); | |
| 645 skia::RefPtr<SkGrPixelRef> background_pixel_ref = | |
| 646 skia::AdoptRef(new SkGrPixelRef(background_texture.get())); | |
| 647 background.setPixelRef(background_pixel_ref.get()); | |
| 648 | |
| 649 // Create a scratch texture for backing store. | |
| 650 GrTextureDesc desc; | |
| 651 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
| 652 desc.fSampleCnt = 0; | |
| 653 desc.fWidth = source.width(); | |
| 654 desc.fHeight = source.height(); | |
| 655 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 656 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
| 657 GrAutoScratchTexture scratch_texture( | |
| 658 offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch); | |
| 659 skia::RefPtr<GrTexture> backing_store = | |
| 660 skia::AdoptRef(scratch_texture.detach()); | |
| 661 | |
| 662 // Create a device and canvas using that backing store. | |
| 663 SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get()); | |
| 664 SkCanvas canvas(&device); | |
| 665 | |
| 666 // Draw the source bitmap through the filter to the canvas. | |
| 667 canvas.clear(SK_ColorTRANSPARENT); | |
| 668 canvas.drawSprite(background, 0, 0); | |
| 669 SkPaint paint; | |
| 670 paint.setXfermodeMode(blend_mode); | |
| 671 canvas.drawSprite(source, 0, 0, &paint); | |
| 672 | |
| 673 // Flush skia context so that all the rendered stuff appears on the | |
| 674 // texture. | |
| 675 offscreen_contexts->GrContext()->flush(); | |
| 676 | |
| 677 // Flush the GL context so rendering results from this context are | |
| 678 // visible in the compositor's context. | |
| 679 offscreen_contexts->Context3d()->flush(); | |
| 680 | |
| 681 // Use the compositor's GL context again. | |
| 682 renderer->Context()->makeContextCurrent(); | |
| 683 | |
| 684 return device.accessBitmap(false); | |
| 685 } | |
| 686 | |
| 687 scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters( | |
| 569 DrawingFrame* frame, | 688 DrawingFrame* frame, |
| 570 const RenderPassDrawQuad* quad, | 689 const RenderPassDrawQuad* quad, |
| 571 const gfx::Transform& contents_device_transform, | 690 const gfx::Transform& contents_device_transform, |
| 572 const gfx::Transform& contents_device_transform_inverse) { | 691 const gfx::Transform& contents_device_transform_inverse, |
| 692 bool* background_changed) { | |
| 573 // This method draws a background filter, which applies a filter to any pixels | 693 // This method draws a background filter, which applies a filter to any pixels |
| 574 // behind the quad and seen through its background. The algorithm works as | 694 // behind the quad and seen through its background. The algorithm works as |
| 575 // follows: | 695 // follows: |
| 576 // 1. Compute a bounding box around the pixels that will be visible through | 696 // 1. Compute a bounding box around the pixels that will be visible through |
| 577 // the quad. | 697 // the quad. |
| 578 // 2. Read the pixels in the bounding box into a buffer R. | 698 // 2. Read the pixels in the bounding box into a buffer R. |
| 579 // 3. Apply the background filter to R, so that it is applied in the pixels' | 699 // 3. Apply the background filter to R, so that it is applied in the pixels' |
| 580 // coordinate space. | 700 // coordinate space. |
| 581 // 4. Apply the quad's inverse transform to map the pixels in R into the | 701 // 4. Apply the quad's inverse transform to map the pixels in R into the |
| 582 // quad's content space. This implicitly clips R by the content bounds of the | 702 // quad's content space. This implicitly clips R by the content bounds of the |
| 583 // quad since the destination texture has bounds matching the quad's content. | 703 // quad since the destination texture has bounds matching the quad's content. |
| 584 // 5. Draw the background texture for the contents using the same transform as | 704 // 5. Draw the background texture for the contents using the same transform as |
| 585 // used to draw the contents itself. This is done without blending to replace | 705 // used to draw the contents itself. This is done without blending to replace |
| 586 // the current background pixels with the new filtered background. | 706 // the current background pixels with the new filtered background. |
| 587 // 6. Draw the contents of the quad over drop of the new background with | 707 // 6. Draw the contents of the quad over drop of the new background with |
| 588 // blending, as per usual. The filtered background pixels will show through | 708 // blending, as per usual. The filtered background pixels will show through |
| 589 // any non-opaque pixels in this draws. | 709 // any non-opaque pixels in this draws. |
| 590 // | 710 // |
| 591 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. | 711 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. |
| 592 | 712 |
| 593 // TODO(danakj): When this algorithm changes, update | 713 // TODO(danakj): When this algorithm changes, update |
| 594 // LayerTreeHost::PrioritizeTextures() accordingly. | 714 // LayerTreeHost::PrioritizeTextures() accordingly. |
| 595 | 715 |
| 596 // TODO(danakj): We only allow background filters on an opaque render surface | 716 // TODO(danakj): We only allow background filters on an opaque render surface |
| 597 // because other surfaces may contain translucent pixels, and the contents | 717 // because other surfaces may contain translucent pixels, and the contents |
| 598 // behind those translucent pixels wouldn't have the filter applied. | 718 // behind those translucent pixels wouldn't have the filter applied. |
| 599 if (frame->current_render_pass->has_transparent_background) | 719 bool apply_background_filters = |
| 600 return scoped_ptr<ScopedResource>(); | 720 !frame->current_render_pass->has_transparent_background; |
| 601 DCHECK(!frame->current_texture); | 721 DCHECK(!frame->current_texture); |
| 602 | 722 |
| 603 // TODO(ajuma): Add support for reference filters once | 723 // TODO(ajuma): Add support for reference filters once |
| 604 // FilterOperations::GetOutsets supports reference filters. | 724 // FilterOperations::GetOutsets supports reference filters. |
| 605 if (quad->background_filters.HasReferenceFilter()) | 725 if (apply_background_filters && quad->background_filters.HasReferenceFilter()) |
| 606 return scoped_ptr<ScopedResource>(); | 726 apply_background_filters = false; |
| 607 | 727 |
| 608 // TODO(danakj): Do a single readback for both the surface and replica and | 728 // TODO(danakj): Do a single readback for both the surface and replica and |
| 609 // cache the filtered results (once filter textures are not reused). | 729 // cache the filtered results (once filter textures are not reused). |
| 610 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 730 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
| 611 contents_device_transform, SharedGeometryQuad().BoundingBox())); | 731 contents_device_transform, SharedGeometryQuad().BoundingBox())); |
| 612 | 732 |
| 613 int top, right, bottom, left; | 733 int top, right, bottom, left; |
| 614 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); | 734 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); |
| 615 window_rect.Inset(-left, -top, -right, -bottom); | 735 window_rect.Inset(-left, -top, -right, -bottom); |
| 616 | 736 |
| 617 window_rect.Intersect( | 737 window_rect.Intersect( |
| 618 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); | 738 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); |
| 619 | 739 |
| 620 scoped_ptr<ScopedResource> device_background_texture = | 740 scoped_ptr<ScopedResource> device_background_texture = |
| 621 ScopedResource::create(resource_provider_); | 741 ScopedResource::create(resource_provider_); |
| 742 cc::ResourceFormat background_texture_format = | |
| 743 is_using_texture_storage_ ? RGBA_4444 : RGBA_8888; | |
|
enne (OOO)
2013/11/04 22:38:16
I am probably missing something, but can you help
rosca
2013/11/05 19:14:09
When GL is capable of texture storage, resource pr
| |
| 622 if (!device_background_texture->Allocate(window_rect.size(), | 744 if (!device_background_texture->Allocate(window_rect.size(), |
| 623 ResourceProvider::TextureUsageAny, | 745 ResourceProvider::TextureUsageAny, |
| 624 RGBA_8888)) { | 746 background_texture_format)) { |
| 625 return scoped_ptr<ScopedResource>(); | 747 return scoped_ptr<ScopedResource>(); |
| 626 } else { | 748 } else { |
| 627 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, | 749 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, |
| 628 device_background_texture->id()); | 750 device_background_texture->id()); |
| 629 GetFramebufferTexture(lock.texture_id(), | 751 GetFramebufferTexture(lock.texture_id(), |
| 630 device_background_texture->format(), | 752 device_background_texture->format(), |
| 631 window_rect); | 753 window_rect); |
| 632 } | 754 } |
| 633 | 755 |
| 756 int filtered_device_background_texture_id = 0; | |
| 634 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | 757 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
| 635 quad->background_filters, device_background_texture->size()); | 758 quad->background_filters, device_background_texture->size()); |
| 636 | 759 |
| 637 SkBitmap filtered_device_background = | 760 SkBitmap filtered_device_background; |
| 638 ApplyImageFilter(this, | 761 if (apply_background_filters) |
| 639 frame->offscreen_context_provider, | 762 filtered_device_background = |
| 640 quad->rect.origin(), | 763 ApplyImageFilter(this, |
| 641 filter.get(), | 764 frame->offscreen_context_provider, |
| 642 device_background_texture.get()); | 765 quad->rect.origin(), |
| 643 if (!filtered_device_background.getTexture()) | 766 filter.get(), |
| 644 return scoped_ptr<ScopedResource>(); | 767 device_background_texture.get()); |
| 768 if (background_changed) | |
| 769 *background_changed = (filtered_device_background.getTexture() != NULL); | |
| 645 | 770 |
| 646 GrTexture* texture = | 771 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; |
| 647 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | 772 if (filtered_device_background.getTexture()) { |
| 648 int filtered_device_background_texture_id = texture->getTextureHandle(); | 773 GrTexture* texture = |
| 774 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | |
| 775 filtered_device_background_texture_id = texture->getTextureHandle(); | |
| 776 } else { | |
| 777 lock.reset(new ResourceProvider::ScopedReadLockGL( | |
| 778 resource_provider_, device_background_texture->id())); | |
| 779 filtered_device_background_texture_id = lock->texture_id(); | |
| 780 } | |
| 649 | 781 |
| 650 scoped_ptr<ScopedResource> background_texture = | 782 scoped_ptr<ScopedResource> background_texture = |
| 651 ScopedResource::create(resource_provider_); | 783 ScopedResource::create(resource_provider_); |
| 652 if (!background_texture->Allocate(quad->rect.size(), | 784 if (!background_texture->Allocate(quad->rect.size(), |
| 653 ResourceProvider::TextureUsageFramebuffer, | 785 ResourceProvider::TextureUsageFramebuffer, |
| 654 RGBA_8888)) | 786 RGBA_8888)) |
| 655 return scoped_ptr<ScopedResource>(); | 787 return scoped_ptr<ScopedResource>(); |
| 656 | 788 |
| 657 const RenderPass* target_render_pass = frame->current_render_pass; | 789 const RenderPass* target_render_pass = frame->current_render_pass; |
| 658 bool using_background_texture = | 790 bool using_background_texture = |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 709 gfx::Transform contents_device_transform = | 841 gfx::Transform contents_device_transform = |
| 710 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 842 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
| 711 contents_device_transform.FlattenTo2d(); | 843 contents_device_transform.FlattenTo2d(); |
| 712 | 844 |
| 713 // Can only draw surface if device matrix is invertible. | 845 // Can only draw surface if device matrix is invertible. |
| 714 gfx::Transform contents_device_transform_inverse( | 846 gfx::Transform contents_device_transform_inverse( |
| 715 gfx::Transform::kSkipInitialization); | 847 gfx::Transform::kSkipInitialization); |
| 716 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 848 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
| 717 return; | 849 return; |
| 718 | 850 |
| 851 bool apply_blend_mode = | |
| 852 quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode; | |
| 853 bool background_changed = false; | |
| 719 scoped_ptr<ScopedResource> background_texture; | 854 scoped_ptr<ScopedResource> background_texture; |
| 720 if (!quad->background_filters.IsEmpty()) { | 855 if (!quad->background_filters.IsEmpty() || apply_blend_mode) { |
| 721 // The pixels from the filtered background should completely replace the | 856 // The pixels from the filtered background should completely replace the |
| 722 // current pixel values. | 857 // current pixel values. |
| 723 bool disable_blending = blend_enabled(); | 858 bool disable_blending = blend_enabled(); |
| 724 if (disable_blending) | 859 if (disable_blending) |
| 725 SetBlendEnabled(false); | 860 SetBlendEnabled(false); |
| 726 | 861 |
| 727 background_texture = DrawBackgroundFilters( | 862 background_texture = |
| 728 frame, | 863 GetBackgroundWithFilters(frame, |
| 729 quad, | 864 quad, |
| 730 contents_device_transform, | 865 contents_device_transform, |
| 731 contents_device_transform_inverse); | 866 contents_device_transform_inverse, |
| 867 &background_changed); | |
| 732 | 868 |
| 733 if (disable_blending) | 869 if (disable_blending) |
| 734 SetBlendEnabled(true); | 870 SetBlendEnabled(true); |
| 735 } | 871 } |
| 736 | 872 |
| 737 // TODO(senorblanco): Cache this value so that we don't have to do it for both | 873 // TODO(senorblanco): Cache this value so that we don't have to do it for both |
| 738 // the surface and its replica. Apply filters to the contents texture. | 874 // the surface and its replica. Apply filters to the contents texture. |
| 739 SkBitmap filter_bitmap; | 875 SkBitmap filter_bitmap; |
| 740 SkScalar color_matrix[20]; | 876 SkScalar color_matrix[20]; |
| 741 bool use_color_matrix = false; | 877 bool use_color_matrix = false; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 760 } else { | 896 } else { |
| 761 filter_bitmap = ApplyImageFilter(this, | 897 filter_bitmap = ApplyImageFilter(this, |
| 762 frame->offscreen_context_provider, | 898 frame->offscreen_context_provider, |
| 763 quad->rect.origin(), | 899 quad->rect.origin(), |
| 764 filter.get(), | 900 filter.get(), |
| 765 contents_texture); | 901 contents_texture); |
| 766 } | 902 } |
| 767 } | 903 } |
| 768 } | 904 } |
| 769 | 905 |
| 906 if (background_texture && apply_blend_mode) { | |
| 907 filter_bitmap = | |
| 908 ApplyBlendModeWithBackdrop(this, | |
| 909 frame->offscreen_context_provider, | |
| 910 filter_bitmap, | |
| 911 contents_texture, | |
| 912 background_texture.get(), | |
| 913 quad->shared_quad_state->blend_mode); | |
| 914 } | |
| 915 | |
| 770 // Draw the background texture if there is one. | 916 // Draw the background texture if there is one. |
| 771 if (background_texture) { | 917 if (background_texture && background_changed) { |
| 772 DCHECK(background_texture->size() == quad->rect.size()); | 918 DCHECK(background_texture->size() == quad->rect.size()); |
| 773 ResourceProvider::ScopedReadLockGL lock(resource_provider_, | 919 ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
| 774 background_texture->id()); | 920 background_texture->id()); |
| 775 | 921 |
| 776 // The background_texture is oriented the same as the frame buffer. The | 922 // The background_texture is oriented the same as the frame buffer. The |
| 777 // transform we are copying with has a vertical flip, so flip the contents | 923 // transform we are copying with has a vertical flip, so flip the contents |
| 778 // in the shader to maintain orientation | 924 // in the shader to maintain orientation |
| 779 bool flip_vertically = true; | 925 bool flip_vertically = true; |
| 780 | 926 |
| 781 CopyTextureToFramebuffer(frame, | 927 CopyTextureToFramebuffer(frame, |
| (...skipping 2300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3082 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 3228 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
| 3083 // implementation. | 3229 // implementation. |
| 3084 return gr_context_ && context_->getContextAttributes().stencil; | 3230 return gr_context_ && context_->getContextAttributes().stencil; |
| 3085 } | 3231 } |
| 3086 | 3232 |
| 3087 bool GLRenderer::IsContextLost() { | 3233 bool GLRenderer::IsContextLost() { |
| 3088 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 3234 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
| 3089 } | 3235 } |
| 3090 | 3236 |
| 3091 } // namespace cc | 3237 } // namespace cc |
| OLD | NEW |