• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 /**
9  * This test relies on GLSL ES2 conformance test files, which are not included in Skia.
10  *
11  * To run the test suite, open `resources/sksl/es2_conformance/import_conformance_tests.py` and
12  * follow the instructions at the top to download and import the test suite.
13  */
14 
15 #include "include/core/SkBitmap.h"
16 #include "include/core/SkCanvas.h"
17 #include "include/core/SkColor.h"
18 #include "include/core/SkData.h"
19 #include "include/core/SkImageInfo.h"
20 #include "include/core/SkPaint.h"
21 #include "include/core/SkRect.h"
22 #include "include/core/SkRefCnt.h"
23 #include "include/core/SkShader.h"
24 #include "include/core/SkString.h"
25 #include "include/core/SkSurface.h"
26 #include "include/core/SkTypes.h"
27 #include "include/effects/SkRuntimeEffect.h"
28 #include "include/gpu/GpuTypes.h"
29 #include "include/gpu/GrDirectContext.h"
30 #include "src/core/SkOSFile.h"
31 #include "src/utils/SkOSPath.h"
32 #include "tests/CtsEnforcement.h"
33 #include "tests/Test.h"
34 #include "tools/Resources.h"
35 
36 #include <functional>
37 
38 struct GrContextOptions;
39 
test_expect_fail(skiatest::Reporter * r,const char * testFile)40 static void test_expect_fail(skiatest::Reporter* r, const char* testFile) {
41     SkRuntimeEffect::Options options{};
42     sk_sp<SkData> shaderData = GetResourceAsData(testFile);
43     if (!shaderData) {
44         ERRORF(r, "%s: Unable to load file", SkOSPath::Basename(testFile).c_str());
45         return;
46     }
47 
48     SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()};
49     SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options);
50     if (result.effect) {
51         ERRORF(r, "%s: Expected failure, but compiled successfully",
52                   SkOSPath::Basename(testFile).c_str());
53         return;
54     }
55 }
56 
test_expect_pass(skiatest::Reporter * r,SkSurface * surface,const char * testFile)57 static void test_expect_pass(skiatest::Reporter* r, SkSurface* surface, const char* testFile) {
58     SkRuntimeEffect::Options options{};
59     sk_sp<SkData> shaderData = GetResourceAsData(testFile);
60     if (!shaderData) {
61         ERRORF(r, "%s: Unable to load file", testFile);
62         return;
63     }
64 
65     SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()};
66     SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options);
67     if (!result.effect) {
68         ERRORF(r, "%s: %s", testFile, result.errorText.c_str());
69         return;
70     }
71 
72     SkRuntimeShaderBuilder builder(result.effect);
73     sk_sp<SkShader> shader = builder.makeShader();
74     if (!shader) {
75         ERRORF(r, "%s: Unable to build shader", testFile);
76         return;
77     }
78 
79     SkPaint paintShader;
80     paintShader.setShader(shader);
81     surface->getCanvas()->drawRect(SkRect::MakeWH(1, 1), paintShader);
82 
83     SkBitmap bitmap;
84     REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo()));
85     REPORTER_ASSERT(r, surface->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(),
86                                            /*srcX=*/0, /*srcY=*/0));
87 
88     SkColor color = bitmap.getColor(0, 0);
89     if (color != SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00)) {
90         ERRORF(r, "%s: Expected solid green. Actual:\n"
91                   "RRGGBBAA\n"
92                   "%02X%02X%02X%02X",
93                   testFile,
94                   SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), SkColorGetA(color));
95     }
96 }
97 
iterate_dir(const char * directory,const std::function<void (const char *)> & run)98 static void iterate_dir(const char* directory, const std::function<void(const char*)>& run) {
99     SkString resourceDirectory = GetResourcePath(directory);
100     SkOSFile::Iter iter(resourceDirectory.c_str(), ".rts");
101     SkString name;
102 
103     while (iter.next(&name, /*getDir=*/false)) {
104         SkString path(SkOSPath::Join(directory, name.c_str()));
105         run(path.c_str());
106     }
107 }
108 
DEF_TEST(SkSL_ES2Conformance_Pass_CPU,r)109 DEF_TEST(SkSL_ES2Conformance_Pass_CPU, r) {
110     const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
111     sk_sp<SkSurface> surface(SkSurface::MakeRaster(info));
112 
113     iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) {
114         test_expect_pass(r, surface.get(), path);
115     });
116 }
117 
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkSL_ES2Conformance_Pass_GPU,r,ctxInfo,CtsEnforcement::kApiLevel_T)118 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkSL_ES2Conformance_Pass_GPU,
119                                        r,
120                                        ctxInfo,
121                                        CtsEnforcement::kApiLevel_T) {
122     const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
123     sk_sp<SkSurface> surface(
124             SkSurface::MakeRenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info));
125     iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) {
126         test_expect_pass(r, surface.get(), path);
127     });
128 }
129 
DEF_TEST(SkSL_ES2Conformance_Fail,r)130 DEF_TEST(SkSL_ES2Conformance_Fail, r) {
131     iterate_dir("sksl/es2_conformance/fail/", [&](const char* path) {
132         test_expect_fail(r, path);
133     });
134 }
135