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 "gm/gm.h" 16#include "include/core/SkBitmap.h" 17#include "include/core/SkCanvas.h" 18#include "include/core/SkData.h" 19#include "include/core/SkFont.h" 20#include "include/core/SkPaint.h" 21#include "include/core/SkSize.h" 22#include "include/core/SkString.h" 23#include "include/core/SkStringView.h" 24#include "include/core/SkSurface.h" 25#include "include/effects/SkGradientShader.h" 26#include "include/effects/SkImageFilters.h" 27#include "include/effects/SkRuntimeEffect.h" 28#include "include/utils/SkRandom.h" 29#include "src/core/SkOSFile.h" 30#include "src/core/SkRuntimeEffectPriv.h" 31#include "src/gpu/GrCaps.h" 32#include "src/gpu/GrDirectContextPriv.h" 33#include "src/utils/SkOSPath.h" 34#include "tests/Test.h" 35#include "tools/Resources.h" 36#include "tools/ToolUtils.h" 37 38static void test_expect_fail(skiatest::Reporter* r, const char* testFile) { 39 SkRuntimeEffect::Options options{}; 40 sk_sp<SkData> shaderData = GetResourceAsData(testFile); 41 if (!shaderData) { 42 ERRORF(r, "%s: Unable to load file", SkOSPath::Basename(testFile).c_str()); 43 return; 44 } 45 46 SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()}; 47 SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options); 48 if (result.effect) { 49 ERRORF(r, "%s: Expected failure, but compiled successfully", 50 SkOSPath::Basename(testFile).c_str()); 51 return; 52 } 53} 54 55static void test_expect_pass(skiatest::Reporter* r, SkSurface* surface, const char* testFile) { 56 SkRuntimeEffect::Options options{}; 57 sk_sp<SkData> shaderData = GetResourceAsData(testFile); 58 if (!shaderData) { 59 ERRORF(r, "%s: Unable to load file", testFile); 60 return; 61 } 62 63 SkString shaderString{reinterpret_cast<const char*>(shaderData->bytes()), shaderData->size()}; 64 SkRuntimeEffect::Result result = SkRuntimeEffect::MakeForShader(shaderString, options); 65 if (!result.effect) { 66 ERRORF(r, "%s: %s", testFile, result.errorText.c_str()); 67 return; 68 } 69 70 SkRuntimeShaderBuilder builder(result.effect); 71 sk_sp<SkShader> shader = builder.makeShader(/*localMatrix=*/nullptr, /*isOpaque=*/true); 72 if (!shader) { 73 ERRORF(r, "%s: Unable to build shader", testFile); 74 return; 75 } 76 77 SkPaint paintShader; 78 paintShader.setShader(shader); 79 surface->getCanvas()->drawRect(SkRect::MakeWH(1, 1), paintShader); 80 81 SkBitmap bitmap; 82 REPORTER_ASSERT(r, bitmap.tryAllocPixels(surface->imageInfo())); 83 REPORTER_ASSERT(r, surface->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 84 /*srcX=*/0, /*srcY=*/0)); 85 86 SkColor color = bitmap.getColor(0, 0); 87 if (color != SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00)) { 88 ERRORF(r, "%s: Expected solid green. Actual:\n" 89 "RRGGBBAA\n" 90 "%02X%02X%02X%02X", 91 testFile, 92 SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), SkColorGetA(color)); 93 } 94} 95 96static void iterate_dir(const char* directory, const std::function<void(const char*)>& run) { 97 SkString resourceDirectory = GetResourcePath(directory); 98 SkOSFile::Iter iter(resourceDirectory.c_str(), ".rts"); 99 SkString name; 100 101 while (iter.next(&name, /*getDir=*/false)) { 102 SkString path(SkOSPath::Join(directory, name.c_str())); 103 run(path.c_str()); 104 } 105} 106 107DEF_TEST(SkSL_ES2Conformance_Pass_CPU, r) { 108 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); 109 sk_sp<SkSurface> surface(SkSurface::MakeRaster(info)); 110 111 iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) { 112 test_expect_pass(r, surface.get(), path); 113 }); 114} 115 116DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkSL_ES2Conformance_Pass_GPU, r, ctxInfo) { 117 const SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); 118 sk_sp<SkSurface> surface(SkSurface::MakeRenderTarget(ctxInfo.directContext(), 119 SkBudgeted::kNo, info)); 120 iterate_dir("sksl/es2_conformance/pass/", [&](const char* path) { 121 test_expect_pass(r, surface.get(), path); 122 }); 123} 124 125DEF_TEST(SkSL_ES2Conformance_Fail, r) { 126 iterate_dir("sksl/es2_conformance/fail/", [&](const char* path) { 127 test_expect_fail(r, path); 128 }); 129} 130