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