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 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 // Flush the GL context so rendering results from this context are | 558 // Flush the GL context so rendering results from this context are |
559 // visible in the compositor's context. | 559 // visible in the compositor's context. |
560 offscreen_contexts->Context3d()->flush(); | 560 offscreen_contexts->Context3d()->flush(); |
561 | 561 |
562 // Use the compositor's GL context again. | 562 // Use the compositor's GL context again. |
563 renderer->Context()->makeContextCurrent(); | 563 renderer->Context()->makeContextCurrent(); |
564 | 564 |
565 return device.accessBitmap(false); | 565 return device.accessBitmap(false); |
566 } | 566 } |
567 | 567 |
568 scoped_ptr<ScopedResource> GLRenderer::DrawBackgroundFilters( | 568 static SkBitmap ApplyBlendModeWithBackdrop( |
| 569 GLRenderer* renderer, |
| 570 ContextProvider* offscreen_contexts, |
| 571 SkBitmap source_bitmap_with_filters, |
| 572 ScopedResource* source_texture_resource, |
| 573 ScopedResource* background_texture_resource, |
| 574 SkXfermode::Mode blendMode) { |
| 575 if (!offscreen_contexts || !offscreen_contexts->GrContext()) |
| 576 return source_bitmap_with_filters; |
| 577 |
| 578 DCHECK(background_texture_resource); |
| 579 DCHECK(source_texture_resource); |
| 580 |
| 581 gfx::Size source_size = source_texture_resource->size(); |
| 582 gfx::Size background_size = background_texture_resource->size(); |
| 583 |
| 584 DCHECK_LE(background_size.width(), source_size.width()); |
| 585 DCHECK_LE(background_size.height(), source_size.height()); |
| 586 |
| 587 int source_texture_with_filters_id; |
| 588 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; |
| 589 if (source_bitmap_with_filters.getTexture()) { |
| 590 DCHECK_EQ(source_size.width(), source_bitmap_with_filters.width()); |
| 591 DCHECK_EQ(source_size.height(), source_bitmap_with_filters.height()); |
| 592 GrTexture* texture = |
| 593 reinterpret_cast<GrTexture*>(source_bitmap_with_filters.getTexture()); |
| 594 source_texture_with_filters_id = texture->getTextureHandle(); |
| 595 } else { |
| 596 lock.reset(new ResourceProvider::ScopedReadLockGL( |
| 597 renderer->resource_provider(), source_texture_resource->id())); |
| 598 source_texture_with_filters_id = lock->texture_id(); |
| 599 } |
| 600 |
| 601 ResourceProvider::ScopedReadLockGL lock_background( |
| 602 renderer->resource_provider(), background_texture_resource->id()); |
| 603 |
| 604 // Flush the compositor context to ensure that textures there are available |
| 605 // in the shared context. Do this after locking/creating the compositor |
| 606 // texture. |
| 607 renderer->resource_provider()->Flush(); |
| 608 |
| 609 // Make sure skia uses the correct GL context. |
| 610 offscreen_contexts->Context3d()->makeContextCurrent(); |
| 611 |
| 612 // Wrap the source texture in a Ganesh platform texture. |
| 613 GrBackendTextureDesc backend_texture_description; |
| 614 backend_texture_description.fConfig = kSkia8888_GrPixelConfig; |
| 615 backend_texture_description.fOrigin = kBottomLeft_GrSurfaceOrigin; |
| 616 |
| 617 backend_texture_description.fWidth = source_size.width(); |
| 618 backend_texture_description.fHeight = source_size.height(); |
| 619 backend_texture_description.fTextureHandle = source_texture_with_filters_id; |
| 620 skia::RefPtr<GrTexture> source_texture = |
| 621 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( |
| 622 backend_texture_description)); |
| 623 |
| 624 backend_texture_description.fWidth = background_size.width(); |
| 625 backend_texture_description.fHeight = background_size.height(); |
| 626 backend_texture_description.fTextureHandle = lock_background.texture_id(); |
| 627 skia::RefPtr<GrTexture> background_texture = |
| 628 skia::AdoptRef(offscreen_contexts->GrContext()->wrapBackendTexture( |
| 629 backend_texture_description)); |
| 630 |
| 631 // Place the platform texture inside an SkBitmap. |
| 632 SkBitmap source; |
| 633 source.setConfig( |
| 634 SkBitmap::kARGB_8888_Config, source_size.width(), source_size.height()); |
| 635 skia::RefPtr<SkGrPixelRef> source_pixel_ref = |
| 636 skia::AdoptRef(new SkGrPixelRef(source_texture.get())); |
| 637 source.setPixelRef(source_pixel_ref.get()); |
| 638 |
| 639 SkBitmap background; |
| 640 background.setConfig(SkBitmap::kARGB_8888_Config, |
| 641 background_size.width(), |
| 642 background_size.height()); |
| 643 skia::RefPtr<SkGrPixelRef> background_pixel_ref = |
| 644 skia::AdoptRef(new SkGrPixelRef(background_texture.get())); |
| 645 background.setPixelRef(background_pixel_ref.get()); |
| 646 |
| 647 // Create a scratch texture for backing store. |
| 648 GrTextureDesc desc; |
| 649 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
| 650 desc.fSampleCnt = 0; |
| 651 desc.fWidth = source.width(); |
| 652 desc.fHeight = source.height(); |
| 653 desc.fConfig = kSkia8888_GrPixelConfig; |
| 654 desc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
| 655 GrAutoScratchTexture scratch_texture( |
| 656 offscreen_contexts->GrContext(), desc, GrContext::kExact_ScratchTexMatch); |
| 657 skia::RefPtr<GrTexture> backing_store = |
| 658 skia::AdoptRef(scratch_texture.detach()); |
| 659 |
| 660 // Create a device and canvas using that backing store. |
| 661 SkGpuDevice device(offscreen_contexts->GrContext(), backing_store.get()); |
| 662 SkCanvas canvas(&device); |
| 663 |
| 664 // Draw the source bitmap through the filter to the canvas. |
| 665 canvas.clear(SK_ColorTRANSPARENT); |
| 666 canvas.drawSprite(background, 0, 0); |
| 667 SkPaint paint; |
| 668 paint.setXfermodeMode(blendMode); |
| 669 canvas.drawSprite(source, 0, 0, &paint); |
| 670 |
| 671 // Flush skia context so that all the rendered stuff appears on the |
| 672 // texture. |
| 673 offscreen_contexts->GrContext()->flush(); |
| 674 |
| 675 // Flush the GL context so rendering results from this context are |
| 676 // visible in the compositor's context. |
| 677 offscreen_contexts->Context3d()->flush(); |
| 678 |
| 679 // Use the compositor's GL context again. |
| 680 renderer->Context()->makeContextCurrent(); |
| 681 |
| 682 return device.accessBitmap(false); |
| 683 } |
| 684 |
| 685 scoped_ptr<ScopedResource> GLRenderer::GetBackgroundWithFilters( |
569 DrawingFrame* frame, | 686 DrawingFrame* frame, |
570 const RenderPassDrawQuad* quad, | 687 const RenderPassDrawQuad* quad, |
571 const gfx::Transform& contents_device_transform, | 688 const gfx::Transform& contents_device_transform, |
572 const gfx::Transform& contents_device_transform_inverse) { | 689 const gfx::Transform& contents_device_transform_inverse, |
| 690 bool* background_changed) { |
573 // This method draws a background filter, which applies a filter to any pixels | 691 // 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 | 692 // behind the quad and seen through its background. The algorithm works as |
575 // follows: | 693 // follows: |
576 // 1. Compute a bounding box around the pixels that will be visible through | 694 // 1. Compute a bounding box around the pixels that will be visible through |
577 // the quad. | 695 // the quad. |
578 // 2. Read the pixels in the bounding box into a buffer R. | 696 // 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' | 697 // 3. Apply the background filter to R, so that it is applied in the pixels' |
580 // coordinate space. | 698 // coordinate space. |
581 // 4. Apply the quad's inverse transform to map the pixels in R into the | 699 // 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 | 700 // 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. | 701 // 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 | 702 // 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 | 703 // used to draw the contents itself. This is done without blending to replace |
586 // the current background pixels with the new filtered background. | 704 // the current background pixels with the new filtered background. |
587 // 6. Draw the contents of the quad over drop of the new background with | 705 // 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 | 706 // blending, as per usual. The filtered background pixels will show through |
589 // any non-opaque pixels in this draws. | 707 // any non-opaque pixels in this draws. |
590 // | 708 // |
591 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. | 709 // Pixel copies in this algorithm occur at steps 2, 3, 4, and 5. |
592 | 710 |
593 // TODO(danakj): When this algorithm changes, update | 711 // TODO(danakj): When this algorithm changes, update |
594 // LayerTreeHost::PrioritizeTextures() accordingly. | 712 // LayerTreeHost::PrioritizeTextures() accordingly. |
595 | 713 |
596 // TODO(danakj): We only allow background filters on an opaque render surface | 714 // TODO(danakj): We only allow background filters on an opaque render surface |
597 // because other surfaces may contain translucent pixels, and the contents | 715 // because other surfaces may contain translucent pixels, and the contents |
598 // behind those translucent pixels wouldn't have the filter applied. | 716 // behind those translucent pixels wouldn't have the filter applied. |
599 if (frame->current_render_pass->has_transparent_background) | 717 bool apply_background_filters = |
600 return scoped_ptr<ScopedResource>(); | 718 !frame->current_render_pass->has_transparent_background; |
601 DCHECK(!frame->current_texture); | 719 DCHECK(!frame->current_texture); |
602 | 720 |
603 // TODO(ajuma): Add support for reference filters once | 721 // TODO(ajuma): Add support for reference filters once |
604 // FilterOperations::GetOutsets supports reference filters. | 722 // FilterOperations::GetOutsets supports reference filters. |
605 if (quad->background_filters.HasReferenceFilter()) | 723 if (apply_background_filters && quad->background_filters.HasReferenceFilter()) |
606 return scoped_ptr<ScopedResource>(); | 724 apply_background_filters = false; |
607 | 725 |
608 // TODO(danakj): Do a single readback for both the surface and replica and | 726 // TODO(danakj): Do a single readback for both the surface and replica and |
609 // cache the filtered results (once filter textures are not reused). | 727 // cache the filtered results (once filter textures are not reused). |
610 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( | 728 gfx::Rect window_rect = gfx::ToEnclosingRect(MathUtil::MapClippedRect( |
611 contents_device_transform, SharedGeometryQuad().BoundingBox())); | 729 contents_device_transform, SharedGeometryQuad().BoundingBox())); |
612 | 730 |
613 int top, right, bottom, left; | 731 int top, right, bottom, left; |
614 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); | 732 quad->background_filters.GetOutsets(&top, &right, &bottom, &left); |
615 window_rect.Inset(-left, -top, -right, -bottom); | 733 window_rect.Inset(-left, -top, -right, -bottom); |
616 | 734 |
617 window_rect.Intersect( | 735 window_rect.Intersect( |
618 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); | 736 MoveFromDrawToWindowSpace(frame->current_render_pass->output_rect)); |
619 | 737 |
620 scoped_ptr<ScopedResource> device_background_texture = | 738 scoped_ptr<ScopedResource> device_background_texture = |
621 ScopedResource::create(resource_provider_); | 739 ScopedResource::create(resource_provider_); |
622 if (!device_background_texture->Allocate(window_rect.size(), | 740 if (!device_background_texture->Allocate(window_rect.size(), |
623 ResourceProvider::TextureUsageAny, | 741 ResourceProvider::TextureUsageAny, |
624 RGBA_8888)) { | 742 RGBA_8888)) { |
625 return scoped_ptr<ScopedResource>(); | 743 return scoped_ptr<ScopedResource>(); |
626 } else { | 744 } else { |
627 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, | 745 ResourceProvider::ScopedWriteLockGL lock(resource_provider_, |
628 device_background_texture->id()); | 746 device_background_texture->id()); |
629 GetFramebufferTexture(lock.texture_id(), | 747 GetFramebufferTextureSubImage(lock.texture_id(), window_rect); |
630 device_background_texture->format(), | |
631 window_rect); | |
632 } | 748 } |
633 | 749 |
| 750 int filtered_device_background_texture_id = 0; |
634 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( | 751 skia::RefPtr<SkImageFilter> filter = RenderSurfaceFilters::BuildImageFilter( |
635 quad->background_filters, device_background_texture->size()); | 752 quad->background_filters, device_background_texture->size()); |
636 | 753 |
637 SkBitmap filtered_device_background = | 754 SkBitmap filtered_device_background; |
638 ApplyImageFilter(this, | 755 if (apply_background_filters) |
639 frame->offscreen_context_provider, | 756 filtered_device_background = |
640 quad->rect.origin(), | 757 ApplyImageFilter(this, |
641 filter.get(), | 758 frame->offscreen_context_provider, |
642 device_background_texture.get()); | 759 quad->rect.origin(), |
643 if (!filtered_device_background.getTexture()) | 760 filter.get(), |
644 return scoped_ptr<ScopedResource>(); | 761 device_background_texture.get()); |
| 762 if (background_changed) |
| 763 *background_changed = (filtered_device_background.getTexture() != NULL); |
645 | 764 |
646 GrTexture* texture = | 765 scoped_ptr<ResourceProvider::ScopedReadLockGL> lock; |
647 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); | 766 if (filtered_device_background.getTexture()) { |
648 int filtered_device_background_texture_id = texture->getTextureHandle(); | 767 GrTexture* texture = |
| 768 reinterpret_cast<GrTexture*>(filtered_device_background.getTexture()); |
| 769 filtered_device_background_texture_id = texture->getTextureHandle(); |
| 770 } else { |
| 771 lock.reset(new ResourceProvider::ScopedReadLockGL( |
| 772 resource_provider_, device_background_texture->id())); |
| 773 filtered_device_background_texture_id = lock->texture_id(); |
| 774 } |
649 | 775 |
650 scoped_ptr<ScopedResource> background_texture = | 776 scoped_ptr<ScopedResource> background_texture = |
651 ScopedResource::create(resource_provider_); | 777 ScopedResource::create(resource_provider_); |
652 if (!background_texture->Allocate(quad->rect.size(), | 778 if (!background_texture->Allocate(quad->rect.size(), |
653 ResourceProvider::TextureUsageFramebuffer, | 779 ResourceProvider::TextureUsageFramebuffer, |
654 RGBA_8888)) | 780 RGBA_8888)) |
655 return scoped_ptr<ScopedResource>(); | 781 return scoped_ptr<ScopedResource>(); |
656 | 782 |
657 const RenderPass* target_render_pass = frame->current_render_pass; | 783 const RenderPass* target_render_pass = frame->current_render_pass; |
658 bool using_background_texture = | 784 bool using_background_texture = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 gfx::Transform contents_device_transform = | 835 gfx::Transform contents_device_transform = |
710 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; | 836 frame->window_matrix * frame->projection_matrix * quad_rect_matrix; |
711 contents_device_transform.FlattenTo2d(); | 837 contents_device_transform.FlattenTo2d(); |
712 | 838 |
713 // Can only draw surface if device matrix is invertible. | 839 // Can only draw surface if device matrix is invertible. |
714 gfx::Transform contents_device_transform_inverse( | 840 gfx::Transform contents_device_transform_inverse( |
715 gfx::Transform::kSkipInitialization); | 841 gfx::Transform::kSkipInitialization); |
716 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) | 842 if (!contents_device_transform.GetInverse(&contents_device_transform_inverse)) |
717 return; | 843 return; |
718 | 844 |
| 845 bool apply_blend_mode = |
| 846 quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode; |
| 847 bool background_changed = false; |
719 scoped_ptr<ScopedResource> background_texture; | 848 scoped_ptr<ScopedResource> background_texture; |
720 if (!quad->background_filters.IsEmpty()) { | 849 if (!quad->background_filters.IsEmpty() || apply_blend_mode) { |
721 // The pixels from the filtered background should completely replace the | 850 // The pixels from the filtered background should completely replace the |
722 // current pixel values. | 851 // current pixel values. |
723 bool disable_blending = blend_enabled(); | 852 bool disable_blending = blend_enabled(); |
724 if (disable_blending) | 853 if (disable_blending) |
725 SetBlendEnabled(false); | 854 SetBlendEnabled(false); |
726 | 855 |
727 background_texture = DrawBackgroundFilters( | 856 background_texture = |
728 frame, | 857 GetBackgroundWithFilters(frame, |
729 quad, | 858 quad, |
730 contents_device_transform, | 859 contents_device_transform, |
731 contents_device_transform_inverse); | 860 contents_device_transform_inverse, |
| 861 &background_changed); |
732 | 862 |
733 if (disable_blending) | 863 if (disable_blending) |
734 SetBlendEnabled(true); | 864 SetBlendEnabled(true); |
735 } | 865 } |
736 | 866 |
737 // TODO(senorblanco): Cache this value so that we don't have to do it for both | 867 // 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. | 868 // the surface and its replica. Apply filters to the contents texture. |
739 SkBitmap filter_bitmap; | 869 SkBitmap filter_bitmap; |
740 SkScalar color_matrix[20]; | 870 SkScalar color_matrix[20]; |
741 bool use_color_matrix = false; | 871 bool use_color_matrix = false; |
(...skipping 18 matching lines...) Expand all Loading... |
760 } else { | 890 } else { |
761 filter_bitmap = ApplyImageFilter(this, | 891 filter_bitmap = ApplyImageFilter(this, |
762 frame->offscreen_context_provider, | 892 frame->offscreen_context_provider, |
763 quad->rect.origin(), | 893 quad->rect.origin(), |
764 filter.get(), | 894 filter.get(), |
765 contents_texture); | 895 contents_texture); |
766 } | 896 } |
767 } | 897 } |
768 } | 898 } |
769 | 899 |
| 900 if (background_texture && apply_blend_mode) { |
| 901 filter_bitmap = |
| 902 ApplyBlendModeWithBackdrop(this, |
| 903 frame->offscreen_context_provider, |
| 904 filter_bitmap, |
| 905 contents_texture, |
| 906 background_texture.get(), |
| 907 quad->shared_quad_state->blend_mode); |
| 908 } |
| 909 |
770 // Draw the background texture if there is one. | 910 // Draw the background texture if there is one. |
771 if (background_texture) { | 911 if (background_texture && background_changed) { |
772 DCHECK(background_texture->size() == quad->rect.size()); | 912 DCHECK(background_texture->size() == quad->rect.size()); |
773 ResourceProvider::ScopedReadLockGL lock(resource_provider_, | 913 ResourceProvider::ScopedReadLockGL lock(resource_provider_, |
774 background_texture->id()); | 914 background_texture->id()); |
775 | 915 |
776 // The background_texture is oriented the same as the frame buffer. The | 916 // 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 | 917 // transform we are copying with has a vertical flip, so flip the contents |
778 // in the shader to maintain orientation | 918 // in the shader to maintain orientation |
779 bool flip_vertically = true; | 919 bool flip_vertically = true; |
780 | 920 |
781 CopyTextureToFramebuffer(frame, | 921 CopyTextureToFramebuffer(frame, |
(...skipping 1627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2409 scoped_ptr<SkAutoLockPixels> lock, | 2549 scoped_ptr<SkAutoLockPixels> lock, |
2410 scoped_ptr<CopyOutputRequest> request, | 2550 scoped_ptr<CopyOutputRequest> request, |
2411 bool success) { | 2551 bool success) { |
2412 DCHECK(request->force_bitmap_result()); | 2552 DCHECK(request->force_bitmap_result()); |
2413 | 2553 |
2414 lock.reset(); | 2554 lock.reset(); |
2415 if (success) | 2555 if (success) |
2416 request->SendBitmapResult(bitmap.Pass()); | 2556 request->SendBitmapResult(bitmap.Pass()); |
2417 } | 2557 } |
2418 | 2558 |
| 2559 void GLRenderer::GetFramebufferTextureSubImage(unsigned texture_id, |
| 2560 gfx::Rect window_rect) { |
| 2561 DCHECK(texture_id); |
| 2562 DCHECK_GE(window_rect.x(), 0); |
| 2563 DCHECK_GE(window_rect.y(), 0); |
| 2564 DCHECK_LE(window_rect.right(), current_surface_size_.width()); |
| 2565 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); |
| 2566 |
| 2567 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); |
| 2568 GLC(context_, |
| 2569 context_->copyTexSubImage2D(GL_TEXTURE_2D, |
| 2570 0, |
| 2571 0, |
| 2572 0, |
| 2573 window_rect.x(), |
| 2574 window_rect.y(), |
| 2575 window_rect.width(), |
| 2576 window_rect.height())); |
| 2577 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); |
| 2578 } |
| 2579 |
2419 void GLRenderer::GetFramebufferTexture( | 2580 void GLRenderer::GetFramebufferTexture( |
2420 unsigned texture_id, ResourceFormat texture_format, gfx::Rect window_rect) { | 2581 unsigned texture_id, ResourceFormat texture_format, gfx::Rect window_rect) { |
2421 DCHECK(texture_id); | 2582 DCHECK(texture_id); |
2422 DCHECK_GE(window_rect.x(), 0); | 2583 DCHECK_GE(window_rect.x(), 0); |
2423 DCHECK_GE(window_rect.y(), 0); | 2584 DCHECK_GE(window_rect.y(), 0); |
2424 DCHECK_LE(window_rect.right(), current_surface_size_.width()); | 2585 DCHECK_LE(window_rect.right(), current_surface_size_.width()); |
2425 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); | 2586 DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); |
2426 | 2587 |
2427 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); | 2588 GLC(context_, context_->bindTexture(GL_TEXTURE_2D, texture_id)); |
2428 GLC(context_, | 2589 GLC(context_, |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3088 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas | 3249 // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas |
3089 // implementation. | 3250 // implementation. |
3090 return gr_context_ && context_->getContextAttributes().stencil; | 3251 return gr_context_ && context_->getContextAttributes().stencil; |
3091 } | 3252 } |
3092 | 3253 |
3093 bool GLRenderer::IsContextLost() { | 3254 bool GLRenderer::IsContextLost() { |
3094 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); | 3255 return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
3095 } | 3256 } |
3096 | 3257 |
3097 } // namespace cc | 3258 } // namespace cc |
OLD | NEW |