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
11c65aec97619682b2c0191554f44ddf35f618a94dBrian Salomon#include "GrClip.h"
12bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrContext.h"
13e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips#include "GrContextPriv.h"
14bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrRenderTargetContext.h"
1532342f032e1dfd133040324f851f0365f9d4cb51Brian Osman#include "GrResourceProvider.h"
16bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "GrTexture.h"
17bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#include "effects/GrSimpleTextureEffect.h"
18bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
19bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomontemplate <typename I>
20bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomonstatic SK_WHEN(std::is_integral<I>::value && 4 == sizeof(I), void)
2107792b218e1cf31c42611276d597fcc99677d391Brian Osmancheck_pixels(skiatest::Reporter* reporter, int w, int h, const I exepctedData[],
2207792b218e1cf31c42611276d597fcc99677d391Brian Osman             const I actualData[], const char* testName) {
23bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int j = 0; j < h; ++j) {
24bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        for (int i = 0; i < w; ++i) {
25bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            I expected = exepctedData[j * w + i];
26bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            I actual = actualData[j * w + i];
27bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            if (expected != actual) {
2807792b218e1cf31c42611276d597fcc99677d391Brian Osman                ERRORF(reporter, "[%s] Expected 0x08%x, got 0x%08x at %d, %d.", testName, expected,
2907792b218e1cf31c42611276d597fcc99677d391Brian Osman                       actual, i, j);
30bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                return;
31bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            }
32bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
33bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
34bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon}
35bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
36bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian SalomonDEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) {
37bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    GrContext* context = ctxInfo.grContext();
38bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    if (!context->caps()->isConfigTexturable(kRGBA_8888_sint_GrPixelConfig)) {
39bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        return;
40bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
41bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    static const int kS = UINT8_MAX + 1;
42d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    static const size_t kRowBytes = kS * sizeof(int32_t);
43d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
44bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    GrSurfaceDesc desc;
45b7b7e5fba08399c76fa0763ec3ed49ae120b64d8Robert Phillips    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
46bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fConfig = kRGBA_8888_sint_GrPixelConfig;
47bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fWidth = kS;
48bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    desc.fHeight = kS;
49bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
50bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<int32_t[]> testData(new int32_t[kS * kS]);
51bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int j = 0; j < kS; ++j) {
52bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        for (int i = 0; i < kS; ++i) {
53bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t r = i - INT8_MIN;
54bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t g = j - INT8_MIN;
55bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t b = INT8_MAX - r;
56bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            uint32_t a = INT8_MAX - g;
57bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            testData.get()[j * kS + i] = (a << 24) | (b << 16) | (g << 8) | r;
58bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
59bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
60bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
61d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that attempting to create a integer texture with multiple MIP levels fails.
62d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
63d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        GrMipLevel levels[2];
64d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[0].fPixels = testData.get();
65d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[0].fRowBytes = kRowBytes;
66d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[1].fPixels = testData.get();
67d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        levels[1].fRowBytes = (kS / 2) * sizeof(int32_t);
68d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
698e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips        sk_sp<GrTextureProxy> temp(GrSurfaceProxy::MakeDeferredMipMap(context->resourceProvider(),
708e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                                                      desc,
718e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                                                      SkBudgeted::kYes,
728e8c755f56e5dbaf0f87d88a775632010b32e974Robert Phillips                                                                      levels, 2));
73d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !temp);
74d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
75d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
76d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that we can create an integer texture.
7726c90e04797e15c37ec00e0f836292b8a207d294Robert Phillips    sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(context->resourceProvider(),
782f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               desc, SkBudgeted::kYes,
792f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               testData.get(),
802f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips                                                               kRowBytes);
81d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    REPORTER_ASSERT(reporter, proxy);
822f49314227053dd5acc011e04681faee05c5e0ffRobert Phillips    if (!proxy) {
83d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        return;
84d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
85d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
86f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips    sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeWrappedSurfaceContext(
87f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                                    std::move(proxy), nullptr);
88f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips    if (!sContext) {
89f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        return;
90f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips    }
91f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips
92bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<int32_t[]> readData(new int32_t[kS * kS]);
93d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    // Test that reading to a non-integer config fails.
94d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
95f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
96e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                0, 0, kS, kS,
97e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                kRGBA_8888_GrPixelConfig,
98e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                nullptr, readData.get());
99d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
100d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
101d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
102d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        std::unique_ptr<uint16_t[]> halfData(new uint16_t[4 * kS * kS]);
103f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
104e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                0, 0, kS, kS,
105e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                kRGBA_half_GrPixelConfig,
106e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                nullptr, halfData.get());
107d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
108d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
109d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
110d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can read back as ints. (ES only requires being able to read back into 32bit ints which
111d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // we don't support. Right now this test is counting on GR_RGBA_INTEGER/GL_BYTE being the
112d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // implementation-dependent second format).
113d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
114f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
115e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                0, 0, kS, kS,
116e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                kRGBA_8888_sint_GrPixelConfig,
117e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                nullptr, readData.get());
118d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
119d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (success) {
120d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "readPixels");
121d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
122d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
123d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
124d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // readPixels should fail if we attempt to use the unpremul flag with an integer texture.
125e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips        bool success = context->contextPriv().readSurfacePixels(
126f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                sContext.get(),
127e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                0, 0, kS, kS,
128e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                kRGBA_8888_sint_GrPixelConfig,
129e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                nullptr, readData.get(), 0,
130e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                GrContextPriv::kUnpremul_PixelOpsFlag);
131d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
132d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
133bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
134bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // Test that copying from one integer texture to another succeeds.
135e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    {
136d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, desc,
137f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                                    sContext->asSurfaceProxy()));
138d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, dstContext);
139f200a90f3e58ce20753420cadced850d7d00dca1Robert Phillips        if (!dstContext || !dstContext->asTextureProxy()) {
140e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips            return;
141e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        }
142e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
143e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
144f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().readSurfacePixels(dstContext.get(), 0, 0, kS, kS,
145e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                kRGBA_8888_sint_GrPixelConfig,
146e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                nullptr, readData.get());
147e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        REPORTER_ASSERT(reporter, success);
148e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        if (success) {
14907792b218e1cf31c42611276d597fcc99677d391Brian Osman            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "copyIntegerToInteger");
150e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        }
151293d696fcfb9f1c83019c4b15c4864cd6649ed78Robert Phillips    }
152398487a850431cf495330d4023607df5305a311fRobert Phillips
153e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
154e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Test that copying to a non-integer (8888) texture fails.
155e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    {
156e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        GrSurfaceDesc nonIntDesc = desc;
157e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig;
158e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
159d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
160f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                                    sContext->asSurfaceProxy()));
161d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !dstContext);
162d316e77c1e1967b439a9a6c11146c54e367bff71Robert Phillips    }
163e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
164e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    // Test that copying to a non-integer (RGBA_half) texture fails.
165e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips    if (context->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
166e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        GrSurfaceDesc nonIntDesc = desc;
167e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips        nonIntDesc.fConfig = kRGBA_half_GrPixelConfig;
168e2f7d1899d890c2f08571e1bd6c7fa2c5ea1be0bRobert Phillips
169d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
170f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                                    sContext->asSurfaceProxy()));
171d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !dstContext);
172bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
173bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
174bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // We overwrite the top left quarter of the texture with the bottom right quarter of the
175bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // original data.
176bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    const void* bottomRightQuarter = testData.get() + kS / 2 * kS + kS / 2;
177d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
178d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
179d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can't write pixels from a non-int config.
180f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().writeSurfacePixels(sContext.get(),
181e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 0, 0, kS/2, kS/2,
182e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 kRGBA_8888_GrPixelConfig, nullptr,
183e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 bottomRightQuarter, kRowBytes);
184d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
185bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
186d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
187d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // Can't use unpremul flag.
188e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips        bool success = context->contextPriv().writeSurfacePixels(
189f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                            sContext.get(),
190e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                            0, 0, kS/2, kS/2,
191e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                            kRGBA_8888_sint_GrPixelConfig,
192e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                            nullptr,
193d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips                                            bottomRightQuarter, kRowBytes,
194e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                            GrContextPriv::kUnpremul_PixelOpsFlag);
195d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !success);
196bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
197d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
198f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        bool success = context->contextPriv().writeSurfacePixels(sContext.get(),
199e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 0, 0, kS/2, kS/2,
200e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 kRGBA_8888_sint_GrPixelConfig,
201e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 nullptr,
202e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                                 bottomRightQuarter, kRowBytes);
203d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
204d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (!success) {
205d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            return;
206d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
207d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips
208d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
209f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips        success = context->contextPriv().readSurfacePixels(sContext.get(),
210e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                           0, 0, kS, kS,
211e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                           kRGBA_8888_sint_GrPixelConfig,
212e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                                           nullptr, readData.get(), 0);
213d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, success);
214d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        if (!success) {
215d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            return;
216d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
217d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        std::unique_ptr<int32_t[]> overwrittenTestData(new int32_t[kS * kS]);
218d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        memcpy(overwrittenTestData.get(), testData.get(), sizeof(int32_t) * kS * kS);
219d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        char* dst = (char*)overwrittenTestData.get();
220d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        char* src = (char*)(testData.get() + kS/2 * kS + kS/2);
221d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        for (int i = 0; i < kS/2; ++i) {
222d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            memcpy(dst, src, sizeof(int32_t) * kS/2);
223d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            dst += kRowBytes;
224d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips            src += kRowBytes;
225d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        }
226d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        check_pixels(reporter, kS, kS, overwrittenTestData.get(), readData.get(), "overwrite");
227bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
228bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
229bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // Test drawing from the integer texture to a fixed point texture. To avoid any premul issues
230bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // we init the int texture with 0s and 1s and make alpha always be 1. We expect that 1s turn
231bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    // into 0xffs and zeros stay zero.
232bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<uint32_t[]> expectedData(new uint32_t[kS * kS]);
233bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    std::unique_ptr<uint32_t[]> actualData(new uint32_t[kS * kS]);
234bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    for (int i = 0; i < kS*kS; ++i) {
235bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t a = 0x1;
236bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t b = ((i & 0x1) ? 1 : 0);
237bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t g = ((i & 0x1) ? 0 : 1);
238bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        int32_t r = ((i & 0x2) ? 1 : 0);
239bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        testData.get()[i] = (a << 24) | (b << 16) | (g << 8) | r;
240bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        expectedData.get()[i] = ((0xFF * a) << 24) | ((0xFF * b) << 16) |
241bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                                ((0xFF * g) << 8) | (0xFF * r);
242bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
243f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips    context->contextPriv().writeSurfacePixels(sContext.get(),
244e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                              0, 0, kS, kS,
245e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                              kRGBA_8888_sint_GrPixelConfig, nullptr,
246e78b7259c3d5cbed77b4390150cfb699b0b59cd4Robert Phillips                                              testData.get(), 0);
247769e80d23d1c1d240b1d510034ec57d19e768d07Robert Phillips
248dd3b3f41829d32d7eaf3eb4903570d49c2ba9ff8Robert Phillips    sk_sp<GrRenderTargetContext> rtContext = context->makeDeferredRenderTargetContext(
249bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            SkBackingFit::kExact, kS, kS, kRGBA_8888_GrPixelConfig, nullptr);
250bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
25107792b218e1cf31c42611276d597fcc99677d391Brian Osman    struct {
25207792b218e1cf31c42611276d597fcc99677d391Brian Osman        GrSamplerParams::FilterMode fMode;
25307792b218e1cf31c42611276d597fcc99677d391Brian Osman        const char* fName;
25407792b218e1cf31c42611276d597fcc99677d391Brian Osman    } kNamedFilters[] ={
25507792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kNone_FilterMode, "filter-none" },
25607792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kBilerp_FilterMode, "filter-bilerp" },
25707792b218e1cf31c42611276d597fcc99677d391Brian Osman        { GrSamplerParams::kMipMap_FilterMode, "filter-mipmap" }
25807792b218e1cf31c42611276d597fcc99677d391Brian Osman    };
25907792b218e1cf31c42611276d597fcc99677d391Brian Osman
26007792b218e1cf31c42611276d597fcc99677d391Brian Osman    for (auto filter : kNamedFilters) {
261fbcef6eb8abad142daf45418516550f7635b4a52Robert Phillips        sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(sContext->asTextureProxyRef(),
262f41c22fca369af85b06ff34bae8a41c6672aff43Robert Phillips                                                                  nullptr,
26367c18d6b5188a0497f6912a73d964c763d2f8f84Robert Phillips                                                                  SkMatrix::I(),
26407792b218e1cf31c42611276d597fcc99677d391Brian Osman                                                                  filter.fMode));
265bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        REPORTER_ASSERT(reporter, fp);
266bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        if (!fp) {
267bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon            return;
268bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        }
269bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        rtContext->clear(nullptr, 0xDDAABBCC, true);
270bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        GrPaint paint;
271bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
272bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        paint.addColorFragmentProcessor(fp);
27382f44319159bb98dcacdbbec7ea643dde5ed024bBrian Salomon        rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
274bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        SkImageInfo readInfo = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
275bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon                                                 kPremul_SkAlphaType);
276bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon        rtContext->readPixels(readInfo, actualData.get(), 0, 0, 0);
27707792b218e1cf31c42611276d597fcc99677d391Brian Osman        check_pixels(reporter, kS, kS, expectedData.get(), actualData.get(), filter.fName);
278bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon    }
279bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
280d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    {
281d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        // No rendering to integer textures.
282d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        GrSurfaceDesc intRTDesc = desc;
283d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        intRTDesc.fFlags = kRenderTarget_GrSurfaceFlag;
28432342f032e1dfd133040324f851f0365f9d4cb51Brian Osman        sk_sp<GrTexture> temp(context->resourceProvider()->createTexture(intRTDesc,
28532342f032e1dfd133040324f851f0365f9d4cb51Brian Osman                                                                         SkBudgeted::kYes));
286d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips        REPORTER_ASSERT(reporter, !temp);
287d46697ac36d5cb3b58571c6129cb5b26fe9d25d7Robert Phillips    }
288bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon}
289bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon
290bf7b620b1e44985b164a8bd68031a7613fe0bb9bBrian Salomon#endif
291