16995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com/*
26995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com * Copyright 2012 Google Inc.
36995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com *
46995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be
56995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com * found in the LICENSE file.
66995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com */
76995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
8f037e0bf138a4e842f39e19864d05010a54950c9reed#include "Test.h"
9f037e0bf138a4e842f39e19864d05010a54950c9reed
10cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com// This test is specific to the GPU backend.
11e9573317d35d08254412eb407211f3607f8f74fbbsalomon#if SK_SUPPORT_GPU
12cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
131530283c483cb88aa725bce50a6d193dd00ee570kkinnunen#include "GrContext.h"
14c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips#include "GrContextPriv.h"
150bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips#include "GrProxyProvider.h"
1632342f032e1dfd133040324f851f0365f9d4cb51Brian Osman#include "GrResourceProvider.h"
17c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips#include "GrSurfaceContext.h"
18c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips#include "GrSurfaceProxy.h"
19009e9af5549301be41cfbd9f286ad90842e4096bRobert Phillips#include "GrTextureProxy.h"
207715e06b68a1f07f07d23c63e7128d32654e30e9robertphillips#include "SkCanvas.h"
217715e06b68a1f07f07d23c63e7128d32654e30e9robertphillips#include "SkSurface.h"
226995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
23f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomon// This was made indivisible by 4 to ensure we test setting GL_PACK_ALIGNMENT properly.
24f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomonstatic const int X_SIZE = 13;
25f46a124ddd31ca4053c1719d720a74eb4a3cad6dbsalomonstatic const int Y_SIZE = 13;
266995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
279d02b264b72be64702e43cb797b7899a8a6926cabsalomonstatic void validate_alpha_data(skiatest::Reporter* reporter, int w, int h, const uint8_t* actual,
2810fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                                size_t actualRowBytes, const uint8_t* expected, SkString extraMsg,
2910fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                                GrPixelConfig config) {
309d02b264b72be64702e43cb797b7899a8a6926cabsalomon    for (int y = 0; y < h; ++y) {
319d02b264b72be64702e43cb797b7899a8a6926cabsalomon        for (int x = 0; x < w; ++x) {
329d02b264b72be64702e43cb797b7899a8a6926cabsalomon            uint8_t a = actual[y * actualRowBytes + x];
339d02b264b72be64702e43cb797b7899a8a6926cabsalomon            uint8_t e = expected[y * w + x];
3410fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            if (kRGBA_1010102_GrPixelConfig == config) {
3510fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                // This config only preserves two bits of alpha
3610fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                a >>= 6;
3710fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                e >>= 6;
3810fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            }
399d02b264b72be64702e43cb797b7899a8a6926cabsalomon            if (e != a) {
409d02b264b72be64702e43cb797b7899a8a6926cabsalomon                ERRORF(reporter,
419d02b264b72be64702e43cb797b7899a8a6926cabsalomon                       "Failed alpha readback. Expected: 0x%02x, Got: 0x%02x at (%d,%d), %s",
429d02b264b72be64702e43cb797b7899a8a6926cabsalomon                       e, a, x, y, extraMsg.c_str());
439d02b264b72be64702e43cb797b7899a8a6926cabsalomon                return;
449d02b264b72be64702e43cb797b7899a8a6926cabsalomon            }
459d02b264b72be64702e43cb797b7899a8a6926cabsalomon        }
469d02b264b72be64702e43cb797b7899a8a6926cabsalomon    }
479d02b264b72be64702e43cb797b7899a8a6926cabsalomon}
486995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
49ab527a5bbfb1eae4f99a1435d349a44d00477d82egdanielDEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReadWriteAlpha, reporter, ctxInfo) {
50c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips    GrContext* context = ctxInfo.grContext();
511afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
521afd4cdb0800e2e395b465da24eb71e0e834dafaRobert Phillips
539d02b264b72be64702e43cb797b7899a8a6926cabsalomon    unsigned char alphaData[X_SIZE * Y_SIZE];
546995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
55df082c54257256ca7570fb3a75852d2af4e6a80crobertphillips    static const int kClearValue = 0x2;
56df082c54257256ca7570fb3a75852d2af4e6a80crobertphillips
57e9573317d35d08254412eb407211f3607f8f74fbbsalomon    bool match;
589d02b264b72be64702e43cb797b7899a8a6926cabsalomon    static const size_t kRowBytes[] = {0, X_SIZE, X_SIZE + 1, 2 * X_SIZE - 1};
597e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips    {
60e9573317d35d08254412eb407211f3607f8f74fbbsalomon        GrSurfaceDesc desc;
617e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips        desc.fFlags     = kNone_GrSurfaceFlags;
62e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips        desc.fOrigin    = kTopLeft_GrSurfaceOrigin;
637e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips        desc.fConfig    = kAlpha_8_GrPixelConfig;    // it is a single channel texture
64e9573317d35d08254412eb407211f3607f8f74fbbsalomon        desc.fWidth     = X_SIZE;
65e9573317d35d08254412eb407211f3607f8f74fbbsalomon        desc.fHeight    = Y_SIZE;
66e9573317d35d08254412eb407211f3607f8f74fbbsalomon
67e9573317d35d08254412eb407211f3607f8f74fbbsalomon        // We are initializing the texture with zeros here
689d02b264b72be64702e43cb797b7899a8a6926cabsalomon        memset(alphaData, 0, X_SIZE * Y_SIZE);
69c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips
700bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
710bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips                                                                        alphaData, 0);
722f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips        if (!proxy) {
737e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips            ERRORF(reporter, "Could not create alpha texture.");
747e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips            return;
75b76afedf11c7fe933954d030048c3222860249e1bsalomon        }
76c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips        sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
77d5f9cdd4b3a6ab0e49bb1a56f2e52e2f40edd0faRobert Phillips                                                                  std::move(proxy)));
7823e566664b85472766c921cd2f5615c846919934bsalomon
797e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips        const SkImageInfo ii = SkImageInfo::MakeA8(X_SIZE, Y_SIZE);
80c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips        sk_sp<SkSurface> surf(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, ii));
817e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips
82e9573317d35d08254412eb407211f3607f8f74fbbsalomon        // create a distinctive texture
83e9573317d35d08254412eb407211f3607f8f74fbbsalomon        for (int y = 0; y < Y_SIZE; ++y) {
84e9573317d35d08254412eb407211f3607f8f74fbbsalomon            for (int x = 0; x < X_SIZE; ++x) {
859d02b264b72be64702e43cb797b7899a8a6926cabsalomon                alphaData[y * X_SIZE + x] = y*X_SIZE+x;
866995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com            }
876995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com        }
886995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
899d02b264b72be64702e43cb797b7899a8a6926cabsalomon        for (auto rowBytes : kRowBytes) {
90c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips
919d02b264b72be64702e43cb797b7899a8a6926cabsalomon            // upload the texture (do per-rowbytes iteration because we may overwrite below).
92c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips            bool result = sContext->writePixels(ii, alphaData, 0, 0, 0);
931c80e99dd5b23ebc3f10c768857a21887ab9f090Brian Salomon            REPORTER_ASSERT(reporter, result, "Initial A8 writePixels failed");
946995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
959d02b264b72be64702e43cb797b7899a8a6926cabsalomon            size_t nonZeroRowBytes = rowBytes ? rowBytes : X_SIZE;
9610fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            size_t bufLen = nonZeroRowBytes * Y_SIZE;
9710fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            std::unique_ptr<uint8_t[]> readback(new uint8_t[bufLen]);
989d02b264b72be64702e43cb797b7899a8a6926cabsalomon            // clear readback to something non-zero so we can detect readback failures
9910fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman            memset(readback.get(), kClearValue, bufLen);
1001530283c483cb88aa725bce50a6d193dd00ee570kkinnunen
1019d02b264b72be64702e43cb797b7899a8a6926cabsalomon            // read the texture back
102c949ce9d808dbf7c2db7dc0b85271969ba46b69aRobert Phillips            result = sContext->readPixels(ii, readback.get(), rowBytes, 0, 0);
1031c80e99dd5b23ebc3f10c768857a21887ab9f090Brian Salomon            REPORTER_ASSERT(reporter, result, "Initial A8 readPixels failed");
1049d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1059d02b264b72be64702e43cb797b7899a8a6926cabsalomon            // make sure the original & read back versions match
1069d02b264b72be64702e43cb797b7899a8a6926cabsalomon            SkString msg;
1077e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips            msg.printf("rb:%d A8", SkToU32(rowBytes));
1089d02b264b72be64702e43cb797b7899a8a6926cabsalomon            validate_alpha_data(reporter, X_SIZE, Y_SIZE, readback.get(), nonZeroRowBytes,
10910fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                                alphaData, msg, kAlpha_8_GrPixelConfig);
1109d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1117e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips            // Now try writing to a single channel surface (if we could create one).
1127e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips            if (surf) {
1137715e06b68a1f07f07d23c63e7128d32654e30e9robertphillips                SkCanvas* canvas = surf->getCanvas();
1149d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1159d02b264b72be64702e43cb797b7899a8a6926cabsalomon                SkPaint paint;
1169d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1179d02b264b72be64702e43cb797b7899a8a6926cabsalomon                const SkRect rect = SkRect::MakeLTRB(-10, -10, X_SIZE + 10, Y_SIZE + 10);
1189d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1199d02b264b72be64702e43cb797b7899a8a6926cabsalomon                paint.setColor(SK_ColorWHITE);
1209d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1217715e06b68a1f07f07d23c63e7128d32654e30e9robertphillips                canvas->drawRect(rect, paint);
1229d02b264b72be64702e43cb797b7899a8a6926cabsalomon
12310fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                // Workaround for a bug in old GCC/glibc used in our Chromecast toolchain:
12410fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                // error: call to '__warn_memset_zero_len' declared with attribute warning:
12510fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                //        memset used with constant zero length parameter; this could be due
12610fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                //        to transposed parameters
12710fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                // See also: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61294
12810fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                if (bufLen > 0) {
12910fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                    memset(readback.get(), kClearValue, bufLen);
13010fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                }
1317e922765545f42ce691e4f3d5fbbd4e44ba47ff1robertphillips                result = surf->readPixels(ii, readback.get(), nonZeroRowBytes, 0, 0);
1321c80e99dd5b23ebc3f10c768857a21887ab9f090Brian Salomon                REPORTER_ASSERT(reporter, result, "A8 readPixels after clear failed");
1339d02b264b72be64702e43cb797b7899a8a6926cabsalomon
1349d02b264b72be64702e43cb797b7899a8a6926cabsalomon                match = true;
1359d02b264b72be64702e43cb797b7899a8a6926cabsalomon                for (int y = 0; y < Y_SIZE && match; ++y) {
1369d02b264b72be64702e43cb797b7899a8a6926cabsalomon                    for (int x = 0; x < X_SIZE && match; ++x) {
1379d02b264b72be64702e43cb797b7899a8a6926cabsalomon                        uint8_t rbValue = readback.get()[y * nonZeroRowBytes + x];
1389d02b264b72be64702e43cb797b7899a8a6926cabsalomon                        if (0xFF != rbValue) {
1399d02b264b72be64702e43cb797b7899a8a6926cabsalomon                            ERRORF(reporter,
1409d02b264b72be64702e43cb797b7899a8a6926cabsalomon                                   "Failed alpha readback after clear. Expected: 0xFF, Got: 0x%02x"
1412ea6ff7f0d2f8f578460de8dd4e2e4ad3eed6e4cBrian Salomon                                   " at (%d,%d), rb:%d", rbValue, x, y, SkToU32(rowBytes));
1429d02b264b72be64702e43cb797b7899a8a6926cabsalomon                            match = false;
1439d02b264b72be64702e43cb797b7899a8a6926cabsalomon                        }
144e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    }
145e9573317d35d08254412eb407211f3607f8f74fbbsalomon                }
146b76afedf11c7fe933954d030048c3222860249e1bsalomon            }
147b76afedf11c7fe933954d030048c3222860249e1bsalomon        }
148b76afedf11c7fe933954d030048c3222860249e1bsalomon    }
14923e566664b85472766c921cd2f5615c846919934bsalomon
150e9573317d35d08254412eb407211f3607f8f74fbbsalomon    static const GrPixelConfig kRGBAConfigs[] {
151e9573317d35d08254412eb407211f3607f8f74fbbsalomon        kRGBA_8888_GrPixelConfig,
152e9573317d35d08254412eb407211f3607f8f74fbbsalomon        kBGRA_8888_GrPixelConfig,
15310fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman        kSRGBA_8888_GrPixelConfig,
15410fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman        kRGBA_1010102_GrPixelConfig,
155e9573317d35d08254412eb407211f3607f8f74fbbsalomon    };
156e9573317d35d08254412eb407211f3607f8f74fbbsalomon
1579d02b264b72be64702e43cb797b7899a8a6926cabsalomon    for (int y = 0; y < Y_SIZE; ++y) {
1589d02b264b72be64702e43cb797b7899a8a6926cabsalomon        for (int x = 0; x < X_SIZE; ++x) {
1599d02b264b72be64702e43cb797b7899a8a6926cabsalomon            alphaData[y * X_SIZE + x] = y*X_SIZE+x;
1609d02b264b72be64702e43cb797b7899a8a6926cabsalomon        }
1619d02b264b72be64702e43cb797b7899a8a6926cabsalomon    }
1629d02b264b72be64702e43cb797b7899a8a6926cabsalomon
163bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips    const SkImageInfo dstInfo = SkImageInfo::Make(X_SIZE, Y_SIZE,
164bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips                                                  kAlpha_8_SkColorType,
165bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips                                                  kPremul_SkAlphaType);
166bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips
167e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // Attempt to read back just alpha from a RGBA/BGRA texture. Once with a texture-only src and
168e9573317d35d08254412eb407211f3607f8f74fbbsalomon    // once with a render target.
169bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips    for (auto config : kRGBAConfigs) {
170e9573317d35d08254412eb407211f3607f8f74fbbsalomon        for (int rt = 0; rt < 2; ++rt) {
171e9573317d35d08254412eb407211f3607f8f74fbbsalomon            GrSurfaceDesc desc;
172e9573317d35d08254412eb407211f3607f8f74fbbsalomon            desc.fFlags     = rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
173e44ef10ebbc7f64b627a9ac3a562bd87b3001b0cRobert Phillips            desc.fOrigin    = rt ? kBottomLeft_GrSurfaceOrigin : kTopLeft_GrSurfaceOrigin;
174bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips            desc.fConfig    = config;
175e9573317d35d08254412eb407211f3607f8f74fbbsalomon            desc.fWidth     = X_SIZE;
176e9573317d35d08254412eb407211f3607f8f74fbbsalomon            desc.fHeight    = Y_SIZE;
177e9573317d35d08254412eb407211f3607f8f74fbbsalomon
1789d02b264b72be64702e43cb797b7899a8a6926cabsalomon            uint32_t rgbaData[X_SIZE * Y_SIZE];
179e9573317d35d08254412eb407211f3607f8f74fbbsalomon            // Make the alpha channel of the rgba texture come from alphaData.
180e9573317d35d08254412eb407211f3607f8f74fbbsalomon            for (int y = 0; y < Y_SIZE; ++y) {
181e9573317d35d08254412eb407211f3607f8f74fbbsalomon                for (int x = 0; x < X_SIZE; ++x) {
1829d02b264b72be64702e43cb797b7899a8a6926cabsalomon                    rgbaData[y * X_SIZE + x] = GrColorPackRGBA(6, 7, 8, alphaData[y * X_SIZE + x]);
183e9573317d35d08254412eb407211f3607f8f74fbbsalomon                }
184e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
1850bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips
1860bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips            sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kNo,
1870bd24dc41f2351d84f5fce32130668a5792d134bRobert Phillips                                                                            rgbaData, 0);
188e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips            if (!proxy) {
189e9573317d35d08254412eb407211f3607f8f74fbbsalomon                // We always expect to be able to create a RGBA texture
190e9573317d35d08254412eb407211f3607f8f74fbbsalomon                if (!rt  && kRGBA_8888_GrPixelConfig == desc.fConfig) {
191e9573317d35d08254412eb407211f3607f8f74fbbsalomon                    ERRORF(reporter, "Failed to create RGBA texture.");
192e9573317d35d08254412eb407211f3607f8f74fbbsalomon                }
193e9573317d35d08254412eb407211f3607f8f74fbbsalomon                continue;
194e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
195e9573317d35d08254412eb407211f3607f8f74fbbsalomon
196366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon            sk_sp<SkColorSpace> colorSpace;
197366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon            if (GrPixelConfigIsSRGB(proxy->config())) {
198366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon                colorSpace = SkColorSpace::MakeSRGB();
199366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon            }
200bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips            sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
201366093f2124c38fa5c590c9ed2d1811817fed8eeBrian Salomon                    std::move(proxy), std::move(colorSpace));
202bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips
2039d02b264b72be64702e43cb797b7899a8a6926cabsalomon            for (auto rowBytes : kRowBytes) {
2049d02b264b72be64702e43cb797b7899a8a6926cabsalomon                size_t nonZeroRowBytes = rowBytes ? rowBytes : X_SIZE;
205e9573317d35d08254412eb407211f3607f8f74fbbsalomon
2067ecc59610de72043e9b7ebaf1ef45c43425e54fcBen Wagner                std::unique_ptr<uint8_t[]> readback(new uint8_t[nonZeroRowBytes * Y_SIZE]);
2079d02b264b72be64702e43cb797b7899a8a6926cabsalomon                // Clear so we don't accidentally see values from previous iteration.
208df082c54257256ca7570fb3a75852d2af4e6a80crobertphillips                memset(readback.get(), kClearValue, nonZeroRowBytes * Y_SIZE);
2099d02b264b72be64702e43cb797b7899a8a6926cabsalomon
2109d02b264b72be64702e43cb797b7899a8a6926cabsalomon                // read the texture back
211bab2dbb5fa50da8e8365abbaa9f1490e659f436cRobert Phillips                bool result = sContext->readPixels(dstInfo, readback.get(), rowBytes, 0, 0);
2121c80e99dd5b23ebc3f10c768857a21887ab9f090Brian Salomon                REPORTER_ASSERT(reporter, result, "8888 readPixels failed");
2139d02b264b72be64702e43cb797b7899a8a6926cabsalomon
2149d02b264b72be64702e43cb797b7899a8a6926cabsalomon                // make sure the original & read back versions match
2159d02b264b72be64702e43cb797b7899a8a6926cabsalomon                SkString msg;
216df082c54257256ca7570fb3a75852d2af4e6a80crobertphillips                msg.printf("rt:%d, rb:%d 8888", rt, SkToU32(rowBytes));
2179d02b264b72be64702e43cb797b7899a8a6926cabsalomon                validate_alpha_data(reporter, X_SIZE, Y_SIZE, readback.get(), nonZeroRowBytes,
21810fc6fddf24878f4f34e75c1bcc11e4499edfcc0Brian Osman                                    alphaData, msg, config);
219e9573317d35d08254412eb407211f3607f8f74fbbsalomon            }
220e9573317d35d08254412eb407211f3607f8f74fbbsalomon        }
221e9573317d35d08254412eb407211f3607f8f74fbbsalomon    }
2226995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com}
2236995068c5ade6e179d2af82caddb0c1cd6f433b6robertphillips@google.com
224cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
225