| /* | |
| * Copyright 2021 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| /** | |
| * This test relies on GLSL ES2 conformance test files, which are not included in Skia. | |
| * | |
| * To run the test suite, open `resources/sksl/es2_conformance/import_conformance_tests.py` and | |
| * follow the instructions at the top to download and import the test suite. | |
| */ | |
| #include "include/core/SkBitmap.h" | |
| #include "include/core/SkCanvas.h" | |
| #include "include/core/SkColor.h" | |
| #include "include/core/SkData.h" | |
| #include "include/core/SkImageInfo.h" | |
| #include "include/core/SkPaint.h" | |
| #include "include/core/SkRect.h" | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/core/SkShader.h" | |
| #include "include/core/SkString.h" | |
| #include "include/core/SkSurface.h" | |
| #include "include/core/SkTypes.h" | |
| #include "include/effects/SkRuntimeEffect.h" | |
| #include "include/gpu/GpuTypes.h" | |
| #include "include/gpu/GrDirectContext.h" | |
| #include "include/gpu/ganesh/SkSurfaceGanesh.h" | |
| #include "src/core/SkOSFile.h" | |
| #include "src/utils/SkOSPath.h" | |
| #include "tests/CtsEnforcement.h" | |
| #include "tests/Test.h" | |
| #include "tools/Resources.h" | |
| #include <functional> | |
| struct GrContextOptions; | |
| static void test_expect_fail(skiatest::Reporter* r, const char* testFile) { | |
| SkRuntimeEffect::Options options{}; | |
| sk_sp<SkData> shaderData = GetResourceAsData(testFile); | |
| if (!shaderData) { | |
| ERRORF(r, "%s: Unable to load file", SkOSPath::Basename(testFile).c_str()); | |
| return; | |
| } | |
| SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()}; | |
| SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options); | |
| if (result.effect) { | |
| ERRORF(r, "%s: Expected failure, but compiled successfully", | |
| SkOSPath::Basename(testFile).c_str()); | |
| return; | |
| } | |
| } | |
| static void test_expect_pass(skiatest::Reporter* r, SkSurface* surface, const char* testFile) { | |
| SkRuntimeEffect::Options options{}; | |
| sk_sp<SkData> shaderData = GetResourceAsData(testFile); | |
| if (!shaderData) { | |
| ERRORF(r, "%s: Unable to load file", testFile); | |
| return; | |
| } | |
| SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()}; | |
| SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options); | |
| if (!result.effect) { | |
| ERRORF(r, "%s: %s", testFile, result.errorText.c_str()); | |
| return; | |
| } | |
| SkRuntimeShaderBuilder builder(result.effect); | |
| sk_sp<SkShader> shader = builder.makeShader(); | |
| if (!shader) { | |
| ERRORF(r, "%s: Unable to build shader", testFile); | |
| return; | |
| } | |
| SkPaint paintShader; | |
| paintShader.setShader(shader); | |
| surface->getCanvas()->drawRect(SkRect::MakeWH(1, 1), paintShader); | |
| SkBitmap bitmap; | |
| REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo())); | |
| REPORTER_ASSERT(r, surface->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), | |
| /*srcX=*/0, /*srcY=*/0)); | |
| SkColor color = bitmap.getColor(0, 0); | |
| if (color != SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00)) { | |
| ERRORF(r, "%s: Expected solid green. Actual:\n" | |
| "RRGGBBAA\n" | |
| "%02X%02X%02X%02X", | |
| testFile, | |
| SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), SkColorGetA(color)); | |
| } | |
| } | |
| static void iterate_dir(const char* directory, const std::function<void(const char*)>& run) { | |
| SkString resourceDirectory = GetResourcePath(directory); | |
| SkOSFile::Iter iter(resourceDirectory.c_str(), ".rts"); | |
| SkString name; | |
| while (iter.next(&name, /*getDir=*/false)) { | |
| SkString path(SkOSPath::Join(directory, name.c_str())); | |
| run(path.c_str()); | |
| } | |
| } | |
| DEF_TEST(SkSL_ES2Conformance_Pass_CPU, r) { | |
| const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
| sk_sp<SkSurface> surface(SkSurfaces::Raster(info)); | |
| iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) { | |
| test_expect_pass(r, surface.get(), path); | |
| }); | |
| } | |
| DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SkSL_ES2Conformance_Pass_GPU, | |
| r, | |
| ctxInfo, | |
| CtsEnforcement::kApiLevel_T) { | |
| const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); | |
| sk_sp<SkSurface> surface( | |
| SkSurfaces::RenderTarget(ctxInfo.directContext(), skgpu::Budgeted::kNo, info)); | |
| iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) { | |
| test_expect_pass(r, surface.get(), path); | |
| }); | |
| } | |
| DEF_TEST(SkSL_ES2Conformance_Fail, r) { | |
| iterate_dir("sksl/es2_conformance/fail/", [&](const char* path) { | |
| test_expect_fail(r, path); | |
| }); | |
| } |