1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "tests/Test.h" 9cb93a386Sopenharmony_ci#include "tests/TestUtils.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrProxyProvider.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 15cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 16cb93a386Sopenharmony_ci#include "src/gpu/SurfaceFillContext.h" 17cb93a386Sopenharmony_ci#include "src/gpu/effects/GrTextureEffect.h" 18cb93a386Sopenharmony_ci#ifdef SK_GL 19cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLGpu.h" 20cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLUtil.h" 21cb93a386Sopenharmony_ci#endif 22cb93a386Sopenharmony_ci#include "tools/gpu/ProxyUtils.h" 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci// skbug.com/5932 25cb93a386Sopenharmony_cistatic void test_basic_draw_as_src(skiatest::Reporter* reporter, GrDirectContext* dContext, 26cb93a386Sopenharmony_ci GrSurfaceProxyView rectView, GrColorType colorType, 27cb93a386Sopenharmony_ci SkAlphaType alphaType, uint32_t expectedPixelValues[]) { 28cb93a386Sopenharmony_ci auto sfc = dContext->priv().makeSFC( 29cb93a386Sopenharmony_ci {colorType, kPremul_SkAlphaType, nullptr, rectView.dimensions()}); 30cb93a386Sopenharmony_ci for (auto filter : {GrSamplerState::Filter::kNearest, GrSamplerState::Filter::kLinear}) { 31cb93a386Sopenharmony_ci for (auto mm : {GrSamplerState::MipmapMode::kNone, GrSamplerState::MipmapMode::kLinear}) { 32cb93a386Sopenharmony_ci sfc->clear(SkPMColor4f::FromBytes_RGBA(0xDDCCBBAA)); 33cb93a386Sopenharmony_ci auto fp = GrTextureEffect::Make(rectView, alphaType, SkMatrix::I(), filter, mm); 34cb93a386Sopenharmony_ci sfc->fillWithFP(std::move(fp)); 35cb93a386Sopenharmony_ci TestReadPixels(reporter, dContext, sfc.get(), expectedPixelValues, 36cb93a386Sopenharmony_ci "RectangleTexture-basic-draw"); 37cb93a386Sopenharmony_ci } 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci} 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_cistatic void test_clear(skiatest::Reporter* reporter, GrDirectContext* dContext, 42cb93a386Sopenharmony_ci skgpu::SurfaceContext* rectContext) { 43cb93a386Sopenharmony_ci if (auto sfc = rectContext->asFillContext()) { 44cb93a386Sopenharmony_ci // Clear the whole thing. 45cb93a386Sopenharmony_ci GrColor color0 = GrColorPackRGBA(0xA, 0xB, 0xC, 0xD); 46cb93a386Sopenharmony_ci sfc->clear(SkPMColor4f::FromBytes_RGBA(color0)); 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ci int w = sfc->width(); 49cb93a386Sopenharmony_ci int h = sfc->height(); 50cb93a386Sopenharmony_ci int pixelCnt = w * h; 51cb93a386Sopenharmony_ci SkAutoTMalloc<uint32_t> expectedPixels(pixelCnt); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci // The clear color is a GrColor, our readback is to kRGBA_8888, which may be different. 54cb93a386Sopenharmony_ci uint32_t expectedColor0 = 0; 55cb93a386Sopenharmony_ci uint8_t* expectedBytes0 = reinterpret_cast<uint8_t*>(&expectedColor0); 56cb93a386Sopenharmony_ci expectedBytes0[0] = GrColorUnpackR(color0); 57cb93a386Sopenharmony_ci expectedBytes0[1] = GrColorUnpackG(color0); 58cb93a386Sopenharmony_ci expectedBytes0[2] = GrColorUnpackB(color0); 59cb93a386Sopenharmony_ci expectedBytes0[3] = GrColorUnpackA(color0); 60cb93a386Sopenharmony_ci for (int i = 0; i < sfc->width() * sfc->height(); ++i) { 61cb93a386Sopenharmony_ci expectedPixels.get()[i] = expectedColor0; 62cb93a386Sopenharmony_ci } 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci // Clear the the top to a different color. 65cb93a386Sopenharmony_ci GrColor color1 = GrColorPackRGBA(0x1, 0x2, 0x3, 0x4); 66cb93a386Sopenharmony_ci SkIRect rect = SkIRect::MakeWH(w, h/2); 67cb93a386Sopenharmony_ci sfc->clear(rect, SkPMColor4f::FromBytes_RGBA(color1)); 68cb93a386Sopenharmony_ci 69cb93a386Sopenharmony_ci uint32_t expectedColor1 = 0; 70cb93a386Sopenharmony_ci uint8_t* expectedBytes1 = reinterpret_cast<uint8_t*>(&expectedColor1); 71cb93a386Sopenharmony_ci expectedBytes1[0] = GrColorUnpackR(color1); 72cb93a386Sopenharmony_ci expectedBytes1[1] = GrColorUnpackG(color1); 73cb93a386Sopenharmony_ci expectedBytes1[2] = GrColorUnpackB(color1); 74cb93a386Sopenharmony_ci expectedBytes1[3] = GrColorUnpackA(color1); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci for (int y = 0; y < h/2; ++y) { 77cb93a386Sopenharmony_ci for (int x = 0; x < w; ++x) { 78cb93a386Sopenharmony_ci expectedPixels.get()[y * h + x] = expectedColor1; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci TestReadPixels(reporter, dContext, sfc, expectedPixels.get(), "RectangleTexture-clear"); 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci} 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_cistatic void test_copy_to_surface(skiatest::Reporter* reporter, 87cb93a386Sopenharmony_ci GrDirectContext* dContext, 88cb93a386Sopenharmony_ci skgpu::SurfaceContext* dstContext, 89cb93a386Sopenharmony_ci const char* testName) { 90cb93a386Sopenharmony_ci 91cb93a386Sopenharmony_ci int pixelCnt = dstContext->width() * dstContext->height(); 92cb93a386Sopenharmony_ci SkAutoTMalloc<uint32_t> pixels(pixelCnt); 93cb93a386Sopenharmony_ci for (int y = 0; y < dstContext->width(); ++y) { 94cb93a386Sopenharmony_ci for (int x = 0; x < dstContext->height(); ++x) { 95cb93a386Sopenharmony_ci pixels.get()[y * dstContext->width() + x] = 96cb93a386Sopenharmony_ci SkColorToPremulGrColor(SkColorSetARGB(2*y, y, x, x * y)); 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) { 101cb93a386Sopenharmony_ci auto origin = dstContext->origin(); 102cb93a386Sopenharmony_ci GrImageInfo info(GrColorType::kRGBA_8888, 103cb93a386Sopenharmony_ci kPremul_SkAlphaType, 104cb93a386Sopenharmony_ci nullptr, 105cb93a386Sopenharmony_ci dstContext->dimensions()); 106cb93a386Sopenharmony_ci GrCPixmap pixmap(info, pixels.get(), dstContext->width()*sizeof(uint32_t)); 107cb93a386Sopenharmony_ci auto srcView = sk_gpu_test::MakeTextureProxyViewFromData(dContext, 108cb93a386Sopenharmony_ci renderable, 109cb93a386Sopenharmony_ci origin, 110cb93a386Sopenharmony_ci pixmap); 111cb93a386Sopenharmony_ci // If this assert ever fails we can add a fallback to do copy as draw, but until then we can 112cb93a386Sopenharmony_ci // be more restrictive. 113cb93a386Sopenharmony_ci SkAssertResult(dstContext->testCopy(srcView.refProxy())); 114cb93a386Sopenharmony_ci TestReadPixels(reporter, dContext, dstContext, pixels.get(), testName); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci} 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci#ifdef SK_GL 119cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(RectangleTexture, reporter, ctxInfo) { 120cb93a386Sopenharmony_ci auto dContext = ctxInfo.directContext(); 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ci GrProxyProvider* proxyProvider = dContext->priv().proxyProvider(); 123cb93a386Sopenharmony_ci static const int kWidth = 16; 124cb93a386Sopenharmony_ci static const int kHeight = 16; 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ci uint32_t pixels[kWidth * kHeight]; 127cb93a386Sopenharmony_ci for (int y = 0; y < kHeight; ++y) { 128cb93a386Sopenharmony_ci for (int x = 0; x < kWidth; ++x) { 129cb93a386Sopenharmony_ci pixels[y * kWidth + x] = y * kWidth + x; 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci } 132cb93a386Sopenharmony_ci auto ii = SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType); 133cb93a386Sopenharmony_ci SkPixmap pm(ii, pixels, sizeof(uint32_t)*kWidth); 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) { 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci auto format = GrBackendFormat::MakeGL(GR_GL_RGBA8, GR_GL_TEXTURE_RECTANGLE); 138cb93a386Sopenharmony_ci GrBackendTexture rectangleTex = dContext->createBackendTexture(kWidth, 139cb93a386Sopenharmony_ci kHeight, 140cb93a386Sopenharmony_ci format, 141cb93a386Sopenharmony_ci GrMipmapped::kNo, 142cb93a386Sopenharmony_ci GrRenderable::kYes); 143cb93a386Sopenharmony_ci if (!rectangleTex.isValid()) { 144cb93a386Sopenharmony_ci continue; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci if (!dContext->updateBackendTexture(rectangleTex, &pm, 1, origin, nullptr, nullptr)) { 148cb93a386Sopenharmony_ci continue; 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci 151cb93a386Sopenharmony_ci GrColor refPixels[kWidth * kHeight]; 152cb93a386Sopenharmony_ci for (int y = 0; y < kHeight; ++y) { 153cb93a386Sopenharmony_ci for (int x = 0; x < kWidth; ++x) { 154cb93a386Sopenharmony_ci refPixels[y * kWidth + x] = pixels[y * kWidth + x]; 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci sk_sp<GrTextureProxy> rectProxy = proxyProvider->wrapBackendTexture( 159cb93a386Sopenharmony_ci rectangleTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType); 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci if (!rectProxy) { 162cb93a386Sopenharmony_ci dContext->deleteBackendTexture(rectangleTex); 163cb93a386Sopenharmony_ci continue; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci SkASSERT(rectProxy->mipmapped() == GrMipmapped::kNo); 167cb93a386Sopenharmony_ci SkASSERT(rectProxy->peekTexture()->mipmapped() == GrMipmapped::kNo); 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci SkASSERT(rectProxy->textureType() == GrTextureType::kRectangle); 170cb93a386Sopenharmony_ci SkASSERT(rectProxy->peekTexture()->textureType() == GrTextureType::kRectangle); 171cb93a386Sopenharmony_ci SkASSERT(rectProxy->hasRestrictedSampling()); 172cb93a386Sopenharmony_ci SkASSERT(rectProxy->peekTexture()->hasRestrictedSampling()); 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ci GrImageInfo grII = ii; 175cb93a386Sopenharmony_ci GrSwizzle swizzle = dContext->priv().caps()->getReadSwizzle(rectangleTex.getBackendFormat(), 176cb93a386Sopenharmony_ci grII.colorType()); 177cb93a386Sopenharmony_ci GrSurfaceProxyView view(rectProxy, origin, swizzle); 178cb93a386Sopenharmony_ci 179cb93a386Sopenharmony_ci test_basic_draw_as_src(reporter, dContext, view, grII.colorType(), kPremul_SkAlphaType, 180cb93a386Sopenharmony_ci refPixels); 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci // Test copy to both a texture and RT 183cb93a386Sopenharmony_ci TestCopyFromSurface(reporter, dContext, rectProxy, origin, grII.colorType(), refPixels, 184cb93a386Sopenharmony_ci "RectangleTexture-copy-from"); 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_ci auto rectContext = dContext->priv().makeSC(std::move(view), grII.colorInfo()); 187cb93a386Sopenharmony_ci SkASSERT(rectContext); 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ci TestReadPixels(reporter, dContext, rectContext.get(), refPixels, "RectangleTexture-read"); 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ci test_copy_to_surface(reporter, dContext, rectContext.get(), "RectangleTexture-copy-to"); 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci TestWritePixels(reporter, dContext, rectContext.get(), true, "RectangleTexture-write"); 194cb93a386Sopenharmony_ci 195cb93a386Sopenharmony_ci test_clear(reporter, dContext, rectContext.get()); 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci dContext->deleteBackendTexture(rectangleTex); 198cb93a386Sopenharmony_ci } 199cb93a386Sopenharmony_ci} 200cb93a386Sopenharmony_ci#endif 201