| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 <functional> | 8 #include <functional> |
| 9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
| 10 #include "SkData.h" | 10 #include "SkData.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 } | 76 } |
| 77 #if SK_SUPPORT_GPU | 77 #if SK_SUPPORT_GPU |
| 78 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { | 78 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { |
| 79 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); | 79 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S
kAlphaType); |
| 80 REPORTER_ASSERT(reporter, nullptr == | 80 REPORTER_ASSERT(reporter, nullptr == |
| 81 SkSurface::MakeRenderTarget(ctxInfo.fGrContext, SkBudgeted::
kNo, info, 0, | 81 SkSurface::MakeRenderTarget(ctxInfo.fGrContext, SkBudgeted::
kNo, info, 0, |
| 82 nullptr)); | 82 nullptr)); |
| 83 } | 83 } |
| 84 #endif | 84 #endif |
| 85 | 85 |
| 86 #if SK_SUPPORT_GPU | |
| 87 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceWrappedTexture, reporter, ctxInfo)
{ | |
| 88 GrGpu* gpu = ctxInfo.fGrContext->getGpu(); | |
| 89 if (!gpu) { | |
| 90 return; | |
| 91 } | |
| 92 | |
| 93 // Test the wrapped factory for SkSurface by creating a backend texture and
then wrap it in | |
| 94 // a SkSurface. | |
| 95 static const int kW = 100; | |
| 96 static const int kH = 100; | |
| 97 static const uint32_t kOrigColor = 0xFFAABBCC; | |
| 98 SkAutoTArray<uint32_t> pixels(kW * kH); | |
| 99 sk_memset32(pixels.get(), kOrigColor, kW * kH); | |
| 100 GrBackendObject texHandle = gpu->createTestingOnlyBackendTexture(pixels.get(
), kW, kH, | |
| 101 kRGBA_8888_
GrPixelConfig); | |
| 102 | |
| 103 GrBackendTextureDesc wrappedDesc; | |
| 104 wrappedDesc.fConfig = kRGBA_8888_GrPixelConfig; | |
| 105 wrappedDesc.fWidth = kW; | |
| 106 wrappedDesc.fHeight = kH; | |
| 107 wrappedDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; | |
| 108 wrappedDesc.fSampleCnt = 0; | |
| 109 wrappedDesc.fFlags = kRenderTarget_GrBackendTextureFlag; | |
| 110 wrappedDesc.fTextureHandle = texHandle; | |
| 111 | |
| 112 auto surface(SkSurface::MakeFromBackendTexture(ctxInfo.fGrContext, wrappedDe
sc, nullptr)); | |
| 113 REPORTER_ASSERT(reporter, surface); | |
| 114 if (surface) { | |
| 115 // Validate that we can draw to the canvas and that the original texture
color is preserved | |
| 116 // in pixels that aren't rendered to via the surface. | |
| 117 SkPaint paint; | |
| 118 static const SkColor kRectColor = ~kOrigColor | 0xFF000000; | |
| 119 paint.setColor(kRectColor); | |
| 120 surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntTo
Scalar(kH)/2), | |
| 121 paint); | |
| 122 SkImageInfo readInfo = SkImageInfo::MakeN32Premul(kW, kH); | |
| 123 surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint32_t), 0, 0)
; | |
| 124 bool stop = false; | |
| 125 SkPMColor origColorPM = SkPackARGB32((kOrigColor >> 24 & 0xFF), | |
| 126 (kOrigColor >> 0 & 0xFF), | |
| 127 (kOrigColor >> 8 & 0xFF), | |
| 128 (kOrigColor >> 16 & 0xFF)); | |
| 129 SkPMColor rectColorPM = SkPackARGB32((kRectColor >> 24 & 0xFF), | |
| 130 (kRectColor >> 16 & 0xFF), | |
| 131 (kRectColor >> 8 & 0xFF), | |
| 132 (kRectColor >> 0 & 0xFF)); | |
| 133 for (int y = 0; y < kH/2 && !stop; ++y) { | |
| 134 for (int x = 0; x < kW && !stop; ++x) { | |
| 135 REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]); | |
| 136 if (rectColorPM != pixels[x + y * kW]) { | |
| 137 stop = true; | |
| 138 } | |
| 139 } | |
| 140 } | |
| 141 stop = false; | |
| 142 for (int y = kH/2; y < kH && !stop; ++y) { | |
| 143 for (int x = 0; x < kW && !stop; ++x) { | |
| 144 REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]); | |
| 145 if (origColorPM != pixels[x + y * kW]) { | |
| 146 stop = true; | |
| 147 } | |
| 148 } | |
| 149 } | |
| 150 } | |
| 151 gpu->deleteTestingOnlyBackendTexture(texHandle); | |
| 152 } | |
| 153 #endif | |
| 154 | |
| 155 static void test_canvas_peek(skiatest::Reporter* reporter, | 86 static void test_canvas_peek(skiatest::Reporter* reporter, |
| 156 sk_sp<SkSurface>& surface, | 87 sk_sp<SkSurface>& surface, |
| 157 const SkImageInfo& requestInfo, | 88 const SkImageInfo& requestInfo, |
| 158 bool expectPeekSuccess) { | 89 bool expectPeekSuccess) { |
| 159 const SkColor color = SK_ColorRED; | 90 const SkColor color = SK_ColorRED; |
| 160 const SkPMColor pmcolor = SkPreMultiplyColor(color); | 91 const SkPMColor pmcolor = SkPreMultiplyColor(color); |
| 161 surface->getCanvas()->clear(color); | 92 surface->getCanvas()->clear(color); |
| 162 | 93 |
| 163 SkPixmap pmap; | 94 SkPixmap pmap; |
| 164 bool success = surface->getCanvas()->peekPixels(&pmap); | 95 bool success = surface->getCanvas()->peekPixels(&pmap); |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 check_rowbytes_remain_consistent(surf1.get(), reporter); | 744 check_rowbytes_remain_consistent(surf1.get(), reporter); |
| 814 | 745 |
| 815 // Try some illegal rowByte values | 746 // Try some illegal rowByte values |
| 816 auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at lea
st 400 | 747 auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at lea
st 400 |
| 817 REPORTER_ASSERT(reporter, nullptr == s); | 748 REPORTER_ASSERT(reporter, nullptr == s); |
| 818 s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large | 749 s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large |
| 819 REPORTER_ASSERT(reporter, nullptr == s); | 750 REPORTER_ASSERT(reporter, nullptr == s); |
| 820 } | 751 } |
| 821 | 752 |
| 822 #if SK_SUPPORT_GPU | 753 #if SK_SUPPORT_GPU |
| 754 static sk_sp<SkSurface> create_gpu_surface_backend_texture( |
| 755 GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTextu
re) { |
| 756 const int kWidth = 10; |
| 757 const int kHeight = 10; |
| 758 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); |
| 759 sk_memset32(pixels.get(), color, kWidth * kHeight); |
| 760 GrBackendTextureDesc desc; |
| 761 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 762 desc.fWidth = kWidth; |
| 763 desc.fHeight = kHeight; |
| 764 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 765 desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture( |
| 766 pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig); |
| 767 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, desc,
nullptr); |
| 768 if (!surface) { |
| 769 context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle); |
| 770 return nullptr; |
| 771 } |
| 772 *outTexture = desc.fTextureHandle; |
| 773 return surface; |
| 774 } |
| 823 | 775 |
| 824 void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface, | 776 static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target( |
| 825 std::function<GrSurface*(SkSurface*)> grSurfaceGetter, | 777 GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTextu
re) { |
| 826 uint32_t expectedValue) { | 778 const int kWidth = 10; |
| 779 const int kHeight = 10; |
| 780 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); |
| 781 sk_memset32(pixels.get(), color, kWidth * kHeight); |
| 782 GrBackendTextureDesc desc; |
| 783 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 784 desc.fWidth = kWidth; |
| 785 desc.fHeight = kHeight; |
| 786 desc.fFlags = kRenderTarget_GrBackendTextureFlag; |
| 787 desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture( |
| 788 pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig); |
| 789 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(c
ontext, desc, |
| 790 n
ullptr); |
| 791 if (!surface) { |
| 792 context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle); |
| 793 return nullptr; |
| 794 } |
| 795 *outTexture = desc.fTextureHandle; |
| 796 return surface; |
| 797 } |
| 798 |
| 799 static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> su
rface, |
| 800 std::function<GrSurface*(SkSurface*)> grSurfaceGe
tter, |
| 801 uint32_t expectedValue) { |
| 827 if (!surface) { | 802 if (!surface) { |
| 828 ERRORF(reporter, "Could not create GPU SkSurface."); | 803 ERRORF(reporter, "Could not create GPU SkSurface."); |
| 829 return; | 804 return; |
| 830 } | 805 } |
| 831 int w = surface->width(); | 806 int w = surface->width(); |
| 832 int h = surface->height(); | 807 int h = surface->height(); |
| 833 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[w * h]); | 808 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[w * h]); |
| 834 memset(pixels.get(), ~expectedValue, sizeof(uint32_t) * w * h); | 809 sk_memset32(pixels.get(), ~expectedValue, w * h); |
| 835 | 810 |
| 836 SkAutoTUnref<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get())))
; | 811 SkAutoTUnref<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get())))
; |
| 837 if (!grSurface) { | 812 if (!grSurface) { |
| 838 ERRORF(reporter, "Could access render target of GPU SkSurface."); | 813 ERRORF(reporter, "Could access render target of GPU SkSurface."); |
| 839 return; | 814 return; |
| 840 } | 815 } |
| 841 surface.reset(); | 816 surface.reset(); |
| 842 grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get()); | 817 grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get()); |
| 843 for (int y = 0; y < h; ++y) { | 818 for (int y = 0; y < h; ++y) { |
| 844 for (int x = 0; x < w; ++x) { | 819 for (int x = 0; x < w; ++x) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 865 [] (SkSurface* s){ | 840 [] (SkSurface* s){ |
| 866 GrDrawContext* dc = s->getCanvas()->internal_private_accessTopLayerD
rawContext(); | 841 GrDrawContext* dc = s->getCanvas()->internal_private_accessTopLayerD
rawContext(); |
| 867 return dc->accessRenderTarget(); }, | 842 return dc->accessRenderTarget(); }, |
| 868 [] (SkSurface* s){ | 843 [] (SkSurface* s){ |
| 869 SkBaseDevice* d = | 844 SkBaseDevice* d = |
| 870 s->getCanvas()->getDevice_just_for_deprecated_compatibility_test
ing(); | 845 s->getCanvas()->getDevice_just_for_deprecated_compatibility_test
ing(); |
| 871 return d->accessRenderTarget(); }, | 846 return d->accessRenderTarget(); }, |
| 872 [] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot()); | 847 [] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot()); |
| 873 return as_IB(i)->peekTexture(); }, | 848 return as_IB(i)->peekTexture(); }, |
| 874 }; | 849 }; |
| 850 |
| 875 for (auto grSurfaceGetter : grSurfaceGetters) { | 851 for (auto grSurfaceGetter : grSurfaceGetters) { |
| 852 // Test that non-wrapped RTs are created clear. |
| 876 for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surf
ace}) { | 853 for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surf
ace}) { |
| 877 auto surface = surface_func(context, kPremul_SkAlphaType, nullptr); | 854 auto surface = surface_func(context, kPremul_SkAlphaType, nullptr); |
| 878 test_surface_clear(reporter, surface, grSurfaceGetter, 0x0); | 855 test_surface_clear(reporter, surface, grSurfaceGetter, 0x0); |
| 879 } | 856 } |
| 880 // Wrapped RTs are *not* supposed to clear (to allow client to partially
update a surface). | 857 // Wrapped RTs are *not* supposed to clear (to allow client to partially
update a surface). |
| 881 static const int kWidth = 10; | 858 // This is applicable only when sample count is 0. Otherwise contents ar
e undefined. |
| 882 static const int kHeight = 10; | 859 const uint32_t kOrigColor = 0xABABABAB; |
| 883 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); | 860 for (auto& surface_func : {&create_gpu_surface_backend_texture, |
| 884 memset(pixels.get(), 0xAB, sizeof(uint32_t) * kWidth * kHeight); | 861 &create_gpu_surface_backend_texture_as_render
_target}) { |
| 885 | 862 GrBackendObject textureObject; |
| 886 GrBackendObject textureObject = | 863 int sampleCnt = 0; |
| 887 context->getGpu()->createTestingOnlyBackendTexture(pixels.get(),
kWidth, kHeight, | 864 auto surface = surface_func(context, sampleCnt, kOrigColor, &texture
Object); |
| 888 kRGBA_8888_Gr
PixelConfig); | 865 test_surface_clear(reporter, surface, grSurfaceGetter, kOrigColor); |
| 889 | 866 surface.reset(); |
| 890 GrBackendTextureDesc desc; | 867 context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); |
| 891 desc.fConfig = kRGBA_8888_GrPixelConfig; | 868 } |
| 892 desc.fWidth = kWidth; | |
| 893 desc.fHeight = kHeight; | |
| 894 desc.fFlags = kRenderTarget_GrBackendTextureFlag; | |
| 895 desc.fTextureHandle = textureObject; | |
| 896 | |
| 897 auto surface = SkSurface::MakeFromBackendTexture(context, desc, nullptr)
; | |
| 898 test_surface_clear(reporter, surface, grSurfaceGetter, 0xABABABAB); | |
| 899 context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); | |
| 900 } | 869 } |
| 901 } | 870 } |
| 902 #endif | 871 #endif |
| 872 |
| 873 #if SK_SUPPORT_GPU |
| 874 static void test_surface_draw_path_triggering_stencil( |
| 875 skiatest::Reporter* reporter, int sampleCnt, sk_sp<SkSurface> surface, |
| 876 uint32_t origColor) { |
| 877 const int kW = surface->width(); |
| 878 const int kH = surface->height(); |
| 879 SkPaint paint; |
| 880 paint.setAntiAlias(true); |
| 881 paint.setColor(SK_ColorGREEN); |
| 882 SkPath clipPath; |
| 883 clipPath.quadTo(SkIntToScalar(kW), SkIntToScalar(0), SkIntToScalar(kW), SkIn
tToScalar(kH)); |
| 884 clipPath.lineTo(SkIntToScalar(0), SkIntToScalar(kH)); |
| 885 clipPath.lineTo(SkIntToScalar(0), SkIntToScalar(0)); |
| 886 clipPath.close(); |
| 887 SkPath path; |
| 888 path.quadTo(SkIntToScalar(0), SkIntToScalar(kH), SkIntToScalar(kW), SkIntToS
calar(kH)); |
| 889 path.lineTo(SkIntToScalar(kW), SkIntToScalar(0)); |
| 890 path.lineTo(SkIntToScalar(0), SkIntToScalar(0)); |
| 891 path.close(); |
| 892 surface->getCanvas()->clipPath(clipPath, SkRegion::kIntersect_Op, true); |
| 893 surface->getCanvas()->drawPath(path, paint); |
| 894 // TODO: verify the drawing in a way that passes all platforms. |
| 895 } |
| 896 |
| 897 static void test_surface_draw_partially( |
| 898 skiatest::Reporter* reporter, sk_sp<SkSurface> surface, uint32_t origColor)
{ |
| 899 const int kW = surface->width(); |
| 900 const int kH = surface->height(); |
| 901 SkPaint paint; |
| 902 const SkColor kRectColor = ~origColor | 0xFF000000; |
| 903 paint.setColor(kRectColor); |
| 904 surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntToScal
ar(kH)/2), |
| 905 paint); |
| 906 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kW * kH]); |
| 907 sk_memset32(pixels.get(), ~origColor, kW * kH); |
| 908 SkImageInfo readInfo = SkImageInfo::MakeN32Premul(kW, kH); |
| 909 SkAssertResult(surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint3
2_t), 0, 0)); |
| 910 bool stop = false; |
| 911 SkPMColor origColorPM = SkPackARGB32((origColor >> 24 & 0xFF), |
| 912 (origColor >> 0 & 0xFF), |
| 913 (origColor >> 8 & 0xFF), |
| 914 (origColor >> 16 & 0xFF)); |
| 915 SkPMColor rectColorPM = SkPackARGB32((kRectColor >> 24 & 0xFF), |
| 916 (kRectColor >> 16 & 0xFF), |
| 917 (kRectColor >> 8 & 0xFF), |
| 918 (kRectColor >> 0 & 0xFF)); |
| 919 for (int y = 0; y < kH/2 && !stop; ++y) { |
| 920 for (int x = 0; x < kW && !stop; ++x) { |
| 921 REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]); |
| 922 if (rectColorPM != pixels[x + y * kW]) { |
| 923 stop = true; |
| 924 } |
| 925 } |
| 926 } |
| 927 stop = false; |
| 928 for (int y = kH/2; y < kH && !stop; ++y) { |
| 929 for (int x = 0; x < kW && !stop; ++x) { |
| 930 REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]); |
| 931 if (origColorPM != pixels[x + y * kW]) { |
| 932 stop = true; |
| 933 } |
| 934 } |
| 935 } |
| 936 } |
| 937 |
| 938 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceWrappedTextureDrawTests, reporter,
ctxInfo) { |
| 939 GrGpu* gpu = ctxInfo.fGrContext->getGpu(); |
| 940 if (!gpu) { |
| 941 return; |
| 942 } |
| 943 static const uint32_t kOrigColor = 0xFFAABBCC; |
| 944 |
| 945 for (auto& surface_func : {&create_gpu_surface_backend_texture, |
| 946 &create_gpu_surface_backend_texture_as_render_tar
get}) { |
| 947 for (int sampleCnt : {0, 4, 8}) { |
| 948 GrBackendObject textureObject; |
| 949 auto surface = surface_func(ctxInfo.fGrContext, sampleCnt, kOrigColo
r, &textureObject); |
| 950 if (!surface) { |
| 951 continue; |
| 952 } |
| 953 // Validate that we can draw paths to a canvas of a surface created
with |
| 954 // SkSurface::MakeFromBackendTextureAsRenderTarget. The code intends
to enforce the use |
| 955 // of stencil buffer. The original bug prevented the creation of ste
ncil buffer, causing |
| 956 // an assert while drawing paths. |
| 957 test_surface_draw_path_triggering_stencil(reporter, sampleCnt, surfa
ce, kOrigColor); |
| 958 surface.reset(); |
| 959 gpu->deleteTestingOnlyBackendTexture(textureObject); |
| 960 } |
| 961 // Validate that we can draw to the canvas and that the original texture
color is |
| 962 // preserved in pixels that aren't rendered to via the surface. |
| 963 // This works only for non-multisampled case. |
| 964 GrBackendObject textureObject; |
| 965 auto surface = surface_func(ctxInfo.fGrContext, 0, kOrigColor, &textureO
bject); |
| 966 if (surface) { |
| 967 test_surface_draw_partially(reporter, surface, kOrigColor); |
| 968 surface.reset(); |
| 969 gpu->deleteTestingOnlyBackendTexture(textureObject); |
| 970 } |
| 971 } |
| 972 } |
| 973 #endif |
| OLD | NEW |