| 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 |