1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2022 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkAlphaType.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorSpace.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSamplingOptions.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurfaceProps.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrBackendSurface.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrDirectContext.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/GrTypes.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/SkSurfaceGanesh.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SkBackingFit.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrCaps.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrDirectContextPriv.h"
33*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrFragmentProcessor.h"
34*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrPaint.h"
35*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrProxyProvider.h"
36*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSamplerState.h"
37*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxy.h"
38*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrSurfaceProxyView.h"
39*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureProxy.h"
40*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrTextureResolveRenderTask.h"
41*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceContext.h"
42*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/SurfaceDrawContext.h"
43*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/effects/GrTextureEffect.h"
44*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/ops/OpsTask.h"
45*c8dee2aaSAndroid Build Coastguard Worker #include "tests/CtsEnforcement.h"
46*c8dee2aaSAndroid Build Coastguard Worker #include "tests/Test.h"
47*c8dee2aaSAndroid Build Coastguard Worker #include "tests/TestUtils.h"
48*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/FenceSync.h"
49*c8dee2aaSAndroid Build Coastguard Worker #include "tools/gpu/ManagedBackendTexture.h"
50*c8dee2aaSAndroid Build Coastguard Worker
51*c8dee2aaSAndroid Build Coastguard Worker #include <functional>
52*c8dee2aaSAndroid Build Coastguard Worker #include <initializer_list>
53*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
54*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
55*c8dee2aaSAndroid Build Coastguard Worker
56*c8dee2aaSAndroid Build Coastguard Worker struct GrContextOptions;
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker using namespace sk_gpu_test;
59*c8dee2aaSAndroid Build Coastguard Worker
check_pixels(skiatest::Reporter * reporter,GrDirectContext * dContext,const GrBackendTexture & tex,const SkImageInfo & info,SkColor expectedColor)60*c8dee2aaSAndroid Build Coastguard Worker bool check_pixels(skiatest::Reporter* reporter,
61*c8dee2aaSAndroid Build Coastguard Worker GrDirectContext* dContext,
62*c8dee2aaSAndroid Build Coastguard Worker const GrBackendTexture& tex,
63*c8dee2aaSAndroid Build Coastguard Worker const SkImageInfo& info,
64*c8dee2aaSAndroid Build Coastguard Worker SkColor expectedColor) {
65*c8dee2aaSAndroid Build Coastguard Worker // We have to do the readback of the backend texture wrapped in a different Skia surface than
66*c8dee2aaSAndroid Build Coastguard Worker // the one used in the main body of the test or else the readPixels call will trigger resolves
67*c8dee2aaSAndroid Build Coastguard Worker // itself.
68*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(dContext,
69*c8dee2aaSAndroid Build Coastguard Worker tex,
70*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
71*c8dee2aaSAndroid Build Coastguard Worker /*sampleCnt=*/4,
72*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
73*c8dee2aaSAndroid Build Coastguard Worker nullptr,
74*c8dee2aaSAndroid Build Coastguard Worker nullptr);
75*c8dee2aaSAndroid Build Coastguard Worker SkBitmap actual;
76*c8dee2aaSAndroid Build Coastguard Worker actual.allocPixels(info);
77*c8dee2aaSAndroid Build Coastguard Worker if (!surface->readPixels(actual, 0, 0)) {
78*c8dee2aaSAndroid Build Coastguard Worker return false;
79*c8dee2aaSAndroid Build Coastguard Worker }
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker SkBitmap expected;
82*c8dee2aaSAndroid Build Coastguard Worker expected.allocPixels(info);
83*c8dee2aaSAndroid Build Coastguard Worker SkCanvas tmp(expected);
84*c8dee2aaSAndroid Build Coastguard Worker tmp.clear(expectedColor);
85*c8dee2aaSAndroid Build Coastguard Worker expected.setImmutable();
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker const float tols[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
88*c8dee2aaSAndroid Build Coastguard Worker
89*c8dee2aaSAndroid Build Coastguard Worker auto error = std::function<ComparePixmapsErrorReporter>(
90*c8dee2aaSAndroid Build Coastguard Worker [reporter](int x, int y, const float diffs[4]) {
91*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(x >= 0 && y >= 0);
92*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "mismatch at %d, %d (%f, %f, %f %f)",
93*c8dee2aaSAndroid Build Coastguard Worker x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
94*c8dee2aaSAndroid Build Coastguard Worker });
95*c8dee2aaSAndroid Build Coastguard Worker
96*c8dee2aaSAndroid Build Coastguard Worker return ComparePixels(expected.pixmap(), actual.pixmap(), tols, error);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceResolveTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)99*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(SurfaceResolveTest,
100*c8dee2aaSAndroid Build Coastguard Worker reporter,
101*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
102*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kApiLevel_T) {
103*c8dee2aaSAndroid Build Coastguard Worker auto dContext = ctxInfo.directContext();
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = SkImageInfo::Make(8, 8, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
106*c8dee2aaSAndroid Build Coastguard Worker
107*c8dee2aaSAndroid Build Coastguard Worker auto managedTex = ManagedBackendTexture::MakeFromInfo(
108*c8dee2aaSAndroid Build Coastguard Worker dContext, info, skgpu::Mipmapped::kNo, GrRenderable::kYes);
109*c8dee2aaSAndroid Build Coastguard Worker if (!managedTex) {
110*c8dee2aaSAndroid Build Coastguard Worker return;
111*c8dee2aaSAndroid Build Coastguard Worker }
112*c8dee2aaSAndroid Build Coastguard Worker auto tex = managedTex->texture();
113*c8dee2aaSAndroid Build Coastguard Worker // Wrap the backend surface but tell it rendering with MSAA so that the wrapped texture is the
114*c8dee2aaSAndroid Build Coastguard Worker // resolve.
115*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(dContext,
116*c8dee2aaSAndroid Build Coastguard Worker tex,
117*c8dee2aaSAndroid Build Coastguard Worker kTopLeft_GrSurfaceOrigin,
118*c8dee2aaSAndroid Build Coastguard Worker /*sampleCnt=*/4,
119*c8dee2aaSAndroid Build Coastguard Worker kRGBA_8888_SkColorType,
120*c8dee2aaSAndroid Build Coastguard Worker nullptr,
121*c8dee2aaSAndroid Build Coastguard Worker nullptr);
122*c8dee2aaSAndroid Build Coastguard Worker
123*c8dee2aaSAndroid Build Coastguard Worker if (!surface) {
124*c8dee2aaSAndroid Build Coastguard Worker return;
125*c8dee2aaSAndroid Build Coastguard Worker }
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker const GrCaps* caps = dContext->priv().caps();
128*c8dee2aaSAndroid Build Coastguard Worker // In metal and vulkan if we prefer discardable msaa attachments we will also auto resolve. The
129*c8dee2aaSAndroid Build Coastguard Worker // GrBackendTexture and SkSurface are set up in a way that is compatible with discardable msaa
130*c8dee2aaSAndroid Build Coastguard Worker // for both backends.
131*c8dee2aaSAndroid Build Coastguard Worker bool autoResolves = caps->msaaResolvesAutomatically() ||
132*c8dee2aaSAndroid Build Coastguard Worker caps->preferDiscardableMSAAAttachment();
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker // First do a simple test where we clear the surface than flush with SkSurface::flush. This
135*c8dee2aaSAndroid Build Coastguard Worker // should trigger the resolve and the texture should have the correct data.
136*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->clear(SK_ColorRED);
137*c8dee2aaSAndroid Build Coastguard Worker dContext->flush(surface.get());
138*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
139*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorRED));
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker // Next try doing a GrDirectContext::flush without the surface which will not trigger a resolve
142*c8dee2aaSAndroid Build Coastguard Worker // on gpus without automatic msaa resolves.
143*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->clear(SK_ColorBLUE);
144*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
145*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
146*c8dee2aaSAndroid Build Coastguard Worker if (autoResolves) {
147*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorBLUE));
148*c8dee2aaSAndroid Build Coastguard Worker } else {
149*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorRED));
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker // Now doing a surface flush (even without any queued up normal work) should still resolve the
153*c8dee2aaSAndroid Build Coastguard Worker // surface.
154*c8dee2aaSAndroid Build Coastguard Worker dContext->flush(surface.get());
155*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
156*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorBLUE));
157*c8dee2aaSAndroid Build Coastguard Worker
158*c8dee2aaSAndroid Build Coastguard Worker // Test using SkSurface::resolve with a GrDirectContext::flush
159*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->clear(SK_ColorRED);
160*c8dee2aaSAndroid Build Coastguard Worker SkSurfaces::ResolveMSAA(surface);
161*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
162*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
163*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorRED));
164*c8dee2aaSAndroid Build Coastguard Worker
165*c8dee2aaSAndroid Build Coastguard Worker // Calling resolve again should cause no issues as it is a no-op (there is an assert in the
166*c8dee2aaSAndroid Build Coastguard Worker // resolve op that the surface's msaa is dirty, we shouldn't hit that assert).
167*c8dee2aaSAndroid Build Coastguard Worker SkSurfaces::ResolveMSAA(surface);
168*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
169*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
170*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorRED));
171*c8dee2aaSAndroid Build Coastguard Worker
172*c8dee2aaSAndroid Build Coastguard Worker // Try resolving in the middle of draw calls. Non automatic resolve gpus should only see the
173*c8dee2aaSAndroid Build Coastguard Worker // results of the first draw.
174*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->clear(SK_ColorGREEN);
175*c8dee2aaSAndroid Build Coastguard Worker SkSurfaces::ResolveMSAA(surface);
176*c8dee2aaSAndroid Build Coastguard Worker surface->getCanvas()->clear(SK_ColorBLUE);
177*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
178*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
179*c8dee2aaSAndroid Build Coastguard Worker if (autoResolves) {
180*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorBLUE));
181*c8dee2aaSAndroid Build Coastguard Worker } else {
182*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, check_pixels(reporter, dContext, tex, info, SK_ColorGREEN));
183*c8dee2aaSAndroid Build Coastguard Worker }
184*c8dee2aaSAndroid Build Coastguard Worker
185*c8dee2aaSAndroid Build Coastguard Worker // Test that a resolve between draws to a different surface doesn't cause the OpsTasks for that
186*c8dee2aaSAndroid Build Coastguard Worker // surface to be split. Fails if we hit validation asserts in GrDrawingManager.
187*c8dee2aaSAndroid Build Coastguard Worker // First clear out dirty msaa from previous test
188*c8dee2aaSAndroid Build Coastguard Worker dContext->flush(surface.get());
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker auto otherSurface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kYes, info);
191*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, otherSurface);
192*c8dee2aaSAndroid Build Coastguard Worker otherSurface->getCanvas()->clear(SK_ColorRED);
193*c8dee2aaSAndroid Build Coastguard Worker SkSurfaces::ResolveMSAA(surface);
194*c8dee2aaSAndroid Build Coastguard Worker otherSurface->getCanvas()->clear(SK_ColorBLUE);
195*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
196*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
197*c8dee2aaSAndroid Build Coastguard Worker
198*c8dee2aaSAndroid Build Coastguard Worker // Make sure resolving a non-msaa surface doesn't trigger a resolve call. We'll hit an assert
199*c8dee2aaSAndroid Build Coastguard Worker // that the msaa is not dirty if it does.
200*c8dee2aaSAndroid Build Coastguard Worker REPORTER_ASSERT(reporter, otherSurface);
201*c8dee2aaSAndroid Build Coastguard Worker otherSurface->getCanvas()->clear(SK_ColorRED);
202*c8dee2aaSAndroid Build Coastguard Worker SkSurfaces::ResolveMSAA(otherSurface);
203*c8dee2aaSAndroid Build Coastguard Worker dContext->flush();
204*c8dee2aaSAndroid Build Coastguard Worker dContext->submit();
205*c8dee2aaSAndroid Build Coastguard Worker }
206*c8dee2aaSAndroid Build Coastguard Worker
207*c8dee2aaSAndroid Build Coastguard Worker // This test comes from crbug.com/1355807 and crbug.com/1365578. The underlying issue was:
208*c8dee2aaSAndroid Build Coastguard Worker // * We would do a non-mipmapped draw of a proxy. This proxy would add a dependency from the ops
209*c8dee2aaSAndroid Build Coastguard Worker // task to the proxy's last render task, which was a copy task targetting the proxy.
210*c8dee2aaSAndroid Build Coastguard Worker // * We would do a mipmapped draw of the same proxy to the same ops task.
211*c8dee2aaSAndroid Build Coastguard Worker // GrRenderTask::addDependency would detect the pre-existing dependency and early out before
212*c8dee2aaSAndroid Build Coastguard Worker // adding the proxy to a resolve task.
213*c8dee2aaSAndroid Build Coastguard Worker // We also test the case where the first draw should add a MSAA resolve and the second draw should
214*c8dee2aaSAndroid Build Coastguard Worker // add a mipmap resolve.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(NonmippedDrawBeforeMippedDraw,reporter,ctxInfo,CtsEnforcement::kNever)215*c8dee2aaSAndroid Build Coastguard Worker DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(NonmippedDrawBeforeMippedDraw,
216*c8dee2aaSAndroid Build Coastguard Worker reporter,
217*c8dee2aaSAndroid Build Coastguard Worker ctxInfo,
218*c8dee2aaSAndroid Build Coastguard Worker CtsEnforcement::kNever) {
219*c8dee2aaSAndroid Build Coastguard Worker using ResolveFlags = GrSurfaceProxy::ResolveFlags;
220*c8dee2aaSAndroid Build Coastguard Worker auto dc = ctxInfo.directContext();
221*c8dee2aaSAndroid Build Coastguard Worker
222*c8dee2aaSAndroid Build Coastguard Worker if (!dc->priv().caps()->mipmapSupport()) {
223*c8dee2aaSAndroid Build Coastguard Worker return;
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker
226*c8dee2aaSAndroid Build Coastguard Worker for (int sampleCount : {1, 4}) {
227*c8dee2aaSAndroid Build Coastguard Worker GrRenderable renderable = sampleCount > 1 ? GrRenderable::kYes : GrRenderable::kNo;
228*c8dee2aaSAndroid Build Coastguard Worker
229*c8dee2aaSAndroid Build Coastguard Worker auto bef = dc->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888, renderable);
230*c8dee2aaSAndroid Build Coastguard Worker if (sampleCount > 1) {
231*c8dee2aaSAndroid Build Coastguard Worker if (dc->priv().caps()->msaaResolvesAutomatically()) {
232*c8dee2aaSAndroid Build Coastguard Worker // MSAA won't add a resolve task.
233*c8dee2aaSAndroid Build Coastguard Worker continue;
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker sampleCount = dc->priv().caps()->getRenderTargetSampleCount(sampleCount, bef);
236*c8dee2aaSAndroid Build Coastguard Worker if (!sampleCount) {
237*c8dee2aaSAndroid Build Coastguard Worker continue;
238*c8dee2aaSAndroid Build Coastguard Worker }
239*c8dee2aaSAndroid Build Coastguard Worker }
240*c8dee2aaSAndroid Build Coastguard Worker
241*c8dee2aaSAndroid Build Coastguard Worker // Create a mipmapped proxy
242*c8dee2aaSAndroid Build Coastguard Worker auto mmProxy = dc->priv().proxyProvider()->createProxy(bef,
243*c8dee2aaSAndroid Build Coastguard Worker {64, 64},
244*c8dee2aaSAndroid Build Coastguard Worker renderable,
245*c8dee2aaSAndroid Build Coastguard Worker sampleCount,
246*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kYes,
247*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
248*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes,
249*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
250*c8dee2aaSAndroid Build Coastguard Worker "test MM Proxy");
251*c8dee2aaSAndroid Build Coastguard Worker GrSurfaceProxyView mmProxyView{mmProxy,
252*c8dee2aaSAndroid Build Coastguard Worker kBottomLeft_GrSurfaceOrigin,
253*c8dee2aaSAndroid Build Coastguard Worker skgpu::Swizzle::RGBA()};
254*c8dee2aaSAndroid Build Coastguard Worker
255*c8dee2aaSAndroid Build Coastguard Worker if (sampleCount > 1) {
256*c8dee2aaSAndroid Build Coastguard Worker // Make sure MSAA surface needs a resolve by drawing to it. This also adds a last
257*c8dee2aaSAndroid Build Coastguard Worker // render task to the proxy.
258*c8dee2aaSAndroid Build Coastguard Worker auto drawContext = skgpu::ganesh::SurfaceDrawContext::Make(dc,
259*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
260*c8dee2aaSAndroid Build Coastguard Worker mmProxy,
261*c8dee2aaSAndroid Build Coastguard Worker nullptr,
262*c8dee2aaSAndroid Build Coastguard Worker kBottomLeft_GrSurfaceOrigin,
263*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps{});
264*c8dee2aaSAndroid Build Coastguard Worker drawContext->fillWithFP(GrFragmentProcessor::MakeColor(SK_PMColor4fWHITE));
265*c8dee2aaSAndroid Build Coastguard Worker } else {
266*c8dee2aaSAndroid Build Coastguard Worker // Use a copy, as in the original bug, to dirty the mipmap status and also install
267*c8dee2aaSAndroid Build Coastguard Worker // a last render task on the proxy.
268*c8dee2aaSAndroid Build Coastguard Worker auto src = dc->priv().proxyProvider()->createProxy(bef,
269*c8dee2aaSAndroid Build Coastguard Worker {64, 64},
270*c8dee2aaSAndroid Build Coastguard Worker GrRenderable::kNo,
271*c8dee2aaSAndroid Build Coastguard Worker 1,
272*c8dee2aaSAndroid Build Coastguard Worker skgpu::Mipmapped::kNo,
273*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
274*c8dee2aaSAndroid Build Coastguard Worker skgpu::Budgeted::kYes,
275*c8dee2aaSAndroid Build Coastguard Worker GrProtected::kNo,
276*c8dee2aaSAndroid Build Coastguard Worker "testSrc");
277*c8dee2aaSAndroid Build Coastguard Worker skgpu::ganesh::SurfaceContext mmSC(
278*c8dee2aaSAndroid Build Coastguard Worker dc, mmProxyView, {GrColorType::kRGBA_8888, kPremul_SkAlphaType, nullptr});
279*c8dee2aaSAndroid Build Coastguard Worker mmSC.testCopy(src);
280*c8dee2aaSAndroid Build Coastguard Worker }
281*c8dee2aaSAndroid Build Coastguard Worker
282*c8dee2aaSAndroid Build Coastguard Worker auto drawDst = skgpu::ganesh::SurfaceDrawContext::Make(dc,
283*c8dee2aaSAndroid Build Coastguard Worker GrColorType::kRGBA_8888,
284*c8dee2aaSAndroid Build Coastguard Worker nullptr,
285*c8dee2aaSAndroid Build Coastguard Worker SkBackingFit::kExact,
286*c8dee2aaSAndroid Build Coastguard Worker {8, 8},
287*c8dee2aaSAndroid Build Coastguard Worker SkSurfaceProps{},
288*c8dee2aaSAndroid Build Coastguard Worker "testDrawDst");
289*c8dee2aaSAndroid Build Coastguard Worker
290*c8dee2aaSAndroid Build Coastguard Worker // Do a non-mipmapped draw from the mipmapped texture. This should add a dependency on the
291*c8dee2aaSAndroid Build Coastguard Worker // copy task recorded above. If the src texture is also multisampled this should record a
292*c8dee2aaSAndroid Build Coastguard Worker // msaa-only resolve.
293*c8dee2aaSAndroid Build Coastguard Worker {
294*c8dee2aaSAndroid Build Coastguard Worker auto te = GrTextureEffect::Make(
295*c8dee2aaSAndroid Build Coastguard Worker mmProxyView,
296*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
297*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::I(),
298*c8dee2aaSAndroid Build Coastguard Worker GrSamplerState{SkFilterMode::kLinear, SkMipmapMode::kNone},
299*c8dee2aaSAndroid Build Coastguard Worker *dc->priv().caps());
300*c8dee2aaSAndroid Build Coastguard Worker
301*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
302*c8dee2aaSAndroid Build Coastguard Worker paint.setColorFragmentProcessor(std::move(te));
303*c8dee2aaSAndroid Build Coastguard Worker
304*c8dee2aaSAndroid Build Coastguard Worker drawDst->drawRect(nullptr,
305*c8dee2aaSAndroid Build Coastguard Worker std::move(paint),
306*c8dee2aaSAndroid Build Coastguard Worker GrAA::kNo,
307*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Scale(1/8.f, 1/8.f),
308*c8dee2aaSAndroid Build Coastguard Worker SkRect::Make(mmProxy->dimensions()));
309*c8dee2aaSAndroid Build Coastguard Worker if (sampleCount > 1) {
310*c8dee2aaSAndroid Build Coastguard Worker const GrTextureResolveRenderTask* resolveTask =
311*c8dee2aaSAndroid Build Coastguard Worker drawDst->getOpsTask()->resolveTask();
312*c8dee2aaSAndroid Build Coastguard Worker if (!resolveTask) {
313*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "No resolve task after drawing MSAA proxy");
314*c8dee2aaSAndroid Build Coastguard Worker return;
315*c8dee2aaSAndroid Build Coastguard Worker }
316*c8dee2aaSAndroid Build Coastguard Worker if (resolveTask->flagsForProxy(mmProxy) != ResolveFlags::kMSAA) {
317*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Expected resolve flags to be kMSAA");
318*c8dee2aaSAndroid Build Coastguard Worker return;
319*c8dee2aaSAndroid Build Coastguard Worker }
320*c8dee2aaSAndroid Build Coastguard Worker }
321*c8dee2aaSAndroid Build Coastguard Worker }
322*c8dee2aaSAndroid Build Coastguard Worker
323*c8dee2aaSAndroid Build Coastguard Worker // Now do a mipmapped draw from the same texture. Ensure that even though we have a
324*c8dee2aaSAndroid Build Coastguard Worker // dependency on the copy task we still ensure that a resolve is recorded.
325*c8dee2aaSAndroid Build Coastguard Worker {
326*c8dee2aaSAndroid Build Coastguard Worker auto te = GrTextureEffect::Make(
327*c8dee2aaSAndroid Build Coastguard Worker mmProxyView,
328*c8dee2aaSAndroid Build Coastguard Worker kPremul_SkAlphaType,
329*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::I(),
330*c8dee2aaSAndroid Build Coastguard Worker GrSamplerState{SkFilterMode::kLinear, SkMipmapMode::kLinear},
331*c8dee2aaSAndroid Build Coastguard Worker *dc->priv().caps());
332*c8dee2aaSAndroid Build Coastguard Worker
333*c8dee2aaSAndroid Build Coastguard Worker GrPaint paint;
334*c8dee2aaSAndroid Build Coastguard Worker paint.setColorFragmentProcessor(std::move(te));
335*c8dee2aaSAndroid Build Coastguard Worker
336*c8dee2aaSAndroid Build Coastguard Worker drawDst->drawRect(nullptr,
337*c8dee2aaSAndroid Build Coastguard Worker std::move(paint),
338*c8dee2aaSAndroid Build Coastguard Worker GrAA::kNo,
339*c8dee2aaSAndroid Build Coastguard Worker SkMatrix::Scale(1/8.f, 1/8.f),
340*c8dee2aaSAndroid Build Coastguard Worker SkRect::Make(mmProxy->dimensions()));
341*c8dee2aaSAndroid Build Coastguard Worker }
342*c8dee2aaSAndroid Build Coastguard Worker const GrTextureResolveRenderTask* resolveTask = drawDst->getOpsTask()->resolveTask();
343*c8dee2aaSAndroid Build Coastguard Worker if (!resolveTask) {
344*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "No resolve task after drawing mip mapped proxy");
345*c8dee2aaSAndroid Build Coastguard Worker return;
346*c8dee2aaSAndroid Build Coastguard Worker }
347*c8dee2aaSAndroid Build Coastguard Worker
348*c8dee2aaSAndroid Build Coastguard Worker ResolveFlags expectedFlags = GrSurfaceProxy::ResolveFlags::kMipMaps;
349*c8dee2aaSAndroid Build Coastguard Worker const char* expectedStr = "kMipMaps";
350*c8dee2aaSAndroid Build Coastguard Worker if (sampleCount > 1) {
351*c8dee2aaSAndroid Build Coastguard Worker expectedFlags |= GrSurfaceProxy::ResolveFlags::kMSAA;
352*c8dee2aaSAndroid Build Coastguard Worker expectedStr = "kMipMaps|kMSAA";
353*c8dee2aaSAndroid Build Coastguard Worker }
354*c8dee2aaSAndroid Build Coastguard Worker if (resolveTask->flagsForProxy(mmProxy) != expectedFlags) {
355*c8dee2aaSAndroid Build Coastguard Worker ERRORF(reporter, "Expected resolve flags to be %s", expectedStr);
356*c8dee2aaSAndroid Build Coastguard Worker return;
357*c8dee2aaSAndroid Build Coastguard Worker }
358*c8dee2aaSAndroid Build Coastguard Worker }
359*c8dee2aaSAndroid Build Coastguard Worker }
360