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