Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: cc/output/gl_renderer.cc

Issue 23455060: mix-blend-mode implementation for accelerated layers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing comments #40 Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698