OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "../src/image/SkImagePriv.h" | 8 #include "../src/image/SkImagePriv.h" |
9 #include "../src/image/SkSurface_Base.h" | 9 #include "../src/image/SkSurface_Base.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 return surface->getCanvas()->internal_private_accessTopLayerRenderTarget
()->asTexture(); | 674 return surface->getCanvas()->internal_private_accessTopLayerRenderTarget
()->asTexture(); |
675 } else | 675 } else |
676 #endif | 676 #endif |
677 { | 677 { |
678 return surface->peekPixels(NULL, NULL); | 678 return surface->peekPixels(NULL, NULL); |
679 } | 679 } |
680 } | 680 } |
681 | 681 |
682 static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFac
tory* factory) { | 682 static void TestDeferredCanvasSurface(skiatest::Reporter* reporter, GrContextFac
tory* factory) { |
683 SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10); | 683 SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10); |
684 SkSurface* surface; | |
685 bool useGpu = NULL != factory; | 684 bool useGpu = NULL != factory; |
| 685 int cnt; |
686 #if SK_SUPPORT_GPU | 686 #if SK_SUPPORT_GPU |
687 if (useGpu) { | 687 if (useGpu) { |
688 GrContext* context = factory->get(GrContextFactory::kNative_GLContextTyp
e); | 688 cnt = GrContextFactory::kGLContextTypeCnt; |
689 if (NULL == context) { | |
690 return; | |
691 } | |
692 | |
693 surface = SkSurface::NewRenderTarget(context, imageSpec); | |
694 } else { | 689 } else { |
695 surface = SkSurface::NewRaster(imageSpec); | 690 cnt = 1; |
696 } | 691 } |
697 #else | 692 #else |
698 SkASSERT(!useGpu); | 693 SkASSERT(!useGpu); |
699 surface = SkSurface::NewRaster(imageSpec); | 694 cnt = 1; |
700 #endif | 695 #endif |
701 SkASSERT(NULL != surface); | 696 for (int i = 0; i < cnt; ++i) { |
702 SkAutoTUnref<SkSurface> aur(surface); | 697 SkSurface* surface; |
703 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface)); | 698 #if SK_SUPPORT_GPU |
| 699 if (useGpu) { |
| 700 GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLCon
textType) i; |
| 701 if (!GrContextFactory::IsRenderingGLContext(glCtxType)) { |
| 702 continue; |
| 703 } |
| 704 GrContext* context = factory->get(glCtxType); |
| 705 if (NULL == context) { |
| 706 return; |
| 707 } |
704 | 708 |
705 SkImage* image1 = canvas->newImageSnapshot(); | 709 surface = SkSurface::NewRenderTarget(context, imageSpec); |
706 SkAutoTUnref<SkImage> aur_i1(image1); | 710 } else |
707 PixelPtr pixels1 = get_surface_ptr(surface, useGpu); | 711 #endif |
708 // The following clear would normally trigger a copy on write, but | 712 { |
709 // it won't because rendering is deferred. | 713 surface = SkSurface::NewRaster(imageSpec); |
710 canvas->clear(SK_ColorBLACK); | 714 } |
711 // Obtaining a snapshot directly from the surface (as opposed to the | 715 SkASSERT(NULL != surface); |
712 // SkDeferredCanvas) will not trigger a flush of deferred draw operations | 716 SkAutoTUnref<SkSurface> aur(surface); |
713 // and will therefore return the same image as the previous snapshot. | 717 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface))
; |
714 SkImage* image2 = surface->newImageSnapshot(); | 718 |
715 SkAutoTUnref<SkImage> aur_i2(image2); | 719 SkImage* image1 = canvas->newImageSnapshot(); |
716 // Images identical because of deferral | 720 SkAutoTUnref<SkImage> aur_i1(image1); |
717 REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID()); | 721 PixelPtr pixels1 = get_surface_ptr(surface, useGpu); |
718 // Now we obtain a snpshot via the deferred canvas, which triggers a flush. | 722 // The following clear would normally trigger a copy on write, but |
719 // Because there is a pending clear, this will generate a different image. | 723 // it won't because rendering is deferred. |
720 SkImage* image3 = canvas->newImageSnapshot(); | 724 canvas->clear(SK_ColorBLACK); |
721 SkAutoTUnref<SkImage> aur_i3(image3); | 725 // Obtaining a snapshot directly from the surface (as opposed to the |
722 REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID()); | 726 // SkDeferredCanvas) will not trigger a flush of deferred draw operation
s |
723 // Verify that backing store is now a different buffer because of copy on | 727 // and will therefore return the same image as the previous snapshot. |
724 // write | 728 SkImage* image2 = surface->newImageSnapshot(); |
725 PixelPtr pixels2 = get_surface_ptr(surface, useGpu); | 729 SkAutoTUnref<SkImage> aur_i2(image2); |
726 REPORTER_ASSERT(reporter, pixels1 != pixels2); | 730 // Images identical because of deferral |
727 // Verify copy-on write with a draw operation that gets deferred by | 731 REPORTER_ASSERT(reporter, image1->uniqueID() == image2->uniqueID()); |
728 // the in order draw buffer. | 732 // Now we obtain a snpshot via the deferred canvas, which triggers a flu
sh. |
729 SkPaint paint; | 733 // Because there is a pending clear, this will generate a different imag
e. |
730 canvas->drawPaint(paint); | 734 SkImage* image3 = canvas->newImageSnapshot(); |
731 SkImage* image4 = canvas->newImageSnapshot(); // implicit flush | 735 SkAutoTUnref<SkImage> aur_i3(image3); |
732 SkAutoTUnref<SkImage> aur_i4(image4); | 736 REPORTER_ASSERT(reporter, image1->uniqueID() != image3->uniqueID()); |
733 REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID()); | 737 // Verify that backing store is now a different buffer because of copy o
n |
734 PixelPtr pixels3 = get_surface_ptr(surface, useGpu); | 738 // write |
735 REPORTER_ASSERT(reporter, pixels2 != pixels3); | 739 PixelPtr pixels2 = get_surface_ptr(surface, useGpu); |
736 // Verify that a direct canvas flush with a pending draw does not trigger | 740 REPORTER_ASSERT(reporter, pixels1 != pixels2); |
737 // a copy on write when the surface is not sharing its buffer with an | 741 // Verify copy-on write with a draw operation that gets deferred by |
738 // SkImage. | 742 // the in order draw buffer. |
739 canvas->clear(SK_ColorWHITE); | 743 SkPaint paint; |
740 canvas->flush(); | 744 canvas->drawPaint(paint); |
741 PixelPtr pixels4 = get_surface_ptr(surface, useGpu); | 745 SkImage* image4 = canvas->newImageSnapshot(); // implicit flush |
742 canvas->drawPaint(paint); | 746 SkAutoTUnref<SkImage> aur_i4(image4); |
743 canvas->flush(); | 747 REPORTER_ASSERT(reporter, image4->uniqueID() != image3->uniqueID()); |
744 PixelPtr pixels5 = get_surface_ptr(surface, useGpu); | 748 PixelPtr pixels3 = get_surface_ptr(surface, useGpu); |
745 REPORTER_ASSERT(reporter, pixels4 == pixels5); | 749 REPORTER_ASSERT(reporter, pixels2 != pixels3); |
| 750 // Verify that a direct canvas flush with a pending draw does not trigge
r |
| 751 // a copy on write when the surface is not sharing its buffer with an |
| 752 // SkImage. |
| 753 canvas->clear(SK_ColorWHITE); |
| 754 canvas->flush(); |
| 755 PixelPtr pixels4 = get_surface_ptr(surface, useGpu); |
| 756 canvas->drawPaint(paint); |
| 757 canvas->flush(); |
| 758 PixelPtr pixels5 = get_surface_ptr(surface, useGpu); |
| 759 REPORTER_ASSERT(reporter, pixels4 == pixels5); |
| 760 } |
746 } | 761 } |
747 | 762 |
748 static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
Factory* factory) { | 763 static void TestDeferredCanvasSetSurface(skiatest::Reporter* reporter, GrContext
Factory* factory) { |
749 SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10); | 764 SkImageInfo imageSpec = SkImageInfo::MakeN32Premul(10, 10); |
750 SkSurface* surface; | 765 SkSurface* surface; |
751 SkSurface* alternateSurface; | 766 SkSurface* alternateSurface; |
752 bool useGpu = NULL != factory; | 767 bool useGpu = NULL != factory; |
| 768 int cnt; |
753 #if SK_SUPPORT_GPU | 769 #if SK_SUPPORT_GPU |
754 if (useGpu) { | 770 if (useGpu) { |
755 GrContext* context = factory->get(GrContextFactory::kNative_GLContextTyp
e); | 771 cnt = GrContextFactory::kGLContextTypeCnt; |
756 if (NULL == context) { | |
757 return; | |
758 } | |
759 surface = SkSurface::NewRenderTarget(context, imageSpec); | |
760 alternateSurface = SkSurface::NewRenderTarget(context, imageSpec); | |
761 } else { | 772 } else { |
762 surface = SkSurface::NewRaster(imageSpec); | 773 cnt = 1; |
763 alternateSurface = SkSurface::NewRaster(imageSpec); | |
764 } | 774 } |
765 #else | 775 #else |
766 SkASSERT(!useGpu); | 776 SkASSERT(!useGpu); |
767 surface = SkSurface::NewRaster(imageSpec); | 777 cnt = 1; |
768 alternateSurface = SkSurface::NewRaster(imageSpec); | |
769 #endif | 778 #endif |
770 SkASSERT(NULL != surface); | 779 |
771 SkASSERT(NULL != alternateSurface); | 780 for (int i = 0; i < cnt; ++i) { |
772 SkAutoTUnref<SkSurface> aur1(surface); | 781 #if SK_SUPPORT_GPU |
773 SkAutoTUnref<SkSurface> aur2(alternateSurface); | 782 if (useGpu) { |
774 PixelPtr pixels1 = get_surface_ptr(surface, useGpu); | 783 GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLCon
textType) i; |
775 PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu); | 784 if (!GrContextFactory::IsRenderingGLContext(glCtxType)) { |
776 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface)); | 785 continue; |
777 SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); | 786 } |
778 canvas->setSurface(alternateSurface); | 787 GrContext* context = factory->get(glCtxType); |
779 SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); | 788 if (NULL == context) { |
780 REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID()); | 789 continue; |
781 // Verify that none of the above operations triggered a surface copy on writ
e. | 790 } |
782 REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1); | 791 surface = SkSurface::NewRenderTarget(context, imageSpec); |
783 REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) == pixel
s2); | 792 alternateSurface = SkSurface::NewRenderTarget(context, imageSpec); |
784 // Verify that a flushed draw command will trigger a copy on write on altern
ateSurface. | 793 } else |
785 canvas->clear(SK_ColorWHITE); | 794 #endif |
786 canvas->flush(); | 795 { |
787 REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1); | 796 surface = SkSurface::NewRaster(imageSpec); |
788 REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != pixel
s2); | 797 alternateSurface = SkSurface::NewRaster(imageSpec); |
| 798 } |
| 799 SkASSERT(NULL != surface); |
| 800 SkASSERT(NULL != alternateSurface); |
| 801 SkAutoTUnref<SkSurface> aur1(surface); |
| 802 SkAutoTUnref<SkSurface> aur2(alternateSurface); |
| 803 PixelPtr pixels1 = get_surface_ptr(surface, useGpu); |
| 804 PixelPtr pixels2 = get_surface_ptr(alternateSurface, useGpu); |
| 805 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface))
; |
| 806 SkAutoTUnref<SkImage> image1(canvas->newImageSnapshot()); |
| 807 canvas->setSurface(alternateSurface); |
| 808 SkAutoTUnref<SkImage> image2(canvas->newImageSnapshot()); |
| 809 REPORTER_ASSERT(reporter, image1->uniqueID() != image2->uniqueID()); |
| 810 // Verify that none of the above operations triggered a surface copy on
write. |
| 811 REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1); |
| 812 REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) == p
ixels2); |
| 813 // Verify that a flushed draw command will trigger a copy on write on al
ternateSurface. |
| 814 canvas->clear(SK_ColorWHITE); |
| 815 canvas->flush(); |
| 816 REPORTER_ASSERT(reporter, get_surface_ptr(surface, useGpu) == pixels1); |
| 817 REPORTER_ASSERT(reporter, get_surface_ptr(alternateSurface, useGpu) != p
ixels2); |
| 818 } |
789 } | 819 } |
790 | 820 |
791 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporte
r) { | 821 static void TestDeferredCanvasCreateCompatibleDevice(skiatest::Reporter* reporte
r) { |
792 SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100)); | 822 SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterPMColor(100, 100)); |
793 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()
)); | 823 SkAutoTUnref<SkDeferredCanvas> canvas(SkDeferredCanvas::Create(surface.get()
)); |
794 | 824 |
795 NotificationCounter notificationCounter; | 825 NotificationCounter notificationCounter; |
796 canvas->setNotificationClient(¬ificationCounter); | 826 canvas->setNotificationClient(¬ificationCounter); |
797 | 827 |
798 SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); | 828 SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); |
(...skipping 24 matching lines...) Expand all Loading... |
823 TestDeferredCanvasSurface(reporter, NULL); | 853 TestDeferredCanvasSurface(reporter, NULL); |
824 TestDeferredCanvasSetSurface(reporter, NULL); | 854 TestDeferredCanvasSetSurface(reporter, NULL); |
825 } | 855 } |
826 | 856 |
827 DEF_GPUTEST(DeferredCanvas_GPU, reporter, factory) { | 857 DEF_GPUTEST(DeferredCanvas_GPU, reporter, factory) { |
828 if (factory != NULL) { | 858 if (factory != NULL) { |
829 TestDeferredCanvasSurface(reporter, factory); | 859 TestDeferredCanvasSurface(reporter, factory); |
830 TestDeferredCanvasSetSurface(reporter, factory); | 860 TestDeferredCanvasSetSurface(reporter, factory); |
831 } | 861 } |
832 } | 862 } |
OLD | NEW |