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 585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 596 // Flush the GL context so rendering results from this context are | 596 // Flush the GL context so rendering results from this context are |
| 597 // visible in the compositor's context. | 597 // visible in the compositor's context. |
| 598 offscreen_contexts->Context3d()->flush(); | 598 offscreen_contexts->Context3d()->flush(); |
| 599 | 599 |
| 600 // Use the compositor's GL context again. | 600 // Use the compositor's GL context again. |
| 601 renderer->Context()->makeContextCurrent(); | 601 renderer->Context()->makeContextCurrent(); |
| 602 | 602 |
| 603 return device.accessBitmap(false); | 603 return device.accessBitmap(false); |
| 604 } | 604 } |
| 605 | 605 |
| 606 scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters( | 606 static SkBitmap ApplyBlendModeWithBackdrop(GLRenderer* renderer, |
| 607 ContextProvider* offscreen_contexts, | |
| 608 SkBitmap source_bitmap_with_filters, | |
| 609 ScopedResource* source_texture_resource, | |
| 610 ScopedResource* background_texture_resource, | |
| 611 SkXfermode::Mode blendMode) { | |
| 612 if (!offscreen_contexts || !offscreen_contexts->GrContext()) | |
| 613 return source_bitmap_with_filters; | |
| 614 | |
| 615 DCHECK(background_texture_resource); | |
| 616 DCHECK(source_texture_resource); | |
| 617 | |
| 618 gfx::Size source_size = source_texture_resource->size(); | |
| 619 gfx::Size background_size = background_texture_resource->size(); | |
| 620 | |
| 621 DCHECK_LE(background_size.width(), source_size.width()); | |
| 622 DCHECK_LE(background_size.height(), source_size.height()); | |
| 623 | |
| 624 int source_texture_with_filters_id; | |
| 625 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; | |
| 626 if (source_bitmap_with_filters.getTexture()) { | |
| 627 DCHECK(source_size.width() == source_bitmap_with_filters.width()); | |
| 628 DCHECK(source_size.height() == source_bitmap_with_filters.height()); | |
| 629 GrTexture* texture = | |
| 630 reinterpret_cast<GrTexture*>(source_bitmap_with_filters.getTexture()); | |
| 631 source_texture_with_filters_id = texture->getTextureHandle(); | |
| 632 } else { | |
| 633 lock.reset( | |
| 634 new ResourceProvider::ScopedReadLockGL(renderer->resource_provider(), | |
| 635 source_texture_resource->id())); | |
| 636 source_texture_with_filters_id = lock->texture_id(); | |
| 637 } | |
| 638 | |
| 639 ResourceProvider::ScopedReadLockGL lock_background( | |
| 640 renderer->resource_provider(), background_texture_resource->id()); | |
| 641 | |
| 642 // Flush the compositor context to ensure that textures there are available | |
| 643 // in the shared context. Do this after locking/creating the compositor | |
| 644 // texture. | |
| 645 renderer->resource_provider()->Flush(); | |
| 646 | |
| 647 // Make sure skia uses the correct GL context. | |
| 648 offscreen_contexts->Context3d()->makeContextCurrent(); | |
| 649 | |
| 650 // Wrap the source texture in a Ganesh platform texture. | |
| 651 GrBackendTextureDesc backend_texture_description; | |
| 652 backend_texture_description.fConfig = kSkia8888_GrPixelConfig; | |
| 653 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
| 654 | |
| 655 backend_texture_description.fWidth = source_size.width(); | |
| 656 backend_texture_description.fHeight = source_size.height(); | |
| 657 backend_texture_description.fTextureHandle = source_texture_with_filters_id; | |
| 658 skia::RefPtr<GrTexture> source_texture = | |
| 659 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( | |
| 660 backend_texture_description)); | |
| 661 | |
| 662 backend_texture_description.fWidth = background_size.width(); | |
| 663 backend_texture_description.fHeight = background_size.height(); | |
| 664 backend_texture_description.fTextureHandle = lock_background.texture_id(); | |
| 665 skia::RefPtr<GrTexture> background_texture = | |
| 666 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( | |
| 667 backend_texture_description)); | |
| 668 | |
| 669 // Place the platform texture inside an SkBitmap. | |
| 670 SkBitmap source; | |
| 671 source.setConfig(SkBitmap::kARGB_8888_Config, | |
| 672 source_size.width(), source_size.height()); | |
| 673 skia::RefPtr<SkGrPixelRef> source_pixel_ref = | |
| 674 skia::AdoptRef(new SkGrPixelRef(source_texture.get())); | |
| 675 source.setPixelRef(source_pixel_ref.get()); | |
| 676 | |
| 677 SkBitmap background; | |
| 678 background.setConfig(SkBitmap::kARGB_8888_Config, | |
| 679 background_size.width(), background_size.height()); | |
| 680 skia::RefPtr<SkGrPixelRef> background_pixel_ref = | |
| 681 skia::AdoptRef(new SkGrPixelRef(background_texture.get())); | |
| 682 background.setPixelRef(background_pixel_ref.get()); | |
| 683 | |
| 684 // Create a scratch texture for backing store. | |
| 685 GrTextureDesc desc; | |
| 686 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | |
| 687 desc.fSampleCnt = 0; | |
| 688 desc.fWidth = source.width(); | |
| 689 desc.fHeight = source.height(); | |
| 690 desc.fConfig = kSkia8888_GrPixelConfig; | |
| 691 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
| 692 GrAutoScratchTexture scratch_texture( | |
| 693 offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch); | |
| 694 skia::RefPtr<GrTexture> backing_store = | |
| 695 skia::AdoptRef(scratch_texture.detach()); | |
| 696 | |
| 697 // Create a device and canvas using that backing store. | |
| 698 SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get()); | |
| 699 SkCanvas canvas(&device); | |
| 700 | |
| 701 // Draw the source bitmap through the filter to the canvas. | |
| 702 canvas.clear(SK_ColorTRANSPARENT); | |
| 703 canvas.drawSprite(background, 0, 0); | |
| 704 SkPaint paint; | |
| 705 paint.setXfermodeMode(blendMode); | |
| 706 canvas.drawSprite(source, 0, 0, &paint); | |
| 707 | |
| 708 // Flush skia context so that all the rendered stuff appears on the | |
| 709 // texture. | |
| 710 offscreen_contexts->GrContext()->flush(); | |
| 711 | |
| 712 // Flush the GL context so rendering results from this context are | |
| 713 // visible in the compositor's context. | |
| 714 offscreen_contexts->Context3d()->flush(); | |
| 715 | |
| 716 // Use the compositor's GL context again. | |
| 717 renderer->Context()->makeContextCurrent(); | |
| 718 | |
| 719 return device.accessBitmap(false); | |
| 720 } | |
| 721 | |
| 722 scoped_ptr<ScopedResource> GLRenderer::CreateBackgroundTextureWithFilters( | |
| 607 DrawingFrame* frame, | 723 DrawingFrame* frame, |
| 608 const RenderPassDrawQuad* quad, | 724 const RenderPassDrawQuad* quad, |
| 609 const gfx::Transform& contents_device_transform, | 725 const gfx::Transform& contents_device_transform, |
| 610 const gfx::Transform& contents_device_transform_inverse) { | 726 const gfx::Transform& contents_device_transform_inverse, |
| 727 bool* background_changed) { | |
| 611 // This method draws a background filter, which applies a filter to any pixels | 728 // This method draws a background filter, which applies a filter to any pixels |
| 612 // behind the quad and seen through its background. The algorithm works as | 729 // behind the quad and seen through its background. The algorithm works as |
| 613 // follows: | 730 // follows: |
| 614 // 1. Compute a bounding box around the pixels that will be visible through | 731 // 1. Compute a bounding box around the pixels that will be visible through |
| 615 // the quad. | 732 // the quad. |
| 616 // 2. Read the pixels in the bounding box into a buffer R. | 733 // 2. Read the pixels in the bounding box into a buffer R. |
| 617 // 3. Apply the background filter to R, so that it is applied in the pixels' | 734 // 3. Apply the background filter to R, so that it is applied in the pixels' |
| 618 // coordinate space. | 735 // coordinate space. |
| 619 // 4. Apply the quad's inverse transform to map the pixels in R into the | 736 // 4. Apply the quad's inverse transform to map the pixels in R into the |
| 620 // quad's content space. This implicitly clips R by the content bounds of the | 737 // quad's content space. This implicitly clips R by the content bounds of the |
| 621 // quad since the destination texture has bounds matching the quad's content. | 738 // quad since the destination texture has bounds matching the quad's content. |
| 622 // 5. Draw the background texture for the contents using the same transform as | 739 // 5. Draw the background texture for the contents using the same transform as |
| 623 // used to draw the contents itself. This is done without blending to replace | 740 // used to draw the contents itself. This is done without blending to replace |
| 624 // the current background pixels with the new filtered background. | 741 // the current background pixels with the new filtered background. |
| 625 // 6. Draw the contents of the quad over drop of the new background with | 742 // 6. Draw the contents of the quad over drop of the new background with |
| 626 // blending, as per usual. The filtered background pixels will show through | 743 // blending, as per usual. The filtered background pixels will show through |
| 627 // any non-opaque pixels in this draws. | 744 // any non-opaque pixels in this draws. |
| 628 // | 745 // |
| 629 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. | 746 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. |
| 630 | 747 |
| 631 // TODO(danakj): When this algorithm changes, update | 748 // TODO(danakj): When this algorithm changes, update |
| 632 // LayerTreeHost::PrioritizeTextures() accordingly. | 749 // LayerTreeHost::PrioritizeTextures() accordingly. |
| 633 | 750 |
| 634 FilterOperations filters = | 751 FilterOperations filters = |
| 635 RenderSurfaceFilters::Optimize(quad->background_filters); | 752 RenderSurfaceFilters::Optimize(quad->background_filters); |
| 636 DCHECK(!filters.IsEmpty()); | 753 DCHECK(!filters.IsEmpty() || |
| 754 quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode); | |
| 637 | 755 |
| 638 // TODO(danakj): We only allow background filters on an opaque render surface | 756 // TODO(danakj): We only allow background filters on an opaque render surface |
| 639 // because other surfaces may contain translucent pixels, and the contents | 757 // because other surfaces may contain translucent pixels, and the contents |
| 640 // behind those translucent pixels wouldn't have the filter applied. | 758 // behind those translucent pixels wouldn't have the filter applied. |
| 641 if (frame->current_render_pass->has_transparent_background) | 759 bool apply_background_filters = !filters.IsEmpty() && |
|
enne (OOO)
2013/09/26 16:25:13
How does this TODO not apply to this path as well?
rosca
2013/09/27 10:39:06
Blend modes should work with transparent pixels. B
enne (OOO)
2013/09/27 17:42:33
Ah, I think there may be some confusion here. Her
rosca
2013/09/30 17:28:36
According to the spec, an element having a blend m
enne (OOO)
2013/09/30 21:26:52
I think that is true only if S is also a stacking
| |
| 642 return scoped_ptr<ScopedResource>(); | 760 !frame->current_render_pass->has_transparent_background; |
| 643 DCHECK(!frame->current_texture); | 761 DCHECK(!frame->current_texture); |
| 644 | 762 |
| 645 // TODO(danakj): Do a single readback for both the surface and replica and | 763 // TODO(danakj): Do a single readback for both the surface and replica and |
| 646 // cache the filtered results (once filter textures are not reused). | 764 // cache the filtered results (once filter textures are not reused). |
| 647 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 765 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
| 648 contents_device_transform, SharedGeometryQuad().BoundingBox())); | 766 contents_device_transform, SharedGeometryQuad().BoundingBox())); |
| 649 | 767 |
| 650 int top, right, bottom, left; | 768 int top, right, bottom, left; |
| 651 filters.GetOutsets(&top, &right, &bottom, &left); | 769 filters.GetOutsets(&top, &right, &bottom, &left); |
| 652 window_rect.Inset(-left, -top, -right, -bottom); | 770 window_rect.Inset(-left, -top, -right, -bottom); |
| 653 | 771 |
| 654 window_rect.Intersect( | 772 window_rect.Intersect( |
| 655 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); | 773 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); |
| 656 | 774 |
| 657 scoped_ptr<ScopedResource> device_background_texture = | 775 scoped_ptr<ScopedResource> device_background_texture = |
| 658 ScopedResource::create(resource_provider_); | 776 ScopedResource::create(resource_provider_); |
| 659 if (!device_background_texture->Allocate(window_rect.size(), | 777 if (!device_background_texture->Allocate(window_rect.size(), |
| 660 ResourceProvider::TextureUsageAny, | 778 ResourceProvider::TextureUsageAny, |
| 661 RGBA_8888)) { | 779 RGBA_8888)) { |
| 662 return scoped_ptr<ScopedResource>(); | 780 return scoped_ptr<ScopedResource>(); |
| 663 } else { | 781 } else { |
| 664 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, | 782 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, |
| 665 device_background_texture->id()); | 783 device_background_texture->id()); |
| 666 GetFramebufferTexture(lock.texture_id(), | 784 GetFramebufferTextureSubImage(lock.texture_id(), |
|
enne (OOO)
2013/09/26 16:25:13
This new function seems unnecessary if you are alw
rosca
2013/09/27 10:39:06
The reason I added this function besides GetFrameb
| |
| 667 device_background_texture->format(), | 785 gfx::Point(), |
| 668 window_rect); | 786 window_rect); |
| 669 } | 787 } |
| 670 | 788 |
| 671 SkBitmap filtered_device_background = | 789 int filtered_device_background_texture_id = 0; |
| 672 ApplyFilters(this, | |
| 673 frame->offscreen_context_provider, | |
| 674 filters, | |
| 675 device_background_texture.get()); | |
| 676 if (!filtered_device_background.getTexture()) | |
| 677 return scoped_ptr<ScopedResource>(); | |
| 678 | 790 |
| 679 GrTexture* texture = | 791 SkBitmap filtered_device_background; |
| 680 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | 792 if (apply_background_filters) |
| 681 int filtered_device_background_texture_id = texture->getTextureHandle(); | 793 filtered_device_background = ApplyFilters(this, |
| 794 frame->offscreen_context_provider, filters, | |
| 795 device_background_texture.get()); | |
| 796 if (background_changed) | |
| 797 *background_changed = filtered_device_background.getTexture(); | |
| 798 | |
| 799 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; | |
| 800 if (filtered_device_background.getTexture()) { | |
| 801 GrTexture* texture = | |
| 802 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | |
| 803 filtered_device_background_texture_id = texture->getTextureHandle(); | |
| 804 } else { | |
| 805 lock.reset(new ResourceProvider::ScopedReadLockGL(resource_provider_, | |
| 806 device_background_texture->id())); | |
| 807 filtered_device_background_texture_id = lock->texture_id(); | |
| 808 } | |
| 682 | 809 |
| 683 scoped_ptr<ScopedResource> background_texture = | 810 scoped_ptr<ScopedResource> background_texture = |
| 684 ScopedResource::create(resource_provider_); | 811 ScopedResource::create(resource_provider_); |
| 685 if (!background_texture->Allocate(quad->rect.size(), | 812 if (!background_texture->Allocate(quad->rect.size(), |
| 686 ResourceProvider::TextureUsageFramebuffer, | 813 ResourceProvider::TextureUsageFramebuffer, |
| 687 RGBA_8888)) | 814 RGBA_8888)) |
| 688 return scoped_ptr<ScopedResource>(); | 815 return scoped_ptr<ScopedResource>(); |
| 689 | 816 |
| 690 const RenderPass* target_render_pass = frame->current_render_pass; | 817 const RenderPass* target_render_pass = frame->current_render_pass; |
| 691 bool using_background_texture = | 818 bool using_background_texture = |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 742 gfx::Transform contents_device_transform = | 869 gfx::Transform contents_device_transform = |
| 743 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 870 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
| 744 contents_device_transform.FlattenTo2d(); | 871 contents_device_transform.FlattenTo2d(); |
| 745 | 872 |
| 746 // Can only draw surface if device matrix is invertible. | 873 // Can only draw surface if device matrix is invertible. |
| 747 gfx::Transform contents_device_transform_inverse( | 874 gfx::Transform contents_device_transform_inverse( |
| 748 gfx::Transform::kSkipInitialization); | 875 gfx::Transform::kSkipInitialization); |
| 749 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 876 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
| 750 return; | 877 return; |
| 751 | 878 |
| 879 bool applyBlendMode = | |
| 880 quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode; | |
| 881 bool backgroundChanged = false; | |
| 752 scoped_ptr<ScopedResource> background_texture; | 882 scoped_ptr<ScopedResource> background_texture; |
| 753 if (!quad->background_filters.IsEmpty()) { | 883 if (!quad->background_filters.IsEmpty() || applyBlendMode) { |
| 754 // The pixels from the filtered background should completely replace the | 884 // The pixels from the filtered background should completely replace the |
| 755 // current pixel values. | 885 // current pixel values. |
| 756 bool disable_blending = blend_enabled(); | 886 bool disable_blending = blend_enabled(); |
| 757 if (disable_blending) | 887 if (disable_blending) |
| 758 SetBlendEnabled(false); | 888 SetBlendEnabled(false); |
| 759 | 889 |
| 760 background_texture = DrawBackgroundFilters( | 890 background_texture = CreateBackgroundTextureWithFilters( |
|
enne (OOO)
2013/09/26 16:25:13
This function seems incorrectly named at this poin
rosca
2013/09/27 10:39:06
I changed it to GetBackgroundWithFilters, would th
enne (OOO)
2013/09/27 17:42:33
It's the "filters" part that seems like the misnom
rosca
2013/09/30 17:28:36
Do you mean that I should make it something like "
| |
| 761 frame, | 891 frame, |
| 762 quad, | 892 quad, |
| 763 contents_device_transform, | 893 contents_device_transform, |
| 764 contents_device_transform_inverse); | 894 contents_device_transform_inverse, |
| 895 &backgroundChanged); | |
| 765 | 896 |
| 766 if (disable_blending) | 897 if (disable_blending) |
| 767 SetBlendEnabled(true); | 898 SetBlendEnabled(true); |
| 768 } | 899 } |
| 769 | 900 |
| 770 // TODO(senorblanco): Cache this value so that we don't have to do it for both | 901 // TODO(senorblanco): Cache this value so that we don't have to do it for both |
| 771 // the surface and its replica. Apply filters to the contents texture. | 902 // the surface and its replica. Apply filters to the contents texture. |
| 772 SkBitmap filter_bitmap; | 903 SkBitmap filter_bitmap; |
| 773 SkScalar color_matrix[20]; | 904 SkScalar color_matrix[20]; |
| 774 bool use_color_matrix = false; | 905 bool use_color_matrix = false; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 802 color_matrix, optimized_filters.at(0).matrix(), sizeof(color_matrix)); | 933 color_matrix, optimized_filters.at(0).matrix(), sizeof(color_matrix)); |
| 803 use_color_matrix = true; | 934 use_color_matrix = true; |
| 804 } else { | 935 } else { |
| 805 filter_bitmap = ApplyFilters(this, | 936 filter_bitmap = ApplyFilters(this, |
| 806 frame->offscreen_context_provider, | 937 frame->offscreen_context_provider, |
| 807 optimized_filters, | 938 optimized_filters, |
| 808 contents_texture); | 939 contents_texture); |
| 809 } | 940 } |
| 810 } | 941 } |
| 811 | 942 |
| 943 if (background_texture && applyBlendMode) { | |
| 944 filter_bitmap = ApplyBlendModeWithBackdrop(this, | |
| 945 frame->offscreen_context_provider, | |
| 946 filter_bitmap, | |
| 947 contents_texture, | |
| 948 background_texture.get(), | |
| 949 quad->shared_quad_state->blend_mode); | |
| 950 } | |
| 951 | |
| 812 // Draw the background texture if there is one. | 952 // Draw the background texture if there is one. |
| 813 if (background_texture) { | 953 if (background_texture && backgroundChanged) { |
| 814 DCHECK(background_texture->size() == quad->rect.size()); | 954 DCHECK(background_texture->size() == quad->rect.size()); |
| 815 ResourceProvider::ScopedReadLockGL lock(resource_provider_, | 955 ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
| 816 background_texture->id()); | 956 background_texture->id()); |
| 817 | 957 |
| 818 // The background_texture is oriented the same as the frame buffer. The | 958 // The background_texture is oriented the same as the frame buffer. The |
| 819 // transform we are copying with has a vertical flip, so flip the contents | 959 // transform we are copying with has a vertical flip, so flip the contents |
| 820 // in the shader to maintain orientation | 960 // in the shader to maintain orientation |
| 821 bool flip_vertically = true; | 961 bool flip_vertically = true; |
| 822 | 962 |
| 823 CopyTextureToFramebuffer(frame, | 963 CopyTextureToFramebuffer(frame, |
| (...skipping 1629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2453 scoped_ptr<SkAutoLockPixels> lock, | 2593 scoped_ptr<SkAutoLockPixels> lock, |
| 2454 scoped_ptr<CopyOutputRequest> request, | 2594 scoped_ptr<CopyOutputRequest> request, |
| 2455 bool success) { | 2595 bool success) { |
| 2456 DCHECK(request->force_bitmap_result()); | 2596 DCHECK(request->force_bitmap_result()); |
| 2457 | 2597 |
| 2458 lock.reset(); | 2598 lock.reset(); |
| 2459 if (success) | 2599 if (success) |
| 2460 request->SendBitmapResult(bitmap.Pass()); | 2600 request->SendBitmapResult(bitmap.Pass()); |
| 2461 } | 2601 } |
| 2462 | 2602 |
| 2603 void GLRenderer::GetFramebufferTextureSubImage(unsigned texture_id, | |
| 2604 gfx::Point offset, | |
| 2605 gfx::Rect window_rect) { | |
| 2606 DCHECK(texture_id); | |
| 2607 DCHECK_GE(window_rect.x(), 0); | |
| 2608 DCHECK_GE(window_rect.y(), 0); | |
| 2609 DCHECK_LE(window_rect.right(), current_surface_size_.width()); | |
| 2610 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); | |
| 2611 | |
| 2612 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); | |
| 2613 GLC(context_, | |
| 2614 context_->copyTexSubImage2D(GL_TEXTURE_2D, | |
| 2615 0, | |
| 2616 offset.x(), | |
| 2617 offset.y(), | |
| 2618 window_rect.x(), | |
| 2619 window_rect.y(), | |
| 2620 window_rect.width(), | |
| 2621 window_rect.height())); | |
| 2622 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); | |
| 2623 } | |
| 2624 | |
| 2463 void GLRenderer::GetFramebufferTexture( | 2625 void GLRenderer::GetFramebufferTexture( |
| 2464 unsigned texture_id, ResourceFormat texture_format, gfx::Rect window_rect) { | 2626 unsigned texture_id, ResourceFormat texture_format, gfx::Rect window_rect) { |
| 2465 DCHECK(texture_id); | 2627 DCHECK(texture_id); |
| 2466 DCHECK_GE(window_rect.x(), 0); | 2628 DCHECK_GE(window_rect.x(), 0); |
| 2467 DCHECK_GE(window_rect.y(), 0); | 2629 DCHECK_GE(window_rect.y(), 0); |
| 2468 DCHECK_LE(window_rect.right(), current_surface_size_.width()); | 2630 DCHECK_LE(window_rect.right(), current_surface_size_.width()); |
| 2469 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); | 2631 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); |
| 2470 | 2632 |
| 2471 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); | 2633 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); |
| 2472 GLC(context_, | 2634 GLC(context_, |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3132 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 3294 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
| 3133 // implementation. | 3295 // implementation. |
| 3134 return gr_context_ && context_->getContextAttributes().stencil; | 3296 return gr_context_ && context_->getContextAttributes().stencil; |
| 3135 } | 3297 } |
| 3136 | 3298 |
| 3137 bool GLRenderer::IsContextLost() { | 3299 bool GLRenderer::IsContextLost() { |
| 3138 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 3300 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
| 3139 } | 3301 } |
| 3140 | 3302 |
| 3141 } // namespace cc | 3303 } // namespace cc |
| OLD | NEW |