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

Side by Side Diff: tests/SurfaceTest.cpp

Issue 1941353003: Allow stencils to be attached to render targets created via SkSurface::MakeFromBackendTextureAsRend… (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Fix unit tests to avoid ANGLE issues 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/GrGLRenderTarget.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"
11 #include "SkDevice.h" 11 #include "SkDevice.h"
12 #include "SkImage_Base.h" 12 #include "SkImage_Base.h"
13 #include "SkPath.h" 13 #include "SkPath.h"
14 #include "SkRRect.h" 14 #include "SkRRect.h"
15 #include "SkSurface.h" 15 #include "SkSurface.h"
16 #include "SkUtils.h" 16 #include "SkUtils.h"
17 #include "Test.h" 17 #include "Test.h"
18 18
19 #if SK_SUPPORT_GPU 19 #if SK_SUPPORT_GPU
20 #include "GrContext.h" 20 #include "GrContext.h"
21 #include "GrDrawContext.h" 21 #include "GrDrawContext.h"
22 #include "GrGpu.h" 22 #include "GrGpu.h"
23 #include "GrResourceProvider.h"
23 #endif 24 #endif
24 25
25 #include <initializer_list> 26 #include <initializer_list>
26 27
27 static void release_direct_surface_storage(void* pixels, void* context) { 28 static void release_direct_surface_storage(void* pixels, void* context) {
28 SkASSERT(pixels == context); 29 SkASSERT(pixels == context);
29 sk_free(pixels); 30 sk_free(pixels);
30 } 31 }
31 static sk_sp<SkSurface> create_surface(SkAlphaType at = kPremul_SkAlphaType, 32 static sk_sp<SkSurface> create_surface(SkAlphaType at = kPremul_SkAlphaType,
32 SkImageInfo* requestedInfo = nullptr) { 33 SkImageInfo* requestedInfo = nullptr) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 } 77 }
77 #if SK_SUPPORT_GPU 78 #if SK_SUPPORT_GPU
78 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) { 79 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceEmpty_Gpu, reporter, ctxInfo) {
79 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S kAlphaType); 80 const SkImageInfo info = SkImageInfo::Make(0, 0, kN32_SkColorType, kPremul_S kAlphaType);
80 REPORTER_ASSERT(reporter, nullptr == 81 REPORTER_ASSERT(reporter, nullptr ==
81 SkSurface::MakeRenderTarget(ctxInfo.fGrContext, SkBudgeted:: kNo, info, 0, 82 SkSurface::MakeRenderTarget(ctxInfo.fGrContext, SkBudgeted:: kNo, info, 0,
82 nullptr)); 83 nullptr));
83 } 84 }
84 #endif 85 #endif
85 86
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, 87 static void test_canvas_peek(skiatest::Reporter* reporter,
156 sk_sp<SkSurface>& surface, 88 sk_sp<SkSurface>& surface,
157 const SkImageInfo& requestInfo, 89 const SkImageInfo& requestInfo,
158 bool expectPeekSuccess) { 90 bool expectPeekSuccess) {
159 const SkColor color = SK_ColorRED; 91 const SkColor color = SK_ColorRED;
160 const SkPMColor pmcolor = SkPreMultiplyColor(color); 92 const SkPMColor pmcolor = SkPreMultiplyColor(color);
161 surface->getCanvas()->clear(color); 93 surface->getCanvas()->clear(color);
162 94
163 SkPixmap pmap; 95 SkPixmap pmap;
164 bool success = surface->getCanvas()->peekPixels(&pmap); 96 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); 745 check_rowbytes_remain_consistent(surf1.get(), reporter);
814 746
815 // Try some illegal rowByte values 747 // Try some illegal rowByte values
816 auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at lea st 400 748 auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at lea st 400
817 REPORTER_ASSERT(reporter, nullptr == s); 749 REPORTER_ASSERT(reporter, nullptr == s);
818 s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large 750 s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large
819 REPORTER_ASSERT(reporter, nullptr == s); 751 REPORTER_ASSERT(reporter, nullptr == s);
820 } 752 }
821 753
822 #if SK_SUPPORT_GPU 754 #if SK_SUPPORT_GPU
755 static sk_sp<SkSurface> create_gpu_surface_backend_texture(
756 GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTextu re) {
757 const int kWidth = 10;
758 const int kHeight = 10;
759 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]);
760 sk_memset32(pixels.get(), color, kWidth * kHeight);
761 GrBackendTextureDesc desc;
762 desc.fConfig = kRGBA_8888_GrPixelConfig;
763 desc.fWidth = kWidth;
764 desc.fHeight = kHeight;
765 desc.fFlags = kRenderTarget_GrBackendTextureFlag;
766 desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture(
767 pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig);
768 desc.fSampleCnt = sampleCnt;
769 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(context, desc, nullptr);
770 if (!surface) {
771 context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle);
772 return nullptr;
773 }
774 *outTexture = desc.fTextureHandle;
775 return surface;
776 }
823 777
824 void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> surface, 778 static sk_sp<SkSurface> create_gpu_surface_backend_texture_as_render_target(
825 std::function<GrSurface*(SkSurface*)> grSurfaceGetter, 779 GrContext* context, int sampleCnt, uint32_t color, GrBackendObject* outTextu re) {
826 uint32_t expectedValue) { 780 const int kWidth = 10;
781 const int kHeight = 10;
782 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]);
783 sk_memset32(pixels.get(), color, kWidth * kHeight);
784 GrBackendTextureDesc desc;
785 desc.fConfig = kRGBA_8888_GrPixelConfig;
786 desc.fWidth = kWidth;
787 desc.fHeight = kHeight;
788 desc.fFlags = kRenderTarget_GrBackendTextureFlag;
789 desc.fTextureHandle = context->getGpu()->createTestingOnlyBackendTexture(
790 pixels.get(), kWidth, kHeight, kRGBA_8888_GrPixelConfig);
791 desc.fSampleCnt = sampleCnt;
792 sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTextureAsRenderTarget(c ontext, desc,
793 n ullptr);
794 if (!surface) {
795 context->getGpu()->deleteTestingOnlyBackendTexture(desc.fTextureHandle);
796 return nullptr;
797 }
798 *outTexture = desc.fTextureHandle;
799 return surface;
800 }
801
802 static void test_surface_clear(skiatest::Reporter* reporter, sk_sp<SkSurface> su rface,
803 std::function<GrSurface*(SkSurface*)> grSurfaceGe tter,
804 uint32_t expectedValue) {
827 if (!surface) { 805 if (!surface) {
828 ERRORF(reporter, "Could not create GPU SkSurface."); 806 ERRORF(reporter, "Could not create GPU SkSurface.");
829 return; 807 return;
830 } 808 }
831 int w = surface->width(); 809 int w = surface->width();
832 int h = surface->height(); 810 int h = surface->height();
833 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[w * h]); 811 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[w * h]);
834 memset(pixels.get(), ~expectedValue, sizeof(uint32_t) * w * h); 812 sk_memset32(pixels.get(), ~expectedValue, w * h);
835 813
836 SkAutoTUnref<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get()))) ; 814 SkAutoTUnref<GrSurface> grSurface(SkSafeRef(grSurfaceGetter(surface.get()))) ;
837 if (!grSurface) { 815 if (!grSurface) {
838 ERRORF(reporter, "Could access render target of GPU SkSurface."); 816 ERRORF(reporter, "Could access render target of GPU SkSurface.");
839 return; 817 return;
840 } 818 }
841 surface.reset(); 819 surface.reset();
842 grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get()); 820 grSurface->readPixels(0, 0, w, h, kRGBA_8888_GrPixelConfig, pixels.get());
843 for (int y = 0; y < h; ++y) { 821 for (int y = 0; y < h; ++y) {
844 for (int x = 0; x < w; ++x) { 822 for (int x = 0; x < w; ++x) {
845 uint32_t pixel = pixels.get()[y * w + x]; 823 uint32_t pixel = pixels.get()[y * w + x];
846 if (pixel != expectedValue) { 824 if (pixel != expectedValue) {
847 SkString msg; 825 SkString msg;
848 if (expectedValue) { 826 if (expectedValue) {
849 msg = "SkSurface should have left render target unmodified"; 827 msg = "SkSurface should have left render target unmodified";
850 } else { 828 } else {
851 msg = "SkSurface should have cleared the render target"; 829 msg = "SkSurface should have cleared the render target";
852 } 830 }
853 ERRORF(reporter, 831 ERRORF(reporter,
854 "%s but read 0x%08x (instead of 0x%08x) at %x,%d", msg.c_ str(), pixel, 832 "%s but read 0x%08x (instead of 0x%08x) at %x,%d", msg.c_ str(), pixel,
855 expectedValue, x, y); 833 expectedValue, x, y);
856 return; 834 return;
857 } 835 }
858 } 836 }
859 } 837 }
860 } 838 }
861 839
862 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) { 840 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) {
863 GrContext* context = ctxInfo.fGrContext; 841 GrContext* context = ctxInfo.fGrContext;
842
864 std::function<GrSurface*(SkSurface*)> grSurfaceGetters[] = { 843 std::function<GrSurface*(SkSurface*)> grSurfaceGetters[] = {
865 [] (SkSurface* s){ 844 [] (SkSurface* s){
866 GrDrawContext* dc = s->getCanvas()->internal_private_accessTopLayerD rawContext(); 845 GrDrawContext* dc = s->getCanvas()->internal_private_accessTopLayerD rawContext();
867 return dc->accessRenderTarget(); }, 846 return dc->accessRenderTarget(); },
868 [] (SkSurface* s){ 847 [] (SkSurface* s){
869 SkBaseDevice* d = 848 SkBaseDevice* d =
870 s->getCanvas()->getDevice_just_for_deprecated_compatibility_test ing(); 849 s->getCanvas()->getDevice_just_for_deprecated_compatibility_test ing();
871 return d->accessRenderTarget(); }, 850 return d->accessRenderTarget(); },
872 [] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot()); 851 [] (SkSurface* s){ sk_sp<SkImage> i(s->makeImageSnapshot());
873 return as_IB(i)->peekTexture(); }, 852 return as_IB(i)->peekTexture(); }
874 }; 853 };
854
875 for (auto grSurfaceGetter : grSurfaceGetters) { 855 for (auto grSurfaceGetter : grSurfaceGetters) {
856 // Test that non-wrapped RTs are created clear.
876 for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surf ace}) { 857 for (auto& surface_func : {&create_gpu_surface, &create_gpu_scratch_surf ace}) {
877 auto surface = surface_func(context, kPremul_SkAlphaType, nullptr); 858 auto surface = surface_func(context, kPremul_SkAlphaType, nullptr);
878 test_surface_clear(reporter, surface, grSurfaceGetter, 0x0); 859 test_surface_clear(reporter, surface, grSurfaceGetter, 0x0);
879 } 860 }
880 // Wrapped RTs are *not* supposed to clear (to allow client to partially update a surface). 861 // Wrapped RTs are *not* supposed to clear (to allow client to partially update a surface).
881 static const int kWidth = 10; 862 const uint32_t kOrigColor = 0xABABABAB;
882 static const int kHeight = 10; 863 for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
883 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kWidth * kHeight]); 864 &create_gpu_surface_backend_texture_as_render_ target}) {
884 memset(pixels.get(), 0xAB, sizeof(uint32_t) * kWidth * kHeight); 865 GrBackendObject textureObject;
866 auto surface = surfaceFunc(context, 0, kOrigColor, &textureObject);
867 test_surface_clear(reporter, surface, grSurfaceGetter, kOrigColor);
868 surface.reset();
869 context->getGpu()->deleteTestingOnlyBackendTexture(textureObject);
870 }
871 }
872 }
885 873
886 GrBackendObject textureObject = 874 static void test_surface_draw_partially(
887 context->getGpu()->createTestingOnlyBackendTexture(pixels.get(), kWidth, kHeight, 875 skiatest::Reporter* reporter, sk_sp<SkSurface> surface, uint32_t origColor) {
888 kRGBA_8888_Gr PixelConfig); 876 const int kW = surface->width();
877 const int kH = surface->height();
878 SkPaint paint;
879 const SkColor kRectColor = ~origColor | 0xFF000000;
880 paint.setColor(kRectColor);
881 surface->getCanvas()->drawRect(SkRect::MakeWH(SkIntToScalar(kW), SkIntToScal ar(kH)/2),
882 paint);
883 SkAutoTDeleteArray<uint32_t> pixels(new uint32_t[kW * kH]);
884 sk_memset32(pixels.get(), ~origColor, kW * kH);
885 // Read back RGBA to avoid format conversions that may not be supported on a ll platforms.
886 SkImageInfo readInfo = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPr emul_SkAlphaType);
887 SkAssertResult(surface->readPixels(readInfo, pixels.get(), kW * sizeof(uint3 2_t), 0, 0));
888 bool stop = false;
889 SkPMColor origColorPM = SkPackARGB_as_RGBA((origColor >> 24 & 0xFF),
890 (origColor >> 0 & 0xFF),
891 (origColor >> 8 & 0xFF),
892 (origColor >> 16 & 0xFF));
893 SkPMColor rectColorPM = SkPackARGB_as_RGBA((kRectColor >> 24 & 0xFF),
894 (kRectColor >> 16 & 0xFF),
895 (kRectColor >> 8 & 0xFF),
896 (kRectColor >> 0 & 0xFF));
897 for (int y = 0; y < kH/2 && !stop; ++y) {
898 for (int x = 0; x < kW && !stop; ++x) {
899 REPORTER_ASSERT(reporter, rectColorPM == pixels[x + y * kW]);
900 if (rectColorPM != pixels[x + y * kW]) {
901 stop = true;
902 }
903 }
904 }
905 stop = false;
906 for (int y = kH/2; y < kH && !stop; ++y) {
907 for (int x = 0; x < kW && !stop; ++x) {
908 REPORTER_ASSERT(reporter, origColorPM == pixels[x + y * kW]);
909 if (origColorPM != pixels[x + y * kW]) {
910 stop = true;
911 }
912 }
913 }
914 }
889 915
890 GrBackendTextureDesc desc; 916 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfacePartialDraw_Gpu, reporter, ctxInfo) {
891 desc.fConfig = kRGBA_8888_GrPixelConfig; 917 GrGpu* gpu = ctxInfo.fGrContext->getGpu();
892 desc.fWidth = kWidth; 918 if (!gpu) {
893 desc.fHeight = kHeight; 919 return;
894 desc.fFlags = kRenderTarget_GrBackendTextureFlag; 920 }
895 desc.fTextureHandle = textureObject; 921 static const uint32_t kOrigColor = 0xFFAABBCC;
896 922
897 auto surface = SkSurface::MakeFromBackendTexture(context, desc, nullptr) ; 923 for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
898 test_surface_clear(reporter, surface, grSurfaceGetter, 0xABABABAB); 924 &create_gpu_surface_backend_texture_as_render_targ et}) {
899 context->getGpu()->deleteTestingOnlyBackendTexture(textureObject); 925 // Validate that we can draw to the canvas and that the original texture color is
926 // preserved in pixels that aren't rendered to via the surface.
927 // This works only for non-multisampled case.
928 GrBackendObject textureObject;
929 auto surface = surfaceFunc(ctxInfo.fGrContext, 0, kOrigColor, &textureOb ject);
930 if (surface) {
931 test_surface_draw_partially(reporter, surface, kOrigColor);
932 surface.reset();
933 gpu->deleteTestingOnlyBackendTexture(textureObject);
934 }
935 }
936 }
937
938
939 DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceAttachStencil_Gpu, reporter, ctxInf o) {
940 GrGpu* gpu = ctxInfo.fGrContext->getGpu();
941 if (!gpu) {
942 return;
943 }
944 static const uint32_t kOrigColor = 0xFFAABBCC;
945
946 for (auto& surfaceFunc : {&create_gpu_surface_backend_texture,
947 &create_gpu_surface_backend_texture_as_render_targ et}) {
948 for (int sampleCnt : {0, 4, 8}) {
949 GrBackendObject textureObject;
950 auto surface = surfaceFunc(ctxInfo.fGrContext, sampleCnt, kOrigColor , &textureObject);
951
952 if (!surface && sampleCnt > 0) {
953 // Certain platforms don't support MSAA, skip these.
954 continue;
955 }
956
957 // Validate that we can attach a stencil buffer to an SkSurface crea ted by either of
958 // our surface functions.
959 GrRenderTarget* rt = surface->getCanvas()->internal_private_accessTo pLayerDrawContext()
960 ->accessRenderTarget();
961 REPORTER_ASSERT(reporter,
962 ctxInfo.fGrContext->resourceProvider()->attachStenci lAttachment(rt));
963 gpu->deleteTestingOnlyBackendTexture(textureObject);
964 }
900 } 965 }
901 } 966 }
902 #endif 967 #endif
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLRenderTarget.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698