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