blob: 121cf86345ff3f02984a868653e9ff835fe65f40 [file] [log] [blame]
Robert Phillips5af44de2017-07-18 14:49:38 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8// Include here to ensure SK_SUPPORT_GPU is set correctly before it is examined.
9#include "SkTypes.h"
10
Robert Phillipsfa8c0802017-10-04 08:42:28 -040011#if SK_SUPPORT_GPU
12#ifndef SK_DISABLE_DEFERRED_PROXIES
Robert Phillips5af44de2017-07-18 14:49:38 -040013#include "Test.h"
14
Robert Phillips57aa3672017-07-21 11:38:13 -040015#include "GrContextPriv.h"
16#include "GrGpu.h"
Robert Phillips0bd24dc2018-01-16 08:06:32 -050017#include "GrProxyProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040018#include "GrResourceAllocator.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040019#include "GrResourceProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040020#include "GrSurfaceProxyPriv.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040021#include "GrTest.h"
22#include "GrTexture.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040023#include "GrTextureProxy.h"
24
Robert Phillips57aa3672017-07-21 11:38:13 -040025struct ProxyParams {
26 int fSize;
27 bool fIsRT;
28 GrPixelConfig fConfig;
29 SkBackingFit fFit;
30 int fSampleCnt;
31 GrSurfaceOrigin fOrigin;
32 // TODO: do we care about mipmapping
33};
34
Robert Phillips1afd4cd2018-01-08 13:40:32 -050035static sk_sp<GrSurfaceProxy> make_deferred(GrProxyProvider* proxyProvider, const ProxyParams& p) {
Robert Phillips57aa3672017-07-21 11:38:13 -040036 GrSurfaceDesc desc;
37 desc.fFlags = p.fIsRT ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
38 desc.fOrigin = p.fOrigin;
39 desc.fWidth = p.fSize;
40 desc.fHeight = p.fSize;
41 desc.fConfig = p.fConfig;
42 desc.fSampleCnt = p.fSampleCnt;
43
Robert Phillips0bd24dc2018-01-16 08:06:32 -050044 return proxyProvider->createProxy(desc, p.fFit, SkBudgeted::kNo);
Robert Phillips57aa3672017-07-21 11:38:13 -040045}
46
47static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
Robert Phillipsd21b2a52017-12-12 13:01:25 -050048 GrBackendTexture* backendTex) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050049 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillipsf440cec2018-01-19 11:51:20 -050050 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips0bd24dc2018-01-16 08:06:32 -050051
Robert Phillipsf440cec2018-01-19 11:51:20 -050052 *backendTex = gpu->createTestingOnlyBackendTexture(nullptr, p.fSize, p.fSize,
53 p.fConfig, false,
54 GrMipMapped::kNo);
Robert Phillips57aa3672017-07-21 11:38:13 -040055
Robert Phillips0bd24dc2018-01-16 08:06:32 -050056 return proxyProvider->createWrappedTextureProxy(*backendTex, p.fOrigin);
Robert Phillips57aa3672017-07-21 11:38:13 -040057}
58
Robert Phillipsd21b2a52017-12-12 13:01:25 -050059static void cleanup_backend(GrContext* context, GrBackendTexture* backendTex) {
Robert Phillipsf440cec2018-01-19 11:51:20 -050060 context->contextPriv().getGpu()->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillips57aa3672017-07-21 11:38:13 -040061}
62
Robert Phillips5af44de2017-07-18 14:49:38 -040063// Basic test that two proxies with overlapping intervals and compatible descriptors are
64// assigned different GrSurfaces.
Robert Phillips57aa3672017-07-21 11:38:13 -040065static void overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
66 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
67 bool expectedResult) {
Robert Phillips5af44de2017-07-18 14:49:38 -040068 GrResourceAllocator alloc(resourceProvider);
69
70 alloc.addInterval(p1.get(), 0, 4);
71 alloc.addInterval(p2.get(), 1, 2);
Robert Phillipseafd48a2017-11-16 07:52:08 -050072 alloc.markEndOfOpList(0);
Robert Phillips5af44de2017-07-18 14:49:38 -040073
Robert Phillipseafd48a2017-11-16 07:52:08 -050074 int startIndex, stopIndex;
75 alloc.assign(&startIndex, &stopIndex);
Robert Phillips5af44de2017-07-18 14:49:38 -040076
77 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
78 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
Robert Phillips57aa3672017-07-21 11:38:13 -040079 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
80 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
Robert Phillips5af44de2017-07-18 14:49:38 -040081}
82
Robert Phillips57aa3672017-07-21 11:38:13 -040083// Test various cases when two proxies do not have overlapping intervals.
84// This mainly acts as a test of the ResourceAllocator's free pool.
85static void non_overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
86 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
87 bool expectedResult) {
88 GrResourceAllocator alloc(resourceProvider);
89
90 alloc.addInterval(p1.get(), 0, 2);
91 alloc.addInterval(p2.get(), 3, 5);
Robert Phillipseafd48a2017-11-16 07:52:08 -050092 alloc.markEndOfOpList(0);
Robert Phillips57aa3672017-07-21 11:38:13 -040093
Robert Phillipseafd48a2017-11-16 07:52:08 -050094 int startIndex, stopIndex;
95 alloc.assign(&startIndex, &stopIndex);
Robert Phillips57aa3672017-07-21 11:38:13 -040096
97 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
98 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
99 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
100 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
101}
102
103DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500104 GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500105 GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
Robert Phillips5af44de2017-07-18 14:49:38 -0400106
Robert Phillips57aa3672017-07-21 11:38:13 -0400107 struct TestCase {
108 ProxyParams fP1;
109 ProxyParams fP2;
110 bool fExpectation;
111 };
112
113 constexpr bool kRT = true;
114 constexpr bool kNotRT = false;
115
116 constexpr bool kShare = true;
117 constexpr bool kDontShare = false;
118 // Non-RT GrSurfaces are never recycled on some platforms.
119 bool kConditionallyShare = resourceProvider->caps()->reuseScratchTextures();
120
121 const GrPixelConfig kRGBA = kRGBA_8888_GrPixelConfig;
122 const GrPixelConfig kBGRA = kBGRA_8888_GrPixelConfig;
123
124 const SkBackingFit kE = SkBackingFit::kExact;
125 const SkBackingFit kA = SkBackingFit::kApprox;
126
127 const GrSurfaceOrigin kTL = kTopLeft_GrSurfaceOrigin;
128 const GrSurfaceOrigin kBL = kBottomLeft_GrSurfaceOrigin;
129
130 //--------------------------------------------------------------------------------------------
131 TestCase gOverlappingTests[] = {
132 //----------------------------------------------------------------------------------------
133 // Two proxies with overlapping intervals and compatible descriptors should never share
134 // RT version
135 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
136 // non-RT version
137 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
138 };
139
140 for (auto test : gOverlappingTests) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500141 sk_sp<GrSurfaceProxy> p1 = make_deferred(proxyProvider, test.fP1);
142 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, test.fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500143 overlap_test(reporter, resourceProvider,
144 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400145 }
146
147 int k2 = ctxInfo.grContext()->caps()->getSampleCount(2, kRGBA);
148 int k4 = ctxInfo.grContext()->caps()->getSampleCount(4, kRGBA);
149
150 //--------------------------------------------------------------------------------------------
151 TestCase gNonOverlappingTests[] = {
152 //----------------------------------------------------------------------------------------
153 // Two non-overlapping intervals w/ compatible proxies should share
154 // both same size & approx
155 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kShare },
156 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
157 // diffs sizes but still approx
158 { { 64, kRT, kRGBA, kA, 0, kTL }, { 50, kRT, kRGBA, kA, 0, kTL }, kShare },
159 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 50, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
160 // sames sizes but exact
161 { { 64, kRT, kRGBA, kE, 0, kTL }, { 64, kRT, kRGBA, kE, 0, kTL }, kShare },
162 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kConditionallyShare },
163 //----------------------------------------------------------------------------------------
164 // Two non-overlapping intervals w/ different exact sizes should not share
165 { { 56, kRT, kRGBA, kE, 0, kTL }, { 54, kRT, kRGBA, kE, 0, kTL }, kDontShare },
166 // Two non-overlapping intervals w/ _very different_ approx sizes should not share
167 { { 255, kRT, kRGBA, kA, 0, kTL }, { 127, kRT, kRGBA, kA, 0, kTL }, kDontShare },
168 // Two non-overlapping intervals w/ different MSAA sample counts should not share
169 { { 64, kRT, kRGBA, kA, k2, kTL },{ 64, kRT, kRGBA, kA, k4, kTL}, k2 == k4 },
170 // Two non-overlapping intervals w/ different configs should not share
171 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kBGRA, kA, 0, kTL }, kDontShare },
172 // Two non-overlapping intervals w/ different RT classifications should never share
173 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
174 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400175 // Two non-overlapping intervals w/ different origins should share
176 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kBL }, kShare },
Robert Phillips57aa3672017-07-21 11:38:13 -0400177 };
178
179 for (auto test : gNonOverlappingTests) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500180 sk_sp<GrSurfaceProxy> p1 = make_deferred(proxyProvider, test.fP1);
181 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, test.fP2);
Robert Phillips57aa3672017-07-21 11:38:13 -0400182 if (!p1 || !p2) {
183 continue; // creation can fail (i.e., for msaa4 on iOS)
184 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500185 non_overlap_test(reporter, resourceProvider,
186 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400187 }
188
189 {
190 // Wrapped backend textures should never be reused
191 TestCase t[1] = {
192 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kDontShare }
193 };
194
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500195 GrBackendTexture backEndTex;
196 sk_sp<GrSurfaceProxy> p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndTex);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500197 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, t[0].fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500198 non_overlap_test(reporter, resourceProvider,
199 std::move(p1), std::move(p2), t[0].fExpectation);
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500200 cleanup_backend(ctxInfo.grContext(), &backEndTex);
Robert Phillips57aa3672017-07-21 11:38:13 -0400201 }
Robert Phillips5af44de2017-07-18 14:49:38 -0400202}
203
204#endif
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400205#endif