1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 9cb93a386Sopenharmony_ci#include "include/core/SkSurface.h" 10cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrCaps.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrImageInfo.h" 14cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 15cb93a386Sopenharmony_ci#include "src/gpu/SurfaceContext.h" 16cb93a386Sopenharmony_ci#include "tests/Test.h" 17cb93a386Sopenharmony_ci#include "tests/TestUtils.h" 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci// using anonymous namespace because these functions are used as template params. 20cb93a386Sopenharmony_cinamespace { 21cb93a386Sopenharmony_ci/** convert 0..1 srgb value to 0..1 linear */ 22cb93a386Sopenharmony_cifloat srgb_to_linear(float srgb) { 23cb93a386Sopenharmony_ci if (srgb <= 0.04045f) { 24cb93a386Sopenharmony_ci return srgb / 12.92f; 25cb93a386Sopenharmony_ci } else { 26cb93a386Sopenharmony_ci return powf((srgb + 0.055f) / 1.055f, 2.4f); 27cb93a386Sopenharmony_ci } 28cb93a386Sopenharmony_ci} 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci/** convert 0..1 linear value to 0..1 srgb */ 31cb93a386Sopenharmony_cifloat linear_to_srgb(float linear) { 32cb93a386Sopenharmony_ci if (linear <= 0.0031308) { 33cb93a386Sopenharmony_ci return linear * 12.92f; 34cb93a386Sopenharmony_ci } else { 35cb93a386Sopenharmony_ci return 1.055f * powf(linear, 1.f / 2.4f) - 0.055f; 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci} // namespace 39cb93a386Sopenharmony_ci 40cb93a386Sopenharmony_ci/** tests a conversion with an error tolerance */ 41cb93a386Sopenharmony_citemplate <float (*CONVERT)(float)> static bool check_conversion(uint32_t input, uint32_t output, 42cb93a386Sopenharmony_ci float error) { 43cb93a386Sopenharmony_ci // alpha should always be exactly preserved. 44cb93a386Sopenharmony_ci if ((input & 0xff000000) != (output & 0xff000000)) { 45cb93a386Sopenharmony_ci return false; 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci for (int c = 0; c < 3; ++c) { 49cb93a386Sopenharmony_ci uint8_t inputComponent = (uint8_t) ((input & (0xff << (c*8))) >> (c*8)); 50cb93a386Sopenharmony_ci float lower = std::max(0.f, (float) inputComponent - error); 51cb93a386Sopenharmony_ci float upper = std::min(255.f, (float) inputComponent + error); 52cb93a386Sopenharmony_ci lower = CONVERT(lower / 255.f); 53cb93a386Sopenharmony_ci upper = CONVERT(upper / 255.f); 54cb93a386Sopenharmony_ci SkASSERT(lower >= 0.f && lower <= 255.f); 55cb93a386Sopenharmony_ci SkASSERT(upper >= 0.f && upper <= 255.f); 56cb93a386Sopenharmony_ci uint8_t outputComponent = (output & (0xff << (c*8))) >> (c*8); 57cb93a386Sopenharmony_ci if (outputComponent < SkScalarFloorToInt(lower * 255.f) || 58cb93a386Sopenharmony_ci outputComponent > SkScalarCeilToInt(upper * 255.f)) { 59cb93a386Sopenharmony_ci return false; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci return true; 63cb93a386Sopenharmony_ci} 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci/** tests a forward and backward conversion with an error tolerance */ 66cb93a386Sopenharmony_citemplate <float (*FORWARD)(float), float (*BACKWARD)(float)> 67cb93a386Sopenharmony_cistatic bool check_double_conversion(uint32_t input, uint32_t output, float error) { 68cb93a386Sopenharmony_ci // alpha should always be exactly preserved. 69cb93a386Sopenharmony_ci if ((input & 0xff000000) != (output & 0xff000000)) { 70cb93a386Sopenharmony_ci return false; 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_ci for (int c = 0; c < 3; ++c) { 74cb93a386Sopenharmony_ci uint8_t inputComponent = (uint8_t) ((input & (0xff << (c*8))) >> (c*8)); 75cb93a386Sopenharmony_ci float lower = std::max(0.f, (float) inputComponent - error); 76cb93a386Sopenharmony_ci float upper = std::min(255.f, (float) inputComponent + error); 77cb93a386Sopenharmony_ci lower = FORWARD(lower / 255.f); 78cb93a386Sopenharmony_ci upper = FORWARD(upper / 255.f); 79cb93a386Sopenharmony_ci SkASSERT(lower >= 0.f && lower <= 255.f); 80cb93a386Sopenharmony_ci SkASSERT(upper >= 0.f && upper <= 255.f); 81cb93a386Sopenharmony_ci uint8_t upperComponent = SkScalarCeilToInt(upper * 255.f); 82cb93a386Sopenharmony_ci uint8_t lowerComponent = SkScalarFloorToInt(lower * 255.f); 83cb93a386Sopenharmony_ci lower = std::max(0.f, (float) lowerComponent - error); 84cb93a386Sopenharmony_ci upper = std::min(255.f, (float) upperComponent + error); 85cb93a386Sopenharmony_ci lower = BACKWARD(lowerComponent / 255.f); 86cb93a386Sopenharmony_ci upper = BACKWARD(upperComponent / 255.f); 87cb93a386Sopenharmony_ci SkASSERT(lower >= 0.f && lower <= 255.f); 88cb93a386Sopenharmony_ci SkASSERT(upper >= 0.f && upper <= 255.f); 89cb93a386Sopenharmony_ci upperComponent = SkScalarCeilToInt(upper * 255.f); 90cb93a386Sopenharmony_ci lowerComponent = SkScalarFloorToInt(lower * 255.f); 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci uint8_t outputComponent = (output & (0xff << (c*8))) >> (c*8); 93cb93a386Sopenharmony_ci if (outputComponent < lowerComponent || outputComponent > upperComponent) { 94cb93a386Sopenharmony_ci return false; 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci return true; 98cb93a386Sopenharmony_ci} 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_cistatic bool check_srgb_to_linear_conversion(uint32_t srgb, uint32_t linear, float error) { 101cb93a386Sopenharmony_ci return check_conversion<srgb_to_linear>(srgb, linear, error); 102cb93a386Sopenharmony_ci} 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_cistatic bool check_linear_to_srgb_conversion(uint32_t linear, uint32_t srgb, float error) { 105cb93a386Sopenharmony_ci return check_conversion<linear_to_srgb>(linear, srgb, error); 106cb93a386Sopenharmony_ci} 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_cistatic bool check_linear_to_srgb_to_linear_conversion(uint32_t input, uint32_t output, float error) { 109cb93a386Sopenharmony_ci return check_double_conversion<linear_to_srgb, srgb_to_linear>(input, output, error); 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_cistatic bool check_srgb_to_linear_to_srgb_conversion(uint32_t input, uint32_t output, float error) { 113cb93a386Sopenharmony_ci return check_double_conversion<srgb_to_linear, linear_to_srgb>(input, output, error); 114cb93a386Sopenharmony_ci} 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_cistatic bool check_no_conversion(uint32_t input, uint32_t output, float error) { 117cb93a386Sopenharmony_ci // This is a bit of a hack to check identity transformations that may lose precision. 118cb93a386Sopenharmony_ci return check_srgb_to_linear_to_srgb_conversion(input, output, error); 119cb93a386Sopenharmony_ci} 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_citypedef bool (*CheckFn) (uint32_t orig, uint32_t actual, float error); 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_civoid read_and_check_pixels(skiatest::Reporter* reporter, 124cb93a386Sopenharmony_ci GrDirectContext* dContext, 125cb93a386Sopenharmony_ci skgpu::SurfaceContext* sc, 126cb93a386Sopenharmony_ci uint32_t* origData, 127cb93a386Sopenharmony_ci const SkImageInfo& dstInfo, CheckFn checker, float error, 128cb93a386Sopenharmony_ci const char* subtestName) { 129cb93a386Sopenharmony_ci auto [w, h] = dstInfo.dimensions(); 130cb93a386Sopenharmony_ci GrPixmap readPM = GrPixmap::Allocate(dstInfo); 131cb93a386Sopenharmony_ci memset(readPM.addr(), 0, sizeof(uint32_t)*w*h); 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci if (!sc->readPixels(dContext, readPM, {0, 0})) { 134cb93a386Sopenharmony_ci ERRORF(reporter, "Could not read pixels for %s.", subtestName); 135cb93a386Sopenharmony_ci return; 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci for (int j = 0; j < h; ++j) { 139cb93a386Sopenharmony_ci for (int i = 0; i < w; ++i) { 140cb93a386Sopenharmony_ci uint32_t orig = origData[j * w + i]; 141cb93a386Sopenharmony_ci uint32_t read = static_cast<uint32_t*>(readPM.addr())[j * w + i]; 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci if (!checker(orig, read, error)) { 144cb93a386Sopenharmony_ci ERRORF(reporter, "Original 0x%08x, read back as 0x%08x in %s at %d, %d).", orig, 145cb93a386Sopenharmony_ci read, subtestName, i, j); 146cb93a386Sopenharmony_ci return; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci} 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_cinamespace { 153cb93a386Sopenharmony_cienum class Encoding { 154cb93a386Sopenharmony_ci kUntagged, 155cb93a386Sopenharmony_ci kLinear, 156cb93a386Sopenharmony_ci kSRGB, 157cb93a386Sopenharmony_ci}; 158cb93a386Sopenharmony_ci} // namespace 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_cistatic sk_sp<SkColorSpace> encoding_as_color_space(Encoding encoding) { 161cb93a386Sopenharmony_ci switch (encoding) { 162cb93a386Sopenharmony_ci case Encoding::kUntagged: return nullptr; 163cb93a386Sopenharmony_ci case Encoding::kLinear: return SkColorSpace::MakeSRGBLinear(); 164cb93a386Sopenharmony_ci case Encoding::kSRGB: return SkColorSpace::MakeSRGB(); 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci return nullptr; 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_cistatic const char* encoding_as_str(Encoding encoding) { 170cb93a386Sopenharmony_ci switch (encoding) { 171cb93a386Sopenharmony_ci case Encoding::kUntagged: return "untagged"; 172cb93a386Sopenharmony_ci case Encoding::kLinear: return "linear"; 173cb93a386Sopenharmony_ci case Encoding::kSRGB: return "sRGB"; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci return nullptr; 176cb93a386Sopenharmony_ci} 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_cistatic constexpr int kW = 255; 179cb93a386Sopenharmony_cistatic constexpr int kH = 255; 180cb93a386Sopenharmony_ci 181cb93a386Sopenharmony_cistatic std::unique_ptr<uint32_t[]> make_data() { 182cb93a386Sopenharmony_ci std::unique_ptr<uint32_t[]> data(new uint32_t[kW * kH]); 183cb93a386Sopenharmony_ci for (int j = 0; j < kH; ++j) { 184cb93a386Sopenharmony_ci for (int i = 0; i < kW; ++i) { 185cb93a386Sopenharmony_ci data[j * kW + i] = (0xFF << 24) | (i << 16) | (i << 8) | i; 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci } 188cb93a386Sopenharmony_ci return data; 189cb93a386Sopenharmony_ci} 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_cistatic std::unique_ptr<skgpu::SurfaceContext> make_surface_context(Encoding contextEncoding, 192cb93a386Sopenharmony_ci GrRecordingContext* rContext, 193cb93a386Sopenharmony_ci skiatest::Reporter* reporter) { 194cb93a386Sopenharmony_ci GrImageInfo info(GrColorType::kRGBA_8888, 195cb93a386Sopenharmony_ci kPremul_SkAlphaType, 196cb93a386Sopenharmony_ci encoding_as_color_space(contextEncoding), 197cb93a386Sopenharmony_ci kW, kH); 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci auto sc = CreateSurfaceContext(rContext, 200cb93a386Sopenharmony_ci info, 201cb93a386Sopenharmony_ci SkBackingFit::kExact, 202cb93a386Sopenharmony_ci kBottomLeft_GrSurfaceOrigin, 203cb93a386Sopenharmony_ci GrRenderable::kYes); 204cb93a386Sopenharmony_ci if (!sc) { 205cb93a386Sopenharmony_ci ERRORF(reporter, "Could not create %s surface context.", encoding_as_str(contextEncoding)); 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci return sc; 208cb93a386Sopenharmony_ci} 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_cistatic void test_write_read(Encoding contextEncoding, Encoding writeEncoding, Encoding readEncoding, 211cb93a386Sopenharmony_ci float error, CheckFn check, GrDirectContext* dContext, 212cb93a386Sopenharmony_ci skiatest::Reporter* reporter) { 213cb93a386Sopenharmony_ci auto surfaceContext = make_surface_context(contextEncoding, dContext, reporter); 214cb93a386Sopenharmony_ci if (!surfaceContext) { 215cb93a386Sopenharmony_ci return; 216cb93a386Sopenharmony_ci } 217cb93a386Sopenharmony_ci auto writeII = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType, 218cb93a386Sopenharmony_ci encoding_as_color_space(writeEncoding)); 219cb93a386Sopenharmony_ci auto data = make_data(); 220cb93a386Sopenharmony_ci GrCPixmap dataPM(writeII, data.get(), kW*sizeof(uint32_t)); 221cb93a386Sopenharmony_ci if (!surfaceContext->writePixels(dContext, dataPM, {0, 0})) { 222cb93a386Sopenharmony_ci ERRORF(reporter, "Could not write %s to %s surface context.", 223cb93a386Sopenharmony_ci encoding_as_str(writeEncoding), encoding_as_str(contextEncoding)); 224cb93a386Sopenharmony_ci return; 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci auto readII = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType, 228cb93a386Sopenharmony_ci encoding_as_color_space(readEncoding)); 229cb93a386Sopenharmony_ci SkString testName; 230cb93a386Sopenharmony_ci testName.printf("write %s data to a %s context and read as %s.", encoding_as_str(writeEncoding), 231cb93a386Sopenharmony_ci encoding_as_str(contextEncoding), encoding_as_str(readEncoding)); 232cb93a386Sopenharmony_ci read_and_check_pixels(reporter, dContext, surfaceContext.get(), data.get(), readII, check, 233cb93a386Sopenharmony_ci error, testName.c_str()); 234cb93a386Sopenharmony_ci} 235cb93a386Sopenharmony_ci 236cb93a386Sopenharmony_ci// Test all combinations of writePixels/readPixels where the surface context/write source/read dst 237cb93a386Sopenharmony_ci// are sRGB, linear, or untagged RGBA_8888. 238cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(SRGBReadWritePixels, reporter, ctxInfo) { 239cb93a386Sopenharmony_ci auto context = ctxInfo.directContext(); 240cb93a386Sopenharmony_ci if (!context->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888_SRGB, 241cb93a386Sopenharmony_ci GrRenderable::kNo).isValid()) { 242cb93a386Sopenharmony_ci return; 243cb93a386Sopenharmony_ci } 244cb93a386Sopenharmony_ci // We allow more error on GPUs with lower precision shader variables. 245cb93a386Sopenharmony_ci float error = context->priv().caps()->shaderCaps()->halfIs32Bits() ? 0.5f : 1.2f; 246cb93a386Sopenharmony_ci // For the all-sRGB case, we allow a small error only for devices that have 247cb93a386Sopenharmony_ci // precision variation because the sRGB data gets converted to linear and back in 248cb93a386Sopenharmony_ci // the shader. 249cb93a386Sopenharmony_ci float smallError = context->priv().caps()->shaderCaps()->halfIs32Bits() ? 0.0f : 1.f; 250cb93a386Sopenharmony_ci 251cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////////////////////// 252cb93a386Sopenharmony_ci // Write sRGB data to a sRGB context - no conversion on the write. 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_ci // back to sRGB - no conversion. 255cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kSRGB, Encoding::kSRGB, smallError, 256cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 257cb93a386Sopenharmony_ci // Reading back to untagged should be a pass through with no conversion. 258cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kSRGB, Encoding::kUntagged, error, 259cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci // Converts back to linear 262cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kSRGB, Encoding::kLinear, error, 263cb93a386Sopenharmony_ci check_srgb_to_linear_conversion, context, reporter); 264cb93a386Sopenharmony_ci 265cb93a386Sopenharmony_ci // Untagged source data should be interpreted as sRGB. 266cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kUntagged, Encoding::kSRGB, smallError, 267cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 268cb93a386Sopenharmony_ci 269cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////////////////////// 270cb93a386Sopenharmony_ci // Write linear data to a sRGB context. It gets converted to sRGB on write. The reads 271cb93a386Sopenharmony_ci // are all the same as the above cases where the original data was untagged. 272cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kLinear, Encoding::kSRGB, error, 273cb93a386Sopenharmony_ci check_linear_to_srgb_conversion, context, reporter); 274cb93a386Sopenharmony_ci // When the dst buffer is untagged there should be no conversion on the read. 275cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kLinear, Encoding::kUntagged, error, 276cb93a386Sopenharmony_ci check_linear_to_srgb_conversion, context, reporter); 277cb93a386Sopenharmony_ci test_write_read(Encoding::kSRGB, Encoding::kLinear, Encoding::kLinear, error, 278cb93a386Sopenharmony_ci check_linear_to_srgb_to_linear_conversion, context, reporter); 279cb93a386Sopenharmony_ci 280cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////////////////////// 281cb93a386Sopenharmony_ci // Write data to an untagged context. The write does no conversion no matter what encoding the 282cb93a386Sopenharmony_ci // src data has. 283cb93a386Sopenharmony_ci for (auto writeEncoding : {Encoding::kSRGB, Encoding::kUntagged, Encoding::kLinear}) { 284cb93a386Sopenharmony_ci // The read from untagged to sRGB also does no conversion. 285cb93a386Sopenharmony_ci test_write_read(Encoding::kUntagged, writeEncoding, Encoding::kSRGB, error, 286cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 287cb93a386Sopenharmony_ci // Reading untagged back as untagged should do no conversion. 288cb93a386Sopenharmony_ci test_write_read(Encoding::kUntagged, writeEncoding, Encoding::kUntagged, error, 289cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 290cb93a386Sopenharmony_ci // Reading untagged back as linear does convert (context is source, so treated as sRGB), 291cb93a386Sopenharmony_ci // dst is tagged. 292cb93a386Sopenharmony_ci test_write_read(Encoding::kUntagged, writeEncoding, Encoding::kLinear, error, 293cb93a386Sopenharmony_ci check_srgb_to_linear_conversion, context, reporter); 294cb93a386Sopenharmony_ci } 295cb93a386Sopenharmony_ci 296cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////////////////////// 297cb93a386Sopenharmony_ci // Write sRGB data to a linear context - converts to sRGB on the write. 298cb93a386Sopenharmony_ci 299cb93a386Sopenharmony_ci // converts back to sRGB on read. 300cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kSRGB, Encoding::kSRGB, error, 301cb93a386Sopenharmony_ci check_srgb_to_linear_to_srgb_conversion, context, reporter); 302cb93a386Sopenharmony_ci // Reading untagged data from linear currently does no conversion. 303cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kSRGB, Encoding::kUntagged, error, 304cb93a386Sopenharmony_ci check_srgb_to_linear_conversion, context, reporter); 305cb93a386Sopenharmony_ci // Stays linear when read. 306cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kSRGB, Encoding::kLinear, error, 307cb93a386Sopenharmony_ci check_srgb_to_linear_conversion, context, reporter); 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci // Untagged source data should be interpreted as sRGB. 310cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kUntagged, Encoding::kSRGB, error, 311cb93a386Sopenharmony_ci check_srgb_to_linear_to_srgb_conversion, context, reporter); 312cb93a386Sopenharmony_ci 313cb93a386Sopenharmony_ci /////////////////////////////////////////////////////////////////////////////////////////////// 314cb93a386Sopenharmony_ci // Write linear data to a linear context. Does no conversion. 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci // Reading to sRGB does a conversion. 317cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kLinear, Encoding::kSRGB, error, 318cb93a386Sopenharmony_ci check_linear_to_srgb_conversion, context, reporter); 319cb93a386Sopenharmony_ci // Reading to untagged does no conversion. 320cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kLinear, Encoding::kUntagged, error, 321cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 322cb93a386Sopenharmony_ci // Stays linear when read. 323cb93a386Sopenharmony_ci test_write_read(Encoding::kLinear, Encoding::kLinear, Encoding::kLinear, error, 324cb93a386Sopenharmony_ci check_no_conversion, context, reporter); 325cb93a386Sopenharmony_ci} 326