Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(599)

Side by Side Diff: tests/SurfaceTest.cpp

Issue 1924183003: Make stencils be attachable to render targets created via SkSurface::MakeFromBackendTextureAsRender… (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/GrGLGpu.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698