SRGBReadWritePixelsTest.cpp revision 7d974f5e4f8ded8834b58f560ac6e03aed370310
116921ec30a81976129d507b1148c93a322e61a4fbsalomon/* 216921ec30a81976129d507b1148c93a322e61a4fbsalomon * Copyright 2015 Google Inc. 316921ec30a81976129d507b1148c93a322e61a4fbsalomon * 416921ec30a81976129d507b1148c93a322e61a4fbsalomon * Use of this source code is governed by a BSD-style license that can be 516921ec30a81976129d507b1148c93a322e61a4fbsalomon * found in the LICENSE file. 616921ec30a81976129d507b1148c93a322e61a4fbsalomon */ 716921ec30a81976129d507b1148c93a322e61a4fbsalomon 816921ec30a81976129d507b1148c93a322e61a4fbsalomon#include "Test.h" 916921ec30a81976129d507b1148c93a322e61a4fbsalomon#if SK_SUPPORT_GPU 1016921ec30a81976129d507b1148c93a322e61a4fbsalomon#include "SkCanvas.h" 1116921ec30a81976129d507b1148c93a322e61a4fbsalomon 1216921ec30a81976129d507b1148c93a322e61a4fbsalomon#include "SkSurface.h" 1316921ec30a81976129d507b1148c93a322e61a4fbsalomon#include "GrContextFactory.h" 1416921ec30a81976129d507b1148c93a322e61a4fbsalomon#include "GrCaps.h" 1516921ec30a81976129d507b1148c93a322e61a4fbsalomon 1616921ec30a81976129d507b1148c93a322e61a4fbsalomon// using anonymous namespace because these functions are used as template params. 1716921ec30a81976129d507b1148c93a322e61a4fbsalomonnamespace { 1816921ec30a81976129d507b1148c93a322e61a4fbsalomon/** convert 0..1 srgb value to 0..1 linear */ 1916921ec30a81976129d507b1148c93a322e61a4fbsalomonfloat srgb_to_linear(float srgb) { 2016921ec30a81976129d507b1148c93a322e61a4fbsalomon if (srgb <= 0.04045f) { 2116921ec30a81976129d507b1148c93a322e61a4fbsalomon return srgb / 12.92f; 2216921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 2316921ec30a81976129d507b1148c93a322e61a4fbsalomon return powf((srgb + 0.055f) / 1.055f, 2.4f); 2416921ec30a81976129d507b1148c93a322e61a4fbsalomon } 2516921ec30a81976129d507b1148c93a322e61a4fbsalomon} 2616921ec30a81976129d507b1148c93a322e61a4fbsalomon 2716921ec30a81976129d507b1148c93a322e61a4fbsalomon/** convert 0..1 linear value to 0..1 srgb */ 2816921ec30a81976129d507b1148c93a322e61a4fbsalomonfloat linear_to_srgb(float linear) { 2916921ec30a81976129d507b1148c93a322e61a4fbsalomon if (linear <= 0.0031308) { 3016921ec30a81976129d507b1148c93a322e61a4fbsalomon return linear * 12.92f; 3116921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 3216921ec30a81976129d507b1148c93a322e61a4fbsalomon return 1.055f * powf(linear, 1.f / 2.4f) - 0.055f; 3316921ec30a81976129d507b1148c93a322e61a4fbsalomon } 3416921ec30a81976129d507b1148c93a322e61a4fbsalomon} 3516921ec30a81976129d507b1148c93a322e61a4fbsalomon} 3616921ec30a81976129d507b1148c93a322e61a4fbsalomon 3716921ec30a81976129d507b1148c93a322e61a4fbsalomon/** tests a conversion with an error tolerance */ 3816921ec30a81976129d507b1148c93a322e61a4fbsalomontemplate <float (*CONVERT)(float)> static bool check_conversion(uint32_t input, uint32_t output, 3916921ec30a81976129d507b1148c93a322e61a4fbsalomon float error) { 4016921ec30a81976129d507b1148c93a322e61a4fbsalomon // alpha should always be exactly preserved. 4116921ec30a81976129d507b1148c93a322e61a4fbsalomon if ((input & 0xff000000) != (output & 0xff000000)) { 4216921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 4316921ec30a81976129d507b1148c93a322e61a4fbsalomon } 4416921ec30a81976129d507b1148c93a322e61a4fbsalomon 4516921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int c = 0; c < 3; ++c) { 4616921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t inputComponent = (uint8_t) ((input & (0xff << (c*8))) >> (c*8)); 4716921ec30a81976129d507b1148c93a322e61a4fbsalomon float lower = SkTMax(0.f, (float) inputComponent - error); 4816921ec30a81976129d507b1148c93a322e61a4fbsalomon float upper = SkTMin(255.f, (float) inputComponent + error); 4916921ec30a81976129d507b1148c93a322e61a4fbsalomon lower = CONVERT(lower / 255.f); 5016921ec30a81976129d507b1148c93a322e61a4fbsalomon upper = CONVERT(upper / 255.f); 5116921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(lower >= 0.f && lower <= 255.f); 5216921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(upper >= 0.f && upper <= 255.f); 5316921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t outputComponent = (output & (0xff << (c*8))) >> (c*8); 5416921ec30a81976129d507b1148c93a322e61a4fbsalomon if (outputComponent < SkScalarFloorToInt(lower * 255.f) || 5516921ec30a81976129d507b1148c93a322e61a4fbsalomon outputComponent > SkScalarCeilToInt(upper * 255.f)) { 5616921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 5716921ec30a81976129d507b1148c93a322e61a4fbsalomon } 5816921ec30a81976129d507b1148c93a322e61a4fbsalomon } 5916921ec30a81976129d507b1148c93a322e61a4fbsalomon return true; 6016921ec30a81976129d507b1148c93a322e61a4fbsalomon} 6116921ec30a81976129d507b1148c93a322e61a4fbsalomon 6216921ec30a81976129d507b1148c93a322e61a4fbsalomon/** tests a forward and backward conversion with an error tolerance */ 6316921ec30a81976129d507b1148c93a322e61a4fbsalomontemplate <float (*FORWARD)(float), float (*BACKWARD)(float)> 6416921ec30a81976129d507b1148c93a322e61a4fbsalomonstatic bool check_double_conversion(uint32_t input, uint32_t output, float error) { 6516921ec30a81976129d507b1148c93a322e61a4fbsalomon // alpha should always be exactly preserved. 6616921ec30a81976129d507b1148c93a322e61a4fbsalomon if ((input & 0xff000000) != (output & 0xff000000)) { 6716921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 6816921ec30a81976129d507b1148c93a322e61a4fbsalomon } 6916921ec30a81976129d507b1148c93a322e61a4fbsalomon 7016921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int c = 0; c < 3; ++c) { 7116921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t inputComponent = (uint8_t) ((input & (0xff << (c*8))) >> (c*8)); 7216921ec30a81976129d507b1148c93a322e61a4fbsalomon float lower = SkTMax(0.f, (float) inputComponent - error); 7316921ec30a81976129d507b1148c93a322e61a4fbsalomon float upper = SkTMin(255.f, (float) inputComponent + error); 7416921ec30a81976129d507b1148c93a322e61a4fbsalomon lower = FORWARD(lower / 255.f); 7516921ec30a81976129d507b1148c93a322e61a4fbsalomon upper = FORWARD(upper / 255.f); 7616921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(lower >= 0.f && lower <= 255.f); 7716921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(upper >= 0.f && upper <= 255.f); 7816921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t upperComponent = SkScalarCeilToInt(upper * 255.f); 7916921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t lowerComponent = SkScalarFloorToInt(lower * 255.f); 8016921ec30a81976129d507b1148c93a322e61a4fbsalomon lower = SkTMax(0.f, (float) lowerComponent - error); 8116921ec30a81976129d507b1148c93a322e61a4fbsalomon upper = SkTMin(255.f, (float) upperComponent + error); 8216921ec30a81976129d507b1148c93a322e61a4fbsalomon lower = BACKWARD(lowerComponent / 255.f); 8316921ec30a81976129d507b1148c93a322e61a4fbsalomon upper = BACKWARD(upperComponent / 255.f); 8416921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(lower >= 0.f && lower <= 255.f); 8516921ec30a81976129d507b1148c93a322e61a4fbsalomon SkASSERT(upper >= 0.f && upper <= 255.f); 8616921ec30a81976129d507b1148c93a322e61a4fbsalomon upperComponent = SkScalarCeilToInt(upper * 255.f); 8716921ec30a81976129d507b1148c93a322e61a4fbsalomon lowerComponent = SkScalarFloorToInt(lower * 255.f); 8816921ec30a81976129d507b1148c93a322e61a4fbsalomon 8916921ec30a81976129d507b1148c93a322e61a4fbsalomon uint8_t outputComponent = (output & (0xff << (c*8))) >> (c*8); 9016921ec30a81976129d507b1148c93a322e61a4fbsalomon if (outputComponent < lowerComponent || outputComponent > upperComponent) { 9116921ec30a81976129d507b1148c93a322e61a4fbsalomon return false; 9216921ec30a81976129d507b1148c93a322e61a4fbsalomon } 9316921ec30a81976129d507b1148c93a322e61a4fbsalomon } 9416921ec30a81976129d507b1148c93a322e61a4fbsalomon return true; 9516921ec30a81976129d507b1148c93a322e61a4fbsalomon} 9616921ec30a81976129d507b1148c93a322e61a4fbsalomon 9716921ec30a81976129d507b1148c93a322e61a4fbsalomonstatic bool check_srgb_to_linear_conversion(uint32_t srgb, uint32_t linear, float error) { 9816921ec30a81976129d507b1148c93a322e61a4fbsalomon return check_conversion<srgb_to_linear>(srgb, linear, error); 9916921ec30a81976129d507b1148c93a322e61a4fbsalomon} 10016921ec30a81976129d507b1148c93a322e61a4fbsalomon 10116921ec30a81976129d507b1148c93a322e61a4fbsalomonstatic bool check_linear_to_srgb_conversion(uint32_t linear, uint32_t srgb, float error) { 10216921ec30a81976129d507b1148c93a322e61a4fbsalomon return check_conversion<linear_to_srgb>(linear, srgb, error); 10316921ec30a81976129d507b1148c93a322e61a4fbsalomon} 10416921ec30a81976129d507b1148c93a322e61a4fbsalomon 10516921ec30a81976129d507b1148c93a322e61a4fbsalomonstatic bool check_linear_to_srgb_to_linear_conversion(uint32_t input, uint32_t output, float error) { 10616921ec30a81976129d507b1148c93a322e61a4fbsalomon return check_double_conversion<linear_to_srgb, srgb_to_linear>(input, output, error); 10716921ec30a81976129d507b1148c93a322e61a4fbsalomon} 10816921ec30a81976129d507b1148c93a322e61a4fbsalomon 10916921ec30a81976129d507b1148c93a322e61a4fbsalomonstatic bool check_srgb_to_linear_to_srgb_conversion(uint32_t input, uint32_t output, float error) { 11016921ec30a81976129d507b1148c93a322e61a4fbsalomon return check_double_conversion<srgb_to_linear, linear_to_srgb>(input, output, error); 11116921ec30a81976129d507b1148c93a322e61a4fbsalomon} 11216921ec30a81976129d507b1148c93a322e61a4fbsalomon 11316921ec30a81976129d507b1148c93a322e61a4fbsalomontypedef bool (*CheckFn) (uint32_t orig, uint32_t actual, float error); 11416921ec30a81976129d507b1148c93a322e61a4fbsalomon 11516921ec30a81976129d507b1148c93a322e61a4fbsalomonvoid read_and_check_pixels(skiatest::Reporter* reporter, GrTexture* texture, uint32_t* origData, 11616921ec30a81976129d507b1148c93a322e61a4fbsalomon GrPixelConfig readConfig, CheckFn checker, float error, 11716921ec30a81976129d507b1148c93a322e61a4fbsalomon const char* subtestName) { 11816921ec30a81976129d507b1148c93a322e61a4fbsalomon int w = texture->width(); 11916921ec30a81976129d507b1148c93a322e61a4fbsalomon int h = texture->height(); 12016921ec30a81976129d507b1148c93a322e61a4fbsalomon SkAutoTMalloc<uint32_t> readData(w * h); 12116921ec30a81976129d507b1148c93a322e61a4fbsalomon memset(readData.get(), 0, sizeof(uint32_t) * w * h); 12216921ec30a81976129d507b1148c93a322e61a4fbsalomon if (!texture->readPixels(0, 0, w, h, readConfig, readData.get())) { 12316921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not read pixels for %s.", subtestName); 12416921ec30a81976129d507b1148c93a322e61a4fbsalomon return; 12516921ec30a81976129d507b1148c93a322e61a4fbsalomon } 12616921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int j = 0; j < h; ++j) { 12716921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int i = 0; i < w; ++i) { 12816921ec30a81976129d507b1148c93a322e61a4fbsalomon uint32_t orig = origData[j * w + i]; 12916921ec30a81976129d507b1148c93a322e61a4fbsalomon uint32_t read = readData[j * w + i]; 13016921ec30a81976129d507b1148c93a322e61a4fbsalomon 13116921ec30a81976129d507b1148c93a322e61a4fbsalomon if (!checker(orig, read, error)) { 13216921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Expected 0x%08x, read back as 0x%08x in %s at %d, %d).", 13316921ec30a81976129d507b1148c93a322e61a4fbsalomon orig, read, subtestName, i, j); 13416921ec30a81976129d507b1148c93a322e61a4fbsalomon return; 13516921ec30a81976129d507b1148c93a322e61a4fbsalomon } 13616921ec30a81976129d507b1148c93a322e61a4fbsalomon } 13716921ec30a81976129d507b1148c93a322e61a4fbsalomon } 13816921ec30a81976129d507b1148c93a322e61a4fbsalomon} 13916921ec30a81976129d507b1148c93a322e61a4fbsalomon 14016921ec30a81976129d507b1148c93a322e61a4fbsalomon// TODO: Add tests for copySurface between srgb/linear textures. Add tests for unpremul/premul 14116921ec30a81976129d507b1148c93a322e61a4fbsalomon// conversion during read/write along with srgb/linear conversions. 14216921ec30a81976129d507b1148c93a322e61a4fbsalomonDEF_GPUTEST(SRGBReadWritePixels, reporter, factory) { 1437d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner#if defined(GOOGLE3) 1447d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner // Stack frame size is limited in GOOGLE3. 1457d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner static const int kW = 63; 1467d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner static const int kH = 63; 1477d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner#else 14816921ec30a81976129d507b1148c93a322e61a4fbsalomon static const int kW = 255; 14916921ec30a81976129d507b1148c93a322e61a4fbsalomon static const int kH = 255; 1507d974f5e4f8ded8834b58f560ac6e03aed370310benjaminwagner#endif 15116921ec30a81976129d507b1148c93a322e61a4fbsalomon uint32_t origData[kW * kH]; 15216921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int j = 0; j < kH; ++j) { 15316921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int i = 0; i < kW; ++i) { 15416921ec30a81976129d507b1148c93a322e61a4fbsalomon origData[j * kW + i] = (j << 24) | (i << 16) | (i << 8) | i; 15516921ec30a81976129d507b1148c93a322e61a4fbsalomon } 15616921ec30a81976129d507b1148c93a322e61a4fbsalomon } 15716921ec30a81976129d507b1148c93a322e61a4fbsalomon 15816921ec30a81976129d507b1148c93a322e61a4fbsalomon for (int t = 0; t < GrContextFactory::kGLContextTypeCnt; ++t) { 15916921ec30a81976129d507b1148c93a322e61a4fbsalomon GrContextFactory::GLContextType glType = (GrContextFactory::GLContextType) t; 16016921ec30a81976129d507b1148c93a322e61a4fbsalomon GrContext* context; 16116921ec30a81976129d507b1148c93a322e61a4fbsalomon // We allow more error on GPUs with lower precision shader variables. 16216921ec30a81976129d507b1148c93a322e61a4fbsalomon if (!GrContextFactory::IsRenderingGLContext(glType) || !(context = factory->get(glType))) { 16316921ec30a81976129d507b1148c93a322e61a4fbsalomon continue; 16416921ec30a81976129d507b1148c93a322e61a4fbsalomon } 16516921ec30a81976129d507b1148c93a322e61a4fbsalomon 16616921ec30a81976129d507b1148c93a322e61a4fbsalomon GrSurfaceDesc desc; 16716921ec30a81976129d507b1148c93a322e61a4fbsalomon desc.fFlags = kRenderTarget_GrSurfaceFlag; 16816921ec30a81976129d507b1148c93a322e61a4fbsalomon desc.fWidth = kW; 16916921ec30a81976129d507b1148c93a322e61a4fbsalomon desc.fHeight = kH; 17016921ec30a81976129d507b1148c93a322e61a4fbsalomon desc.fConfig = kSRGBA_8888_GrPixelConfig; 17116921ec30a81976129d507b1148c93a322e61a4fbsalomon if (context->caps()->isConfigRenderable(desc.fConfig, false) && 17216921ec30a81976129d507b1148c93a322e61a4fbsalomon context->caps()->isConfigTexturable(desc.fConfig)) { 17316921ec30a81976129d507b1148c93a322e61a4fbsalomon SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(desc, false)); 17416921ec30a81976129d507b1148c93a322e61a4fbsalomon if (!tex) { 17516921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not create SRGBA texture."); 17616921ec30a81976129d507b1148c93a322e61a4fbsalomon continue; 17716921ec30a81976129d507b1148c93a322e61a4fbsalomon } 17816921ec30a81976129d507b1148c93a322e61a4fbsalomon 17916921ec30a81976129d507b1148c93a322e61a4fbsalomon float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.2f : 0.5f; 18016921ec30a81976129d507b1148c93a322e61a4fbsalomon 18116921ec30a81976129d507b1148c93a322e61a4fbsalomon // Write srgba data and read as srgba and then as rgba 18216921ec30a81976129d507b1148c93a322e61a4fbsalomon if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) { 18316921ec30a81976129d507b1148c93a322e61a4fbsalomon // For the all-srgba case, we allow a small error only for devices that have 18416921ec30a81976129d507b1148c93a322e61a4fbsalomon // precision variation because the srgba data gets converted to linear and back in 18516921ec30a81976129d507b1148c93a322e61a4fbsalomon // the shader. 18616921ec30a81976129d507b1148c93a322e61a4fbsalomon float smallError = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.f : 18716921ec30a81976129d507b1148c93a322e61a4fbsalomon 0.0f; 18816921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig, 18916921ec30a81976129d507b1148c93a322e61a4fbsalomon check_srgb_to_linear_to_srgb_conversion, smallError, 19016921ec30a81976129d507b1148c93a322e61a4fbsalomon "write/read srgba to srgba texture"); 19116921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig, 19216921ec30a81976129d507b1148c93a322e61a4fbsalomon check_srgb_to_linear_conversion, error, 19316921ec30a81976129d507b1148c93a322e61a4fbsalomon "write srgba/read rgba with srgba texture"); 19416921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 19516921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not write srgba data to srgba texture."); 19616921ec30a81976129d507b1148c93a322e61a4fbsalomon } 19716921ec30a81976129d507b1148c93a322e61a4fbsalomon 19816921ec30a81976129d507b1148c93a322e61a4fbsalomon // Now verify that we can write linear data 19916921ec30a81976129d507b1148c93a322e61a4fbsalomon if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) { 20016921ec30a81976129d507b1148c93a322e61a4fbsalomon // We allow more error on GPUs with lower precision shader variables. 20116921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig, 20216921ec30a81976129d507b1148c93a322e61a4fbsalomon check_linear_to_srgb_conversion, error, 20316921ec30a81976129d507b1148c93a322e61a4fbsalomon "write rgba/read srgba with srgba texture"); 20416921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig, 20516921ec30a81976129d507b1148c93a322e61a4fbsalomon check_linear_to_srgb_to_linear_conversion, error, 20616921ec30a81976129d507b1148c93a322e61a4fbsalomon "write/read rgba with srgba texture"); 20716921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 20816921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not write rgba data to srgba texture."); 20916921ec30a81976129d507b1148c93a322e61a4fbsalomon } 21016921ec30a81976129d507b1148c93a322e61a4fbsalomon 21116921ec30a81976129d507b1148c93a322e61a4fbsalomon desc.fConfig = kRGBA_8888_GrPixelConfig; 21216921ec30a81976129d507b1148c93a322e61a4fbsalomon tex.reset(context->textureProvider()->createTexture(desc, false)); 21316921ec30a81976129d507b1148c93a322e61a4fbsalomon if (!tex) { 21416921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not create RGBA texture."); 21516921ec30a81976129d507b1148c93a322e61a4fbsalomon continue; 21616921ec30a81976129d507b1148c93a322e61a4fbsalomon } 21716921ec30a81976129d507b1148c93a322e61a4fbsalomon 21816921ec30a81976129d507b1148c93a322e61a4fbsalomon // Write srgba data to a rgba texture and read back as srgba and rgba 21916921ec30a81976129d507b1148c93a322e61a4fbsalomon if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData)) { 22016921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig, 22116921ec30a81976129d507b1148c93a322e61a4fbsalomon check_srgb_to_linear_to_srgb_conversion, error, 22216921ec30a81976129d507b1148c93a322e61a4fbsalomon "write/read srgba to rgba texture"); 22316921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelConfig, 22416921ec30a81976129d507b1148c93a322e61a4fbsalomon check_srgb_to_linear_conversion, error, 22516921ec30a81976129d507b1148c93a322e61a4fbsalomon "write srgba/read rgba to rgba texture"); 22616921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 22716921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not write srgba data to rgba texture."); 22816921ec30a81976129d507b1148c93a322e61a4fbsalomon } 22916921ec30a81976129d507b1148c93a322e61a4fbsalomon 23016921ec30a81976129d507b1148c93a322e61a4fbsalomon // Write rgba data to a rgba texture and read back as srgba 23116921ec30a81976129d507b1148c93a322e61a4fbsalomon if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData)) { 23216921ec30a81976129d507b1148c93a322e61a4fbsalomon read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelConfig, 23316921ec30a81976129d507b1148c93a322e61a4fbsalomon check_linear_to_srgb_conversion, 1.2f, 23416921ec30a81976129d507b1148c93a322e61a4fbsalomon "write rgba/read srgba to rgba texture"); 23516921ec30a81976129d507b1148c93a322e61a4fbsalomon } else { 23616921ec30a81976129d507b1148c93a322e61a4fbsalomon ERRORF(reporter, "Could not write rgba data to rgba texture."); 23716921ec30a81976129d507b1148c93a322e61a4fbsalomon } 23816921ec30a81976129d507b1148c93a322e61a4fbsalomon} 23916921ec30a81976129d507b1148c93a322e61a4fbsalomon } 24016921ec30a81976129d507b1148c93a322e61a4fbsalomon} 24116921ec30a81976129d507b1148c93a322e61a4fbsalomon#endif 242