Flutter Engine
The Flutter Engine
Functions
GrSurfaceResolveTest.cpp File Reference
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/private/SkColorData.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrFragmentProcessor.h"
#include "src/gpu/ganesh/GrPaint.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/GrTextureResolveRenderTask.h"
#include "src/gpu/ganesh/SurfaceContext.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/effects/GrTextureEffect.h"
#include "src/gpu/ganesh/ops/OpsTask.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/gpu/FenceSync.h"
#include "tools/gpu/ManagedBackendTexture.h"
#include <functional>
#include <initializer_list>
#include <memory>
#include <utility>

Go to the source code of this file.

Functions

bool check_pixels (skiatest::Reporter *reporter, GrDirectContext *dContext, const GrBackendTexture &tex, const SkImageInfo &info, SkColor expectedColor)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (SurfaceResolveTest, reporter, ctxInfo, CtsEnforcement::kApiLevel_T)
 
 DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS (NonmippedDrawBeforeMippedDraw, reporter, ctxInfo, CtsEnforcement::kNever)
 

Function Documentation

◆ check_pixels()

bool check_pixels ( skiatest::Reporter reporter,
GrDirectContext dContext,
const GrBackendTexture tex,
const SkImageInfo info,
SkColor  expectedColor 
)

Definition at line 60 of file GrSurfaceResolveTest.cpp.

64 {
65 // We have to do the readback of the backend texture wrapped in a different Skia surface than
66 // the one used in the main body of the test or else the readPixels call will trigger resolves
67 // itself.
69 tex,
71 /*sampleCnt=*/4,
73 nullptr,
74 nullptr);
75 SkBitmap actual;
76 actual.allocPixels(info);
77 if (!surface->readPixels(actual, 0, 0)) {
78 return false;
79 }
80
81 SkBitmap expected;
82 expected.allocPixels(info);
83 SkCanvas tmp(expected);
84 tmp.clear(expectedColor);
85 expected.setImmutable();
86
87 const float tols[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
88
89 auto error = std::function<ComparePixmapsErrorReporter>(
90 [reporter](int x, int y, const float diffs[4]) {
91 SkASSERT(x >= 0 && y >= 0);
92 ERRORF(reporter, "mismatch at %d, %d (%f, %f, %f %f)",
93 x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
94 });
95
96 return ComparePixels(expected.pixmap(), actual.pixmap(), tols, error);
97}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
reporter
Definition: FontMgrTest.cpp:39
@ kTopLeft_GrSurfaceOrigin
Definition: GrTypes.h:148
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
bool ComparePixels(const GrCPixmap &a, const GrCPixmap &b, const float tolRGBA[4], std::function< ComparePixmapsErrorReporter > &error)
Definition: TestUtils.cpp:142
#define ERRORF(r,...)
Definition: Test.h:293
void allocPixels(const SkImageInfo &info, size_t rowBytes)
Definition: SkBitmap.cpp:258
void setImmutable()
Definition: SkBitmap.cpp:400
const SkPixmap & pixmap() const
Definition: SkBitmap.h:133
VkSurfaceKHR surface
Definition: main.cc:49
const uint8_t uint32_t uint32_t GError ** error
double y
double x
SK_API sk_sp< SkSurface > WrapBackendTexture(GrRecordingContext *context, const GrBackendTexture &backendTexture, GrSurfaceOrigin origin, int sampleCnt, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, TextureReleaseProc textureReleaseProc=nullptr, ReleaseContext releaseContext=nullptr)

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [1/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( NonmippedDrawBeforeMippedDraw  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kNever   
)

Definition at line 215 of file GrSurfaceResolveTest.cpp.

218 {
219 using ResolveFlags = GrSurfaceProxy::ResolveFlags;
220 auto dc = ctxInfo.directContext();
221
222 if (!dc->priv().caps()->mipmapSupport()) {
223 return;
224 }
225
226 for (int sampleCount : {1, 4}) {
227 GrRenderable renderable = sampleCount > 1 ? GrRenderable::kYes : GrRenderable::kNo;
228
229 auto bef = dc->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888, renderable);
230 if (sampleCount > 1) {
231 if (dc->priv().caps()->msaaResolvesAutomatically()) {
232 // MSAA won't add a resolve task.
233 continue;
234 }
235 sampleCount = dc->priv().caps()->getRenderTargetSampleCount(sampleCount, bef);
236 if (!sampleCount) {
237 continue;
238 }
239 }
240
241 // Create a mipmapped proxy
242 auto mmProxy = dc->priv().proxyProvider()->createProxy(bef,
243 {64, 64},
244 renderable,
245 sampleCount,
250 "test MM Proxy");
251 GrSurfaceProxyView mmProxyView{mmProxy,
254
255 if (sampleCount > 1) {
256 // Make sure MSAA surface needs a resolve by drawing to it. This also adds a last
257 // render task to the proxy.
258 auto drawContext = skgpu::ganesh::SurfaceDrawContext::Make(dc,
260 mmProxy,
261 nullptr,
264 drawContext->fillWithFP(GrFragmentProcessor::MakeColor(SK_PMColor4fWHITE));
265 } else {
266 // Use a copy, as in the original bug, to dirty the mipmap status and also install
267 // a last render task on the proxy.
268 auto src = dc->priv().proxyProvider()->createProxy(bef,
269 {64, 64},
271 1,
276 "testSrc");
278 dc, mmProxyView, {GrColorType::kRGBA_8888, kPremul_SkAlphaType, nullptr});
279 mmSC.testCopy(src);
280 }
281
284 nullptr,
286 {8, 8},
288 "testDrawDst");
289
290 // Do a non-mipmapped draw from the mipmapped texture. This should add a dependency on the
291 // copy task recorded above. If the src texture is also multisampled this should record a
292 // msaa-only resolve.
293 {
294 auto te = GrTextureEffect::Make(
295 mmProxyView,
297 SkMatrix::I(),
299 *dc->priv().caps());
300
302 paint.setColorFragmentProcessor(std::move(te));
303
304 drawDst->drawRect(nullptr,
305 std::move(paint),
306 GrAA::kNo,
307 SkMatrix::Scale(1/8.f, 1/8.f),
308 SkRect::Make(mmProxy->dimensions()));
309 if (sampleCount > 1) {
310 const GrTextureResolveRenderTask* resolveTask =
311 drawDst->getOpsTask()->resolveTask();
312 if (!resolveTask) {
313 ERRORF(reporter, "No resolve task after drawing MSAA proxy");
314 return;
315 }
316 if (resolveTask->flagsForProxy(mmProxy) != ResolveFlags::kMSAA) {
317 ERRORF(reporter, "Expected resolve flags to be kMSAA");
318 return;
319 }
320 }
321 }
322
323 // Now do a mipmapped draw from the same texture. Ensure that even though we have a
324 // dependency on the copy task we still ensure that a resolve is recorded.
325 {
326 auto te = GrTextureEffect::Make(
327 mmProxyView,
329 SkMatrix::I(),
331 *dc->priv().caps());
332
334 paint.setColorFragmentProcessor(std::move(te));
335
336 drawDst->drawRect(nullptr,
337 std::move(paint),
338 GrAA::kNo,
339 SkMatrix::Scale(1/8.f, 1/8.f),
340 SkRect::Make(mmProxy->dimensions()));
341 }
342 const GrTextureResolveRenderTask* resolveTask = drawDst->getOpsTask()->resolveTask();
343 if (!resolveTask) {
344 ERRORF(reporter, "No resolve task after drawing mip mapped proxy");
345 return;
346 }
347
348 ResolveFlags expectedFlags = GrSurfaceProxy::ResolveFlags::kMipMaps;
349 const char* expectedStr = "kMipMaps";
350 if (sampleCount > 1) {
352 expectedStr = "kMipMaps|kMSAA";
353 }
354 if (resolveTask->flagsForProxy(mmProxy) != expectedFlags) {
355 ERRORF(reporter, "Expected resolve flags to be %s", expectedStr);
356 return;
357 }
358 }
359}
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
constexpr SkPMColor4f SK_PMColor4fWHITE
Definition: SkColorData.h:380
static std::unique_ptr< GrFragmentProcessor > MakeColor(SkPMColor4f color)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
static constexpr Swizzle RGBA()
Definition: Swizzle.h:66
static std::unique_ptr< SurfaceDrawContext > Make(GrRecordingContext *, GrColorType, sk_sp< GrSurfaceProxy >, sk_sp< SkColorSpace >, GrSurfaceOrigin, const SkSurfaceProps &)
const Paint & paint
Definition: color_source.cc:38
Renderable
Definition: GpuTypes.h:69
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS() [2/2]

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS ( SurfaceResolveTest  ,
reporter  ,
ctxInfo  ,
CtsEnforcement::kApiLevel_T   
)

Definition at line 99 of file GrSurfaceResolveTest.cpp.

102 {
103 auto dContext = ctxInfo.directContext();
104
106
107 auto managedTex = ManagedBackendTexture::MakeFromInfo(
109 if (!managedTex) {
110 return;
111 }
112 auto tex = managedTex->texture();
113 // Wrap the backend surface but tell it rendering with MSAA so that the wrapped texture is the
114 // resolve.
116 tex,
118 /*sampleCnt=*/4,
120 nullptr,
121 nullptr);
122
123 if (!surface) {
124 return;
125 }
126
127 const GrCaps* caps = dContext->priv().caps();
128 // In metal and vulkan if we prefer discardable msaa attachments we will also auto resolve. The
129 // GrBackendTexture and SkSurface are set up in a way that is compatible with discardable msaa
130 // for both backends.
131 bool autoResolves = caps->msaaResolvesAutomatically() ||
133
134 // First do a simple test where we clear the surface than flush with SkSurface::flush. This
135 // should trigger the resolve and the texture should have the correct data.
136 surface->getCanvas()->clear(SK_ColorRED);
137 dContext->flush(surface.get());
138 dContext->submit();
140
141 // Next try doing a GrDirectContext::flush without the surface which will not trigger a resolve
142 // on gpus without automatic msaa resolves.
143 surface->getCanvas()->clear(SK_ColorBLUE);
144 dContext->flush();
145 dContext->submit();
146 if (autoResolves) {
148 } else {
150 }
151
152 // Now doing a surface flush (even without any queued up normal work) should still resolve the
153 // surface.
154 dContext->flush(surface.get());
155 dContext->submit();
157
158 // Test using SkSurface::resolve with a GrDirectContext::flush
159 surface->getCanvas()->clear(SK_ColorRED);
161 dContext->flush();
162 dContext->submit();
164
165 // Calling resolve again should cause no issues as it is a no-op (there is an assert in the
166 // resolve op that the surface's msaa is dirty, we shouldn't hit that assert).
168 dContext->flush();
169 dContext->submit();
171
172 // Try resolving in the middle of draw calls. Non automatic resolve gpus should only see the
173 // results of the first draw.
174 surface->getCanvas()->clear(SK_ColorGREEN);
176 surface->getCanvas()->clear(SK_ColorBLUE);
177 dContext->flush();
178 dContext->submit();
179 if (autoResolves) {
181 } else {
183 }
184
185 // Test that a resolve between draws to a different surface doesn't cause the OpsTasks for that
186 // surface to be split. Fails if we hit validation asserts in GrDrawingManager.
187 // First clear out dirty msaa from previous test
188 dContext->flush(surface.get());
189
190 auto otherSurface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kYes, info);
191 REPORTER_ASSERT(reporter, otherSurface);
192 otherSurface->getCanvas()->clear(SK_ColorRED);
194 otherSurface->getCanvas()->clear(SK_ColorBLUE);
195 dContext->flush();
196 dContext->submit();
197
198 // Make sure resolving a non-msaa surface doesn't trigger a resolve call. We'll hit an assert
199 // that the msaa is not dirty if it does.
200 REPORTER_ASSERT(reporter, otherSurface);
201 otherSurface->getCanvas()->clear(SK_ColorRED);
202 SkSurfaces::ResolveMSAA(otherSurface);
203 dContext->flush();
204 dContext->submit();
205}
bool check_pixels(skiatest::Reporter *reporter, GrDirectContext *dContext, const GrBackendTexture &tex, const SkImageInfo &info, SkColor expectedColor)
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
Definition: GrCaps.h:57
bool preferDiscardableMSAAAttachment() const
Definition: GrCaps.h:107
bool msaaResolvesAutomatically() const
Definition: GrCaps.h:100
SK_API void ResolveMSAA(SkSurface *surface)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)