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; | |
enne (OOO)
2013/11/06 22:40:19
This is a little too magical for me. It makes ass
rosca
2013/11/07 01:58:16
Done.
| |
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_); |
622 if (!device_background_texture->Allocate(window_rect.size(), | 742 if (!device_background_texture->Allocate(window_rect.size(), |
623 ResourceProvider::TextureUsageAny, | 743 ResourceProvider::TextureUsageAny, |
enne (OOO)
2013/11/06 22:40:19
It seems like this should be TextureUsageFramebuff
rosca
2013/11/07 01:58:16
Awesome! Done.
| |
624 RGBA_8888)) { | 744 RGBA_8888)) { |
625 return scoped_ptr<ScopedResource>(); | 745 return scoped_ptr<ScopedResource>(); |
626 } else { | 746 } else { |
627 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, | 747 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, |
628 device_background_texture->id()); | 748 device_background_texture->id()); |
629 GetFramebufferTexture(lock.texture_id(), | 749 GetFramebufferTexture(lock.texture_id(), |
630 device_background_texture->format(), | 750 device_background_texture->format(), |
631 window_rect); | 751 window_rect, |
752 is_using_texture_storage_); | |
632 } | 753 } |
633 | 754 |
755 int filtered_device_background_texture_id = 0; | |
634 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | 756 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
635 quad->background_filters, device_background_texture->size()); | 757 quad->background_filters, device_background_texture->size()); |
636 | 758 |
637 SkBitmap filtered_device_background = | 759 SkBitmap filtered_device_background; |
638 ApplyImageFilter(this, | 760 if (apply_background_filters) |
639 frame->offscreen_context_provider, | 761 filtered_device_background = |
640 quad->rect.origin(), | 762 ApplyImageFilter(this, |
641 filter.get(), | 763 frame->offscreen_context_provider, |
642 device_background_texture.get()); | 764 quad->rect.origin(), |
643 if (!filtered_device_background.getTexture()) | 765 filter.get(), |
644 return scoped_ptr<ScopedResource>(); | 766 device_background_texture.get()); |
767 if (background_changed) | |
768 *background_changed = (filtered_device_background.getTexture() != NULL); | |
645 | 769 |
646 GrTexture* texture = | 770 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; |
647 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | 771 if (filtered_device_background.getTexture()) { |
648 int filtered_device_background_texture_id = texture->getTextureHandle(); | 772 GrTexture* texture = |
773 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | |
774 filtered_device_background_texture_id = texture->getTextureHandle(); | |
775 } else { | |
776 lock.reset(new ResourceProvider::ScopedReadLockGL( | |
777 resource_provider_, device_background_texture->id())); | |
778 filtered_device_background_texture_id = lock->texture_id(); | |
779 } | |
649 | 780 |
650 scoped_ptr<ScopedResource> background_texture = | 781 scoped_ptr<ScopedResource> background_texture = |
651 ScopedResource::create(resource_provider_); | 782 ScopedResource::create(resource_provider_); |
652 if (!background_texture->Allocate(quad->rect.size(), | 783 if (!background_texture->Allocate(quad->rect.size(), |
653 ResourceProvider::TextureUsageFramebuffer, | 784 ResourceProvider::TextureUsageFramebuffer, |
654 RGBA_8888)) | 785 RGBA_8888)) |
655 return scoped_ptr<ScopedResource>(); | 786 return scoped_ptr<ScopedResource>(); |
656 | 787 |
657 const RenderPass* target_render_pass = frame->current_render_pass; | 788 const RenderPass* target_render_pass = frame->current_render_pass; |
658 bool using_background_texture = | 789 bool using_background_texture = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
709 gfx::Transform contents_device_transform = | 840 gfx::Transform contents_device_transform = |
710 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 841 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
711 contents_device_transform.FlattenTo2d(); | 842 contents_device_transform.FlattenTo2d(); |
712 | 843 |
713 // Can only draw surface if device matrix is invertible. | 844 // Can only draw surface if device matrix is invertible. |
714 gfx::Transform contents_device_transform_inverse( | 845 gfx::Transform contents_device_transform_inverse( |
715 gfx::Transform::kSkipInitialization); | 846 gfx::Transform::kSkipInitialization); |
716 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 847 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
717 return; | 848 return; |
718 | 849 |
850 bool apply_blend_mode = | |
851 quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode; | |
852 bool background_changed = false; | |
719 scoped_ptr<ScopedResource> background_texture; | 853 scoped_ptr<ScopedResource> background_texture; |
720 if (!quad->background_filters.IsEmpty()) { | 854 if (!quad->background_filters.IsEmpty() || apply_blend_mode) { |
721 // The pixels from the filtered background should completely replace the | 855 // The pixels from the filtered background should completely replace the |
722 // current pixel values. | 856 // current pixel values. |
723 bool disable_blending = blend_enabled(); | 857 bool disable_blending = blend_enabled(); |
724 if (disable_blending) | 858 if (disable_blending) |
725 SetBlendEnabled(false); | 859 SetBlendEnabled(false); |
726 | 860 |
727 background_texture = DrawBackgroundFilters( | 861 background_texture = |
728 frame, | 862 GetBackgroundWithFilters(frame, |
729 quad, | 863 quad, |
730 contents_device_transform, | 864 contents_device_transform, |
731 contents_device_transform_inverse); | 865 contents_device_transform_inverse, |
866 &background_changed); | |
732 | 867 |
733 if (disable_blending) | 868 if (disable_blending) |
734 SetBlendEnabled(true); | 869 SetBlendEnabled(true); |
735 } | 870 } |
736 | 871 |
737 // TODO(senorblanco): Cache this value so that we don't have to do it for both | 872 // 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. | 873 // the surface and its replica. Apply filters to the contents texture. |
739 SkBitmap filter_bitmap; | 874 SkBitmap filter_bitmap; |
740 SkScalar color_matrix[20]; | 875 SkScalar color_matrix[20]; |
741 bool use_color_matrix = false; | 876 bool use_color_matrix = false; |
(...skipping 18 matching lines...) Expand all Loading... | |
760 } else { | 895 } else { |
761 filter_bitmap = ApplyImageFilter(this, | 896 filter_bitmap = ApplyImageFilter(this, |
762 frame->offscreen_context_provider, | 897 frame->offscreen_context_provider, |
763 quad->rect.origin(), | 898 quad->rect.origin(), |
764 filter.get(), | 899 filter.get(), |
765 contents_texture); | 900 contents_texture); |
766 } | 901 } |
767 } | 902 } |
768 } | 903 } |
769 | 904 |
905 if (background_texture && apply_blend_mode) { | |
906 filter_bitmap = | |
907 ApplyBlendModeWithBackdrop(this, | |
908 frame->offscreen_context_provider, | |
909 filter_bitmap, | |
910 contents_texture, | |
911 background_texture.get(), | |
912 quad->shared_quad_state->blend_mode); | |
913 } | |
914 | |
770 // Draw the background texture if there is one. | 915 // Draw the background texture if there is one. |
771 if (background_texture) { | 916 if (background_texture && background_changed) { |
772 DCHECK(background_texture->size() == quad->rect.size()); | 917 DCHECK(background_texture->size() == quad->rect.size()); |
773 ResourceProvider::ScopedReadLockGL lock(resource_provider_, | 918 ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
774 background_texture->id()); | 919 background_texture->id()); |
775 | 920 |
776 // The background_texture is oriented the same as the frame buffer. The | 921 // 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 | 922 // transform we are copying with has a vertical flip, so flip the contents |
778 // in the shader to maintain orientation | 923 // in the shader to maintain orientation |
779 bool flip_vertically = true; | 924 bool flip_vertically = true; |
780 | 925 |
781 CopyTextureToFramebuffer(frame, | 926 CopyTextureToFramebuffer(frame, |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2164 unsigned int texture_id = context_->createTexture(); | 2309 unsigned int texture_id = context_->createTexture(); |
2165 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); | 2310 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); |
2166 GLC(context_, context_->texParameteri( | 2311 GLC(context_, context_->texParameteri( |
2167 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); | 2312 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
2168 GLC(context_, context_->texParameteri( | 2313 GLC(context_, context_->texParameteri( |
2169 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); | 2314 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
2170 GLC(context_, context_->texParameteri( | 2315 GLC(context_, context_->texParameteri( |
2171 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); | 2316 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
2172 GLC(context_, context_->texParameteri( | 2317 GLC(context_, context_->texParameteri( |
2173 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); | 2318 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
2174 GetFramebufferTexture(texture_id, RGBA_8888, window_rect); | 2319 GetFramebufferTexture(texture_id, RGBA_8888, window_rect, false); |
2175 | 2320 |
2176 gpu::Mailbox mailbox; | 2321 gpu::Mailbox mailbox; |
2177 unsigned sync_point = 0; | 2322 unsigned sync_point = 0; |
2178 GLC(context_, context_->genMailboxCHROMIUM(mailbox.name)); | 2323 GLC(context_, context_->genMailboxCHROMIUM(mailbox.name)); |
2179 if (mailbox.IsZero()) { | 2324 if (mailbox.IsZero()) { |
2180 context_->deleteTexture(texture_id); | 2325 context_->deleteTexture(texture_id); |
2181 request->SendEmptyResult(); | 2326 request->SendEmptyResult(); |
2182 return; | 2327 return; |
2183 } | 2328 } |
2184 | 2329 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2255 GLC(context_, context_->texParameteri( | 2400 GLC(context_, context_->texParameteri( |
2256 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); | 2401 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
2257 GLC(context_, context_->texParameteri( | 2402 GLC(context_, context_->texParameteri( |
2258 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); | 2403 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
2259 GLC(context_, context_->texParameteri( | 2404 GLC(context_, context_->texParameteri( |
2260 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); | 2405 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
2261 GLC(context_, context_->texParameteri( | 2406 GLC(context_, context_->texParameteri( |
2262 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); | 2407 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
2263 // Copy the contents of the current (IOSurface-backed) framebuffer into a | 2408 // Copy the contents of the current (IOSurface-backed) framebuffer into a |
2264 // temporary texture. | 2409 // temporary texture. |
2265 GetFramebufferTexture(temporary_texture, | 2410 GetFramebufferTexture( |
2266 RGBA_8888, | 2411 temporary_texture, RGBA_8888, gfx::Rect(current_surface_size_), false); |
2267 gfx::Rect(current_surface_size_)); | |
2268 temporary_fbo = context_->createFramebuffer(); | 2412 temporary_fbo = context_->createFramebuffer(); |
2269 // Attach this texture to an FBO, and perform the readback from that FBO. | 2413 // Attach this texture to an FBO, and perform the readback from that FBO. |
2270 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, temporary_fbo)); | 2414 GLC(context_, context_->bindFramebuffer(GL_FRAMEBUFFER, temporary_fbo)); |
2271 GLC(context_, context_->framebufferTexture2D(GL_FRAMEBUFFER, | 2415 GLC(context_, context_->framebufferTexture2D(GL_FRAMEBUFFER, |
2272 GL_COLOR_ATTACHMENT0, | 2416 GL_COLOR_ATTACHMENT0, |
2273 GL_TEXTURE_2D, | 2417 GL_TEXTURE_2D, |
2274 temporary_texture, | 2418 temporary_texture, |
2275 0)); | 2419 0)); |
2276 | 2420 |
2277 DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE), | 2421 DCHECK_EQ(static_cast<unsigned>(GL_FRAMEBUFFER_COMPLETE), |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2403 scoped_ptr<SkAutoLockPixels> lock, | 2547 scoped_ptr<SkAutoLockPixels> lock, |
2404 scoped_ptr<CopyOutputRequest> request, | 2548 scoped_ptr<CopyOutputRequest> request, |
2405 bool success) { | 2549 bool success) { |
2406 DCHECK(request->force_bitmap_result()); | 2550 DCHECK(request->force_bitmap_result()); |
2407 | 2551 |
2408 lock.reset(); | 2552 lock.reset(); |
2409 if (success) | 2553 if (success) |
2410 request->SendBitmapResult(bitmap.Pass()); | 2554 request->SendBitmapResult(bitmap.Pass()); |
2411 } | 2555 } |
2412 | 2556 |
2413 void GLRenderer::GetFramebufferTexture( | 2557 void GLRenderer::GetFramebufferTexture(unsigned texture_id, |
2414 unsigned texture_id, ResourceFormat texture_format, gfx::Rect window_rect) { | 2558 ResourceFormat texture_format, |
2559 gfx::Rect window_rect, | |
2560 bool is_texture_storage) { | |
2415 DCHECK(texture_id); | 2561 DCHECK(texture_id); |
2416 DCHECK_GE(window_rect.x(), 0); | 2562 DCHECK_GE(window_rect.x(), 0); |
2417 DCHECK_GE(window_rect.y(), 0); | 2563 DCHECK_GE(window_rect.y(), 0); |
2418 DCHECK_LE(window_rect.right(), current_surface_size_.width()); | 2564 DCHECK_LE(window_rect.right(), current_surface_size_.width()); |
2419 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); | 2565 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); |
2420 | 2566 |
2421 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); | 2567 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); |
2422 GLC(context_, | 2568 |
2423 context_->copyTexImage2D( | 2569 // if the texture is allocated using texStorage2DEXT, its structure is |
2424 GL_TEXTURE_2D, | 2570 // immutable and we cannot use copyTexImage2D |
2425 0, | 2571 if (!is_texture_storage) { |
2426 GLDataFormat(texture_format), | 2572 GLC(context_, |
2427 window_rect.x(), | 2573 context_->copyTexImage2D(GL_TEXTURE_2D, |
2428 window_rect.y(), | 2574 0, |
2429 window_rect.width(), | 2575 GLDataFormat(texture_format), |
2430 window_rect.height(), | 2576 window_rect.x(), |
2431 0)); | 2577 window_rect.y(), |
2578 window_rect.width(), | |
2579 window_rect.height(), | |
2580 0)); | |
2581 } else { | |
2582 GLC(context_, | |
2583 context_->copyTexSubImage2D(GL_TEXTURE_2D, | |
2584 0, | |
2585 0, | |
2586 0, | |
2587 window_rect.x(), | |
2588 window_rect.y(), | |
2589 window_rect.width(), | |
2590 window_rect.height())); | |
2591 } | |
2592 | |
2432 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); | 2593 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); |
2433 } | 2594 } |
2434 | 2595 |
2435 bool GLRenderer::UseScopedTexture(DrawingFrame* frame, | 2596 bool GLRenderer::UseScopedTexture(DrawingFrame* frame, |
2436 const ScopedResource* texture, | 2597 const ScopedResource* texture, |
2437 gfx::Rect viewport_rect) { | 2598 gfx::Rect viewport_rect) { |
2438 DCHECK(texture->id()); | 2599 DCHECK(texture->id()); |
2439 frame->current_render_pass = NULL; | 2600 frame->current_render_pass = NULL; |
2440 frame->current_texture = texture; | 2601 frame->current_texture = texture; |
2441 | 2602 |
(...skipping 640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3082 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 3243 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
3083 // implementation. | 3244 // implementation. |
3084 return gr_context_ && context_->getContextAttributes().stencil; | 3245 return gr_context_ && context_->getContextAttributes().stencil; |
3085 } | 3246 } |
3086 | 3247 |
3087 bool GLRenderer::IsContextLost() { | 3248 bool GLRenderer::IsContextLost() { |
3088 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 3249 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
3089 } | 3250 } |
3090 | 3251 |
3091 } // namespace cc | 3252 } // namespace cc |
OLD | NEW |