1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2021 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
10cb93a386Sopenharmony_ci#include "include/core/SkVertices.h"
11cb93a386Sopenharmony_ci#include "src/core/SkBlendModePriv.h"
12cb93a386Sopenharmony_ci#include "src/core/SkMatrixProvider.h"
13cb93a386Sopenharmony_ci#include "src/core/SkSurfacePriv.h"
14cb93a386Sopenharmony_ci#include "src/gpu/GrStyle.h"
15cb93a386Sopenharmony_ci#include "src/gpu/v1/SurfaceDrawContext_v1.h"
16cb93a386Sopenharmony_ci
17cb93a386Sopenharmony_cinamespace {
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_cistatic SkSurfaceProps kDMSAAProps(SkSurfaceProps::kDynamicMSAA_Flag, kUnknown_SkPixelGeometry);
20cb93a386Sopenharmony_cistatic SkSurfaceProps kBasicProps(0, kUnknown_SkPixelGeometry);
21cb93a386Sopenharmony_ciconstexpr static SkPMColor4f kTransYellow = {.5f,.5f,.0f,.5f};
22cb93a386Sopenharmony_ciconstexpr static SkPMColor4f kTransCyan = {.0f,.5f,.5f,.5f};
23cb93a386Sopenharmony_ciconstexpr static int kWidth=10, kHeight=10;
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci}
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cistatic void draw_paint_with_aa(skgpu::v1::SurfaceDrawContext* sdc,
28cb93a386Sopenharmony_ci                               const SkPMColor4f& color,
29cb93a386Sopenharmony_ci                               SkBlendMode blendMode) {
30cb93a386Sopenharmony_ci    GrPaint paint;
31cb93a386Sopenharmony_ci    paint.setColor4f(color);
32cb93a386Sopenharmony_ci    paint.setXPFactory(SkBlendMode_AsXPFactory(blendMode));
33cb93a386Sopenharmony_ci    sdc->drawRect(nullptr, std::move(paint), GrAA::kYes, SkMatrix::I(),
34cb93a386Sopenharmony_ci                  SkRect::MakeIWH(kWidth, kHeight), nullptr);
35cb93a386Sopenharmony_ci}
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_cistatic void draw_paint_with_dmsaa(skgpu::v1::SurfaceDrawContext* sdc,
38cb93a386Sopenharmony_ci                                  const SkPMColor4f& color,
39cb93a386Sopenharmony_ci                                  SkBlendMode blendMode) {
40cb93a386Sopenharmony_ci    // drawVertices should always trigger dmsaa, but draw something non-rectangular just to be 100%
41cb93a386Sopenharmony_ci    // certain.
42cb93a386Sopenharmony_ci    static const SkPoint kVertices[3] = {{-.5f,-.5f}, {kWidth * 2.1f, 0}, {0, kHeight * 2.1f}};
43cb93a386Sopenharmony_ci    SkVertices::Builder builder(SkVertices::kTriangles_VertexMode, 3, 0, 0);
44cb93a386Sopenharmony_ci    memcpy(builder.positions(), kVertices, sizeof(kVertices));
45cb93a386Sopenharmony_ci    auto vertices = builder.detach();
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci    GrPaint paint;
48cb93a386Sopenharmony_ci    paint.setColor4f(color);
49cb93a386Sopenharmony_ci    paint.setXPFactory(SkBlendMode_AsXPFactory(blendMode));
50cb93a386Sopenharmony_ci    sdc->drawVertices(nullptr, std::move(paint), SkSimpleMatrixProvider(SkMatrix::I()), vertices);
51cb93a386Sopenharmony_ci}
52cb93a386Sopenharmony_ci
53cb93a386Sopenharmony_cistatic bool fuzzy_equals(const float a[4], const SkPMColor4f& b) {
54cb93a386Sopenharmony_ci    constexpr static float kTolerance = 2.5f / 256;
55cb93a386Sopenharmony_ci    for (int i = 0; i < 4; ++i) {
56cb93a386Sopenharmony_ci        if (!SkScalarNearlyEqual(a[i], b.vec()[i], kTolerance)) {
57cb93a386Sopenharmony_ci            return false;
58cb93a386Sopenharmony_ci        }
59cb93a386Sopenharmony_ci    }
60cb93a386Sopenharmony_ci    return true;
61cb93a386Sopenharmony_ci}
62cb93a386Sopenharmony_ci
63cb93a386Sopenharmony_cistatic void check_sdc_color(skiatest::Reporter* reporter,
64cb93a386Sopenharmony_ci                            skgpu::v1::SurfaceDrawContext* sdc,
65cb93a386Sopenharmony_ci                            GrDirectContext* ctx,
66cb93a386Sopenharmony_ci                            const SkPMColor4f& color) {
67cb93a386Sopenharmony_ci    auto info = SkImageInfo::Make(kWidth, kHeight, kRGBA_F32_SkColorType, kPremul_SkAlphaType);
68cb93a386Sopenharmony_ci    GrPixmap pixmap = GrPixmap::Allocate(info);
69cb93a386Sopenharmony_ci    sdc->readPixels(ctx, pixmap, {0, 0});
70cb93a386Sopenharmony_ci    auto pix = static_cast<const float*>(pixmap.addr());
71cb93a386Sopenharmony_ci    for (int y = 0; y < kHeight; ++y) {
72cb93a386Sopenharmony_ci        for (int x = 0; x < kWidth; ++x) {
73cb93a386Sopenharmony_ci            if (!fuzzy_equals(pix, color)) {
74cb93a386Sopenharmony_ci                ERRORF(reporter, "SDC color mismatch.\n"
75cb93a386Sopenharmony_ci                                 "Got      [%0.3f, %0.3f, %0.3f, %0.3f]\n"
76cb93a386Sopenharmony_ci                                 "Expected [%0.3f, %0.3f, %0.3f, %0.3f]",
77cb93a386Sopenharmony_ci                       pix[0], pix[1], pix[2], pix[3], color.fR, color.fG, color.fB, color.fA);
78cb93a386Sopenharmony_ci                return;
79cb93a386Sopenharmony_ci            }
80cb93a386Sopenharmony_ci            pix += 4;
81cb93a386Sopenharmony_ci        }
82cb93a386Sopenharmony_ci    }
83cb93a386Sopenharmony_ci}
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_CONTEXTS(DMSAA_preserve_contents,
86cb93a386Sopenharmony_ci                         &sk_gpu_test::GrContextFactory::IsRenderingContext, reporter, ctxInfo,
87cb93a386Sopenharmony_ci                         nullptr) {
88cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
89cb93a386Sopenharmony_ci    auto sdc = skgpu::v1::SurfaceDrawContext::Make(dContext, GrColorType::kRGBA_8888, nullptr,
90cb93a386Sopenharmony_ci                                                   SkBackingFit::kApprox, {kWidth, kHeight},
91cb93a386Sopenharmony_ci                                                   kDMSAAProps);
92cb93a386Sopenharmony_ci
93cb93a386Sopenharmony_ci    // Initialize the texture and dmsaa attachment with transparent.
94cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
95cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
96cb93a386Sopenharmony_ci
97cb93a386Sopenharmony_ci    // Clear the main texture to yellow.
98cb93a386Sopenharmony_ci    sdc->clear(kTransYellow);
99cb93a386Sopenharmony_ci
100cb93a386Sopenharmony_ci    // Close the opsTask by doing a readback.
101cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, kTransYellow);
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    // Now the DMSAA attachment is clear and the texture is yellow. Blend cyan into the DMSAA
104cb93a386Sopenharmony_ci    // attachment. This will fail if the yellow from the main texture doesn't get copied into the
105cb93a386Sopenharmony_ci    // DMSAA attachment before the renderPass.
106cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
107cb93a386Sopenharmony_ci    SkPMColor4f dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, kTransYellow);
108cb93a386Sopenharmony_ci
109cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, dstColor);
110cb93a386Sopenharmony_ci}
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_cistatic void require_dst_reads(GrContextOptions* options) {
113cb93a386Sopenharmony_ci    options->fSuppressAdvancedBlendEquations = true;
114cb93a386Sopenharmony_ci    options->fSuppressFramebufferFetch = true;
115cb93a386Sopenharmony_ci}
116cb93a386Sopenharmony_ci
117cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_CONTEXTS(DMSAA_dst_read, &sk_gpu_test::GrContextFactory::IsRenderingContext,
118cb93a386Sopenharmony_ci                         reporter, ctxInfo, require_dst_reads) {
119cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
120cb93a386Sopenharmony_ci    auto sdc = skgpu::v1::SurfaceDrawContext::Make(dContext, GrColorType::kRGBA_8888, nullptr,
121cb93a386Sopenharmony_ci                                                   SkBackingFit::kApprox, {kWidth, kHeight},
122cb93a386Sopenharmony_ci                                                   kDMSAAProps);
123cb93a386Sopenharmony_ci
124cb93a386Sopenharmony_ci    // Initialize the texture and dmsaa attachment with transparent.
125cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
126cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ci    sdc->clear(SK_PMColor4fWHITE);
129cb93a386Sopenharmony_ci    SkPMColor4f dstColor = SK_PMColor4fWHITE;
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
132cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
135cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, dstColor);
138cb93a386Sopenharmony_ci}
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_CONTEXTS(DMSAA_aa_dst_read_after_dmsaa,
141cb93a386Sopenharmony_ci                         &sk_gpu_test::GrContextFactory::IsRenderingContext, reporter, ctxInfo,
142cb93a386Sopenharmony_ci                         require_dst_reads) {
143cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
144cb93a386Sopenharmony_ci    auto sdc = skgpu::v1::SurfaceDrawContext::Make(dContext, GrColorType::kRGBA_8888, nullptr,
145cb93a386Sopenharmony_ci                                                   SkBackingFit::kApprox, {kWidth, kHeight},
146cb93a386Sopenharmony_ci                                                   kDMSAAProps);
147cb93a386Sopenharmony_ci
148cb93a386Sopenharmony_ci    // Initialize the texture and dmsaa attachment with transparent.
149cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
150cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
151cb93a386Sopenharmony_ci
152cb93a386Sopenharmony_ci    sdc->clear(SK_PMColor4fWHITE);
153cb93a386Sopenharmony_ci    SkPMColor4f dstColor = SK_PMColor4fWHITE;
154cb93a386Sopenharmony_ci
155cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
156cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci    // Draw with aa after dmsaa. This should break up the render pass and issue a texture barrier.
159cb93a386Sopenharmony_ci    draw_paint_with_aa(sdc.get(), kTransCyan, SkBlendMode::kDarken);
160cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransCyan, dstColor);
161cb93a386Sopenharmony_ci
162cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, dstColor);
163cb93a386Sopenharmony_ci}
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_CONTEXTS(DMSAA_dst_read_with_existing_barrier,
166cb93a386Sopenharmony_ci                         &sk_gpu_test::GrContextFactory::IsRenderingContext, reporter, ctxInfo,
167cb93a386Sopenharmony_ci                         require_dst_reads) {
168cb93a386Sopenharmony_ci    auto dContext = ctxInfo.directContext();
169cb93a386Sopenharmony_ci    auto sdc = skgpu::v1::SurfaceDrawContext::Make(dContext, GrColorType::kRGBA_8888, nullptr,
170cb93a386Sopenharmony_ci                                                   SkBackingFit::kApprox, {kWidth, kHeight},
171cb93a386Sopenharmony_ci                                                   kDMSAAProps);
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ci    // Initialize the texture and dmsaa attachment with transparent.
174cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), SK_PMColor4fTRANSPARENT, SkBlendMode::kSrc);
175cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, SK_PMColor4fTRANSPARENT);
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci    sdc->clear(SK_PMColor4fWHITE);
178cb93a386Sopenharmony_ci    SkPMColor4f dstColor = SK_PMColor4fWHITE;
179cb93a386Sopenharmony_ci
180cb93a386Sopenharmony_ci    // Blend to the texture (not the dmsaa attachment) with a dst read. This creates a texture
181cb93a386Sopenharmony_ci    // barrier.
182cb93a386Sopenharmony_ci    draw_paint_with_aa(sdc.get(), kTransYellow, SkBlendMode::kDarken);
183cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kDarken, kTransYellow, dstColor);
184cb93a386Sopenharmony_ci
185cb93a386Sopenharmony_ci    // Blend to the msaa attachment _without_ a dst read. This ensures we respect the prior texture
186cb93a386Sopenharmony_ci    // barrier by splitting the opsTask.
187cb93a386Sopenharmony_ci    draw_paint_with_dmsaa(sdc.get(), kTransCyan, SkBlendMode::kSrcOver);
188cb93a386Sopenharmony_ci    dstColor = SkBlendMode_Apply(SkBlendMode::kSrcOver, kTransCyan, dstColor);
189cb93a386Sopenharmony_ci
190cb93a386Sopenharmony_ci    check_sdc_color(reporter, sdc.get(), dContext, dstColor);
191cb93a386Sopenharmony_ci}
192cb93a386Sopenharmony_ci
193cb93a386Sopenharmony_ci// This test is used to test for crbug.com/1241134. The bug appears on Adreno5xx devices with OS
194cb93a386Sopenharmony_ci// PQ3A. It does not repro on the earlier PPR1 version since the extend blend func extension was not
195cb93a386Sopenharmony_ci// present on the older driver.
196cb93a386Sopenharmony_ciDEF_GPUTEST_FOR_RENDERING_CONTEXTS(DMSAA_dual_source_blend_disable, reporter, ctxInfo) {
197cb93a386Sopenharmony_ci    SkISize surfaceDims = {100, 100};
198cb93a386Sopenharmony_ci    SkISize texDims = {50, 50};
199cb93a386Sopenharmony_ci    auto context = ctxInfo.directContext();
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    auto sourceTexture = context->createBackendTexture(texDims.width(),
202cb93a386Sopenharmony_ci                                                       texDims.height(),
203cb93a386Sopenharmony_ci                                                       kRGBA_8888_SkColorType,
204cb93a386Sopenharmony_ci                                                       SkColors::kBlue,
205cb93a386Sopenharmony_ci                                                       GrMipMapped::kNo,
206cb93a386Sopenharmony_ci                                                       GrRenderable::kYes,
207cb93a386Sopenharmony_ci                                                       GrProtected::kNo);
208cb93a386Sopenharmony_ci
209cb93a386Sopenharmony_ci    auto sourceImage = SkImage::MakeFromTexture(context,
210cb93a386Sopenharmony_ci                                                sourceTexture,
211cb93a386Sopenharmony_ci                                                kTopLeft_GrSurfaceOrigin,
212cb93a386Sopenharmony_ci                                                kRGBA_8888_SkColorType,
213cb93a386Sopenharmony_ci                                                kPremul_SkAlphaType,
214cb93a386Sopenharmony_ci                                                nullptr);
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ci    auto texture1 = context->createBackendTexture(surfaceDims.width(),
217cb93a386Sopenharmony_ci                                                  surfaceDims.height(),
218cb93a386Sopenharmony_ci                                                  kRGBA_8888_SkColorType,
219cb93a386Sopenharmony_ci                                                  SkColors::kRed,
220cb93a386Sopenharmony_ci                                                  GrMipMapped::kNo,
221cb93a386Sopenharmony_ci                                                  GrRenderable::kYes,
222cb93a386Sopenharmony_ci                                                  GrProtected::kNo);
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_ci    auto texture2 = context->createBackendTexture(surfaceDims.width(),
225cb93a386Sopenharmony_ci                                                  surfaceDims.height(),
226cb93a386Sopenharmony_ci                                                  kRGBA_8888_SkColorType,
227cb93a386Sopenharmony_ci                                                  SkColors::kYellow,
228cb93a386Sopenharmony_ci                                                  GrMipMapped::kNo,
229cb93a386Sopenharmony_ci                                                  GrRenderable::kYes,
230cb93a386Sopenharmony_ci                                                  GrProtected::kNo);
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ci    SkPaint paint;
233cb93a386Sopenharmony_ci    paint.setBlendMode(SkBlendMode::kSrc);
234cb93a386Sopenharmony_ci
235cb93a386Sopenharmony_ci    SkRect srcRect = SkRect::MakeIWH(texDims.width(), texDims.height());
236cb93a386Sopenharmony_ci    SkRect dstRect = SkRect::MakeXYWH(texDims.width()/2, texDims.height()/2,
237cb93a386Sopenharmony_ci                                      texDims.width(), texDims.height());
238cb93a386Sopenharmony_ci
239cb93a386Sopenharmony_ci    // First we do an image draw to a DMSAA surface with kSrc blend mode. This will trigger us to
240cb93a386Sopenharmony_ci    // use dual source blending if supported.
241cb93a386Sopenharmony_ci    // Note: The draw here doesn't actually use the dmsaa multisampled buffer. However, by using
242cb93a386Sopenharmony_ci    // a dmsaa surface it forces us to use the FillRRectOp instead of the normal FillQuad path. It
243cb93a386Sopenharmony_ci    // is unclear why, but using the FillRRectOp is required to repro the bug.
244cb93a386Sopenharmony_ci    {
245cb93a386Sopenharmony_ci        auto surface = SkSurface::MakeFromBackendTexture(context,
246cb93a386Sopenharmony_ci                                                         texture1,
247cb93a386Sopenharmony_ci                                                         kTopLeft_GrSurfaceOrigin,
248cb93a386Sopenharmony_ci                                                         1,
249cb93a386Sopenharmony_ci                                                         kRGBA_8888_SkColorType,
250cb93a386Sopenharmony_ci                                                         nullptr,
251cb93a386Sopenharmony_ci                                                         &kDMSAAProps);
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_ci        surface->getCanvas()->drawImageRect(sourceImage,
254cb93a386Sopenharmony_ci                                            srcRect,
255cb93a386Sopenharmony_ci                                            dstRect,
256cb93a386Sopenharmony_ci                                            SkSamplingOptions(),
257cb93a386Sopenharmony_ci                                            &paint,
258cb93a386Sopenharmony_ci                                            SkCanvas::kStrict_SrcRectConstraint);
259cb93a386Sopenharmony_ci        // Make sure there isn't any batching
260cb93a386Sopenharmony_ci        surface->flushAndSubmit();
261cb93a386Sopenharmony_ci    }
262cb93a386Sopenharmony_ci
263cb93a386Sopenharmony_ci    // Next we do an image draw to a different surface that doesn't have the dmsaa flag. This will
264cb93a386Sopenharmony_ci    // trigger use to disable blending. However, when the bug is present the driver still seems to
265cb93a386Sopenharmony_ci    // try and use a "src2" blend value and ends up just writing the original dst color of yellow.
266cb93a386Sopenharmony_ci    {
267cb93a386Sopenharmony_ci        auto surface = SkSurface::MakeFromBackendTexture(context,
268cb93a386Sopenharmony_ci                                                         texture2,
269cb93a386Sopenharmony_ci                                                         kTopLeft_GrSurfaceOrigin,
270cb93a386Sopenharmony_ci                                                         1,
271cb93a386Sopenharmony_ci                                                         kRGBA_8888_SkColorType,
272cb93a386Sopenharmony_ci                                                         nullptr,
273cb93a386Sopenharmony_ci                                                         &kBasicProps);
274cb93a386Sopenharmony_ci
275cb93a386Sopenharmony_ci        surface->getCanvas()->drawImageRect(sourceImage,
276cb93a386Sopenharmony_ci                                            srcRect,
277cb93a386Sopenharmony_ci                                            dstRect,
278cb93a386Sopenharmony_ci                                            SkSamplingOptions(),
279cb93a386Sopenharmony_ci                                            &paint,
280cb93a386Sopenharmony_ci                                            SkCanvas::kStrict_SrcRectConstraint);
281cb93a386Sopenharmony_ci        surface->flushAndSubmit();
282cb93a386Sopenharmony_ci    }
283cb93a386Sopenharmony_ci
284cb93a386Sopenharmony_ci    {
285cb93a386Sopenharmony_ci        auto readImage = SkImage::MakeFromTexture(context,
286cb93a386Sopenharmony_ci                                                  texture2,
287cb93a386Sopenharmony_ci                                                  kTopLeft_GrSurfaceOrigin,
288cb93a386Sopenharmony_ci                                                  kRGBA_8888_SkColorType,
289cb93a386Sopenharmony_ci                                                  kPremul_SkAlphaType,
290cb93a386Sopenharmony_ci                                                  nullptr);
291cb93a386Sopenharmony_ci        SkImageInfo dstIInfo = SkImageInfo::Make(texDims.width(),
292cb93a386Sopenharmony_ci                                                 texDims.height(),
293cb93a386Sopenharmony_ci                                                 kRGBA_8888_SkColorType,
294cb93a386Sopenharmony_ci                                                 kPremul_SkAlphaType,
295cb93a386Sopenharmony_ci                                                 nullptr);
296cb93a386Sopenharmony_ci
297cb93a386Sopenharmony_ci        SkBitmap bitmap;
298cb93a386Sopenharmony_ci        bitmap.allocPixels(dstIInfo);
299cb93a386Sopenharmony_ci
300cb93a386Sopenharmony_ci        bool success = readImage->readPixels(context, bitmap.pixmap(), dstRect.fLeft, dstRect.fTop);
301cb93a386Sopenharmony_ci        if (!success) {
302cb93a386Sopenharmony_ci            ERRORF(reporter, "Failed to read pixels");
303cb93a386Sopenharmony_ci            return;
304cb93a386Sopenharmony_ci        }
305cb93a386Sopenharmony_ci        auto pix = static_cast<const uint32_t*>(bitmap.getAddr(0, 0));
306cb93a386Sopenharmony_ci        for (int x = 0; x < 50; ++x) {
307cb93a386Sopenharmony_ci            for (int y = 0; y < 50; ++y) {
308cb93a386Sopenharmony_ci                uint32_t pixColor = pix[x + y * 50];
309cb93a386Sopenharmony_ci                if (pixColor != 0xFFFF0000) {
310cb93a386Sopenharmony_ci                    ERRORF(reporter, "Didn't get a blue pixel at %d, %d. Got 0x%8X",
311cb93a386Sopenharmony_ci                           x, y, pixColor);
312cb93a386Sopenharmony_ci                    continue;
313cb93a386Sopenharmony_ci                }
314cb93a386Sopenharmony_ci            }
315cb93a386Sopenharmony_ci        }
316cb93a386Sopenharmony_ci    }
317cb93a386Sopenharmony_ci    sourceImage.reset();
318cb93a386Sopenharmony_ci    // Need to make sure the gpu is fully finished before deleting the textures
319cb93a386Sopenharmony_ci    context->flushAndSubmit(true);
320cb93a386Sopenharmony_ci    context->deleteBackendTexture(sourceTexture);
321cb93a386Sopenharmony_ci    context->deleteBackendTexture(texture1);
322cb93a386Sopenharmony_ci    context->deleteBackendTexture(texture2);
323cb93a386Sopenharmony_ci}
324cb93a386Sopenharmony_ci
325