IntTextureTest.cpp revision 32342f032e1dfd133040324f851f0365f9d4cb51
1bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon/*
2bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon * Copyright 2016 Google Inc.
3bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon *
4bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon * Use of this source code is governed by a BSD-style license that can be
5bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon * found in the LICENSE file.
6bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon */
7bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
8bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "Test.h"
9bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
10bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#if SK_SUPPORT_GPU
11bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrContext.h"
12bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrRenderTargetContext.h"
1332342f032e1dfd133040324f851f0365f9d4cb51Brian Osman#include "GrResourceProvider.h"
14bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrTexture.h"
15bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "effects/GrSimpleTextureEffect.h"
16bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
17bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomontemplate <typename I>
18bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomonstatic SK_WHEN(std::is_integral<I>::value && 4 == sizeof(I), void)
1907792b218e1cf31c42611276d597fcc99677d391Brian Osmancheck_pixels(skiatest::Reporter* reporter, int w, int h, const I exepctedData[],
2007792b218e1cf31c42611276d597fcc99677d391Brian Osman             const I actualData[], const char* testName) {
21bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int j = 0; j < h; ++j) {
22bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        for (int i = 0; i < w; ++i) {
23bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            I expected = exepctedData[j * w + i];
24bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            I actual = actualData[j * w + i];
25bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            if (expected != actual) {
2607792b218e1cf31c42611276d597fcc99677d391Brian Osman                ERRORF(reporter, "[%s] Expected 0x08%x, got 0x%08x at %d, %d.", testName, expected,
2707792b218e1cf31c42611276d597fcc99677d391Brian Osman                       actual, i, j);
28bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                return;
29bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            }
30bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
31bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
32bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon}
33bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
34bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian SalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) {
35bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    GrContext* context = ctxInfo.grContext();
36bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (!context->caps()->isConfigTexturable(kRGBA_8888_sint_GrPixelConfig)) {
37bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        return;
38bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
39bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    static const int kS = UINT8_MAX + 1;
40d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    static const size_t kRowBytes = kS * sizeof(int32_t);
41d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
42bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    GrSurfaceDesc desc;
43bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fConfig = kRGBA_8888_sint_GrPixelConfig;
44bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fWidth = kS;
45bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fHeight = kS;
46bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
47bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<int32_t[]> testData(new int32_t[kS * kS]);
48bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int j = 0; j < kS; ++j) {
49bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        for (int i = 0; i < kS; ++i) {
50bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t r = i - INT8_MIN;
51bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t g = j - INT8_MIN;
52bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t b = INT8_MAX - r;
53bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t a = INT8_MAX - g;
54bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            testData.get()[j * kS + i] = (a << 24) | (b << 16) | (g << 8) | r;
55bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
56bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
57bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
58d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that attempting to create a integer texture with multiple MIP levels fails.
59d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
60d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        GrMipLevel levels[2];
61d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[0].fPixels = testData.get();
62d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[0].fRowBytes = kRowBytes;
63d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[1].fPixels = testData.get();
64d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[1].fRowBytes = (kS / 2) * sizeof(int32_t);
65d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
6632342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        sk_sp<GrTexture> temp(context->resourceProvider()->createMipMappedTexture(desc,
6732342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                                                  SkBudgeted::kYes,
6832342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                                                  levels, 2));
69d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !temp);
70d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
71d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
72d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that we can create an integer texture.
732f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(*context->caps(),
7432342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                               context->resourceProvider(),
752f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               desc, SkBudgeted::kYes,
762f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               testData.get(),
772f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               kRowBytes);
78d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    REPORTER_ASSERT(reporter, proxy);
792f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    if (!proxy) {
80d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        return;
81d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
82d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
8332342f032e1dfd133040324f851f0365f9d4cb51Brian Osman    GrTexture* texture = proxy->instantiate(context->resourceProvider());
84bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    REPORTER_ASSERT(reporter, texture);
85bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (!texture) {
86bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        return;
87bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
88bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
89bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<int32_t[]> readData(new int32_t[kS * kS]);
90d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that reading to a non-integer config fails.
91d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
92d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_GrPixelConfig, readData.get());
93d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
94d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
95d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
96d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        std::unique_ptr<uint16_t[]> halfData(new uint16_t[4 * kS * kS]);
97d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->readPixels(0, 0, kS, kS, kRGBA_half_GrPixelConfig, halfData.get());
98d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
99d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
100d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
101d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can read back as ints. (ES only requires being able to read back into 32bit ints which
102d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // we don't support. Right now this test is counting on GR_RGBA_INTEGER/GL_BYTE being the
103d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // implementation-dependent second format).
104d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
105d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig,
106d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                           readData.get());
107d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
108d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (success) {
109d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "readPixels");
110d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
111d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
112d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
113d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // readPixels should fail if we attempt to use the unpremul flag with an integer texture.
114d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig,
115d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                           readData.get(), 0, GrContext::kUnpremul_PixelOpsFlag);
116d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
117d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
118bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
119bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // Test that copying from one integer texture to another succeeds.
120e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    {
121d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, desc,
122d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                                                    proxy.get()));
123d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, dstContext);
124f200a90f3e58ce20753420cadced850d7d00dca1Robert Phillips        if (!dstContext || !dstContext->asTextureProxy()) {
125e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips            return;
126e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        }
127e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
128f200a90f3e58ce20753420cadced850d7d00dca1Robert Phillips        GrSurface* copySurface = dstContext->asTextureProxy()->instantiate(
12932342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                                    context->resourceProvider());
130e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        REPORTER_ASSERT(reporter, copySurface);
131e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        if (!copySurface) {
132e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips            return;
133e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        }
134e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
135e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
136d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = copySurface->readPixels(0, 0, kS, kS,
137d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                               kRGBA_8888_sint_GrPixelConfig, readData.get());
138e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        REPORTER_ASSERT(reporter, success);
139e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        if (success) {
14007792b218e1cf31c42611276d597fcc99677d391Brian Osman            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "copyIntegerToInteger");
141e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        }
142293d696fcfb9f1c83019c4b15c4864cd6649ed78Robert Phillips    }
143398487a850431cf495330d4023607df5305a311fRobert Phillips
144e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
145e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Test that copying to a non-integer (8888) texture fails.
146e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    {
147e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        GrSurfaceDesc nonIntDesc = desc;
148e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig;
149e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
150d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
151d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                                                    proxy.get()));
152d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !dstContext);
153d316e77c1e1967b439a9a6c11146c54e367bff71Robert Phillips    }
154e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
155e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Test that copying to a non-integer (RGBA_half) texture fails.
156e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    if (context->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
157e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        GrSurfaceDesc nonIntDesc = desc;
158e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        nonIntDesc.fConfig = kRGBA_half_GrPixelConfig;
159e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
160d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
161d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                                                    proxy.get()));
162d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !dstContext);
163bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
164bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
165bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // We overwrite the top left quarter of the texture with the bottom right quarter of the
166bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // original data.
167bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    const void* bottomRightQuarter = testData.get() + kS / 2 * kS + kS / 2;
168d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
169d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
170d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can't write pixels from a non-int config.
171d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_GrPixelConfig,
172d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            bottomRightQuarter, kRowBytes);
173d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
174bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
175d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
176d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can't use unpremul flag.
177d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig,
178d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            bottomRightQuarter, kRowBytes,
179d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            GrContext::kUnpremul_PixelOpsFlag);
180d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
181bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
182d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
183d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig,
184d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            bottomRightQuarter, kRowBytes);
185d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
186d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (!success) {
187d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            return;
188d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
189d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
190d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
191d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get());
192d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
193d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (!success) {
194d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            return;
195d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
196d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        std::unique_ptr<int32_t[]> overwrittenTestData(new int32_t[kS * kS]);
197d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        memcpy(overwrittenTestData.get(), testData.get(), sizeof(int32_t) * kS * kS);
198d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        char* dst = (char*)overwrittenTestData.get();
199d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        char* src = (char*)(testData.get() + kS/2 * kS + kS/2);
200d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        for (int i = 0; i < kS/2; ++i) {
201d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            memcpy(dst, src, sizeof(int32_t) * kS/2);
202d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            dst += kRowBytes;
203d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            src += kRowBytes;
204d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
205d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        check_pixels(reporter, kS, kS, overwrittenTestData.get(), readData.get(), "overwrite");
206bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
207bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
208bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // Test drawing from the integer texture to a fixed point texture. To avoid any premul issues
209bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // we init the int texture with 0s and 1s and make alpha always be 1. We expect that 1s turn
210bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // into 0xffs and zeros stay zero.
211bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<uint32_t[]> expectedData(new uint32_t[kS * kS]);
212bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<uint32_t[]> actualData(new uint32_t[kS * kS]);
213bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int i = 0; i < kS*kS; ++i) {
214bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t a = 0x1;
215bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t b = ((i & 0x1) ? 1 : 0);
216bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t g = ((i & 0x1) ? 0 : 1);
217bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t r = ((i & 0x2) ? 1 : 0);
218bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        testData.get()[i] = (a << 24) | (b << 16) | (g << 8) | r;
219bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        expectedData.get()[i] = ((0xFF * a) << 24) | ((0xFF * b) << 16) |
220bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                                ((0xFF * g) << 8) | (0xFF * r);
221bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
222bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    texture->writePixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, testData.get());
223d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
224bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    sk_sp<GrRenderTargetContext> rtContext = context->makeRenderTargetContext(
225bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            SkBackingFit::kExact, kS, kS, kRGBA_8888_GrPixelConfig, nullptr);
226bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
22707792b218e1cf31c42611276d597fcc99677d391Brian Osman    struct {
22807792b218e1cf31c42611276d597fcc99677d391Brian Osman        GrSamplerParams::FilterMode fMode;
22907792b218e1cf31c42611276d597fcc99677d391Brian Osman        const char* fName;
23007792b218e1cf31c42611276d597fcc99677d391Brian Osman    } kNamedFilters[] ={
23107792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kNone_FilterMode, "filter-none" },
23207792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kBilerp_FilterMode, "filter-bilerp" },
23307792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kMipMap_FilterMode, "filter-mipmap" }
23407792b218e1cf31c42611276d597fcc99677d391Brian Osman    };
23507792b218e1cf31c42611276d597fcc99677d391Brian Osman
23607792b218e1cf31c42611276d597fcc99677d391Brian Osman    for (auto filter : kNamedFilters) {
237d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(texture, nullptr,
23867c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips                                                                  SkMatrix::I(),
23907792b218e1cf31c42611276d597fcc99677d391Brian Osman                                                                  filter.fMode));
240bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        REPORTER_ASSERT(reporter, fp);
241bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        if (!fp) {
242bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            return;
243bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
244bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        rtContext->clear(nullptr, 0xDDAABBCC, true);
245bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        GrPaint paint;
246bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
247bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        paint.addColorFragmentProcessor(fp);
24882f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
249bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        SkImageInfo readInfo = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
250bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                                                 kPremul_SkAlphaType);
251bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        rtContext->readPixels(readInfo, actualData.get(), 0, 0, 0);
25207792b218e1cf31c42611276d597fcc99677d391Brian Osman        check_pixels(reporter, kS, kS, expectedData.get(), actualData.get(), filter.fName);
253bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
254bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
255d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
256d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // No rendering to integer textures.
257d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        GrSurfaceDesc intRTDesc = desc;
258d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        intRTDesc.fFlags = kRenderTarget_GrSurfaceFlag;
25932342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        sk_sp<GrTexture> temp(context->resourceProvider()->createTexture(intRTDesc,
26032342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                                         SkBudgeted::kYes));
261d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !temp);
262d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
263bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon}
264bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
265bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#endif
266