blob: 51ecdb7ed05428aebdddd01d8f2444f1a6d0e6a3 [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
Robert Phillips5af44de2017-07-18 14:49:38 -04008#include "SkTypes.h"
9
Robert Phillips5af44de2017-07-18 14:49:38 -040010#include "Test.h"
11
Robert Phillips57aa3672017-07-21 11:38:13 -040012#include "GrContextPriv.h"
13#include "GrGpu.h"
Robert Phillips0bd24dc2018-01-16 08:06:32 -050014#include "GrProxyProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040015#include "GrResourceAllocator.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040016#include "GrResourceProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040017#include "GrSurfaceProxyPriv.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040018#include "GrTest.h"
19#include "GrTexture.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040020#include "GrTextureProxy.h"
Greg Daniel4684f822018-03-08 15:27:36 -050021#include "GrUninstantiateProxyTracker.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040022
Robert Phillips57aa3672017-07-21 11:38:13 -040023struct ProxyParams {
24 int fSize;
25 bool fIsRT;
26 GrPixelConfig fConfig;
27 SkBackingFit fFit;
28 int fSampleCnt;
29 GrSurfaceOrigin fOrigin;
30 // TODO: do we care about mipmapping
31};
32
Robert Phillips1afd4cd2018-01-08 13:40:32 -050033static sk_sp<GrSurfaceProxy> make_deferred(GrProxyProvider* proxyProvider, const ProxyParams& p) {
Robert Phillips57aa3672017-07-21 11:38:13 -040034 GrSurfaceDesc desc;
35 desc.fFlags = p.fIsRT ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
Robert Phillips57aa3672017-07-21 11:38:13 -040036 desc.fWidth = p.fSize;
37 desc.fHeight = p.fSize;
38 desc.fConfig = p.fConfig;
39 desc.fSampleCnt = p.fSampleCnt;
40
Brian Salomon2a4f9832018-03-03 22:43:43 -050041 return proxyProvider->createProxy(desc, p.fOrigin, p.fFit, SkBudgeted::kNo);
Robert Phillips57aa3672017-07-21 11:38:13 -040042}
43
44static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
Robert Phillipsd21b2a52017-12-12 13:01:25 -050045 GrBackendTexture* backendTex) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050046 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050047 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips0bd24dc2018-01-16 08:06:32 -050048
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050049 *backendTex = gpu->createTestingOnlyBackendTexture(nullptr, p.fSize, p.fSize,
50 p.fConfig, false,
51 GrMipMapped::kNo);
Robert Phillips57aa3672017-07-21 11:38:13 -040052
Brian Salomon7578f3e2018-03-07 14:39:54 -050053 return proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin);
Robert Phillips57aa3672017-07-21 11:38:13 -040054}
55
Brian Salomon26102cb2018-03-09 09:33:19 -050056static void cleanup_backend(GrContext* context, const GrBackendTexture& backendTex) {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050057 context->contextPriv().getGpu()->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillips57aa3672017-07-21 11:38:13 -040058}
59
Robert Phillips5af44de2017-07-18 14:49:38 -040060// Basic test that two proxies with overlapping intervals and compatible descriptors are
61// assigned different GrSurfaces.
Robert Phillips57aa3672017-07-21 11:38:13 -040062static void overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
63 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
64 bool expectedResult) {
Robert Phillips5af44de2017-07-18 14:49:38 -040065 GrResourceAllocator alloc(resourceProvider);
66
67 alloc.addInterval(p1.get(), 0, 4);
68 alloc.addInterval(p2.get(), 1, 2);
Robert Phillipseafd48a2017-11-16 07:52:08 -050069 alloc.markEndOfOpList(0);
Robert Phillips5af44de2017-07-18 14:49:38 -040070
Robert Phillipseafd48a2017-11-16 07:52:08 -050071 int startIndex, stopIndex;
Greg Danielaa3dfbe2018-01-29 10:34:25 -050072 GrResourceAllocator::AssignError error;
Greg Daniel4684f822018-03-08 15:27:36 -050073 GrUninstantiateProxyTracker uninstantiateTracker;
74 alloc.assign(&startIndex, &stopIndex, &uninstantiateTracker, &error);
Greg Danielaa3dfbe2018-01-29 10:34:25 -050075 REPORTER_ASSERT(reporter, GrResourceAllocator::AssignError::kNoError == error);
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;
Greg Danielaa3dfbe2018-01-29 10:34:25 -050095 GrResourceAllocator::AssignError error;
Greg Daniel4684f822018-03-08 15:27:36 -050096 GrUninstantiateProxyTracker uninstantiateTracker;
97 alloc.assign(&startIndex, &stopIndex, &uninstantiateTracker, &error);
Greg Danielaa3dfbe2018-01-29 10:34:25 -050098 REPORTER_ASSERT(reporter, GrResourceAllocator::AssignError::kNoError == error);
Robert Phillips57aa3672017-07-21 11:38:13 -040099
100 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
101 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
102 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
103 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
104}
105
Robert Phillips4150eea2018-02-07 17:08:21 -0500106bool GrResourceProvider::testingOnly_setExplicitlyAllocateGPUResources(bool newValue) {
107 bool oldValue = fExplicitlyAllocateGPUResources;
108 fExplicitlyAllocateGPUResources = newValue;
109 return oldValue;
110}
111
Robert Phillips57aa3672017-07-21 11:38:13 -0400112DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500113 GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500114 GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
Robert Phillips5af44de2017-07-18 14:49:38 -0400115
Robert Phillips4150eea2018-02-07 17:08:21 -0500116 bool orig = resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(true);
117
Robert Phillips57aa3672017-07-21 11:38:13 -0400118 struct TestCase {
119 ProxyParams fP1;
120 ProxyParams fP2;
121 bool fExpectation;
122 };
123
124 constexpr bool kRT = true;
125 constexpr bool kNotRT = false;
126
127 constexpr bool kShare = true;
128 constexpr bool kDontShare = false;
129 // Non-RT GrSurfaces are never recycled on some platforms.
130 bool kConditionallyShare = resourceProvider->caps()->reuseScratchTextures();
131
132 const GrPixelConfig kRGBA = kRGBA_8888_GrPixelConfig;
133 const GrPixelConfig kBGRA = kBGRA_8888_GrPixelConfig;
134
135 const SkBackingFit kE = SkBackingFit::kExact;
136 const SkBackingFit kA = SkBackingFit::kApprox;
137
138 const GrSurfaceOrigin kTL = kTopLeft_GrSurfaceOrigin;
139 const GrSurfaceOrigin kBL = kBottomLeft_GrSurfaceOrigin;
140
141 //--------------------------------------------------------------------------------------------
142 TestCase gOverlappingTests[] = {
143 //----------------------------------------------------------------------------------------
144 // Two proxies with overlapping intervals and compatible descriptors should never share
145 // RT version
146 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
147 // non-RT version
148 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
149 };
150
151 for (auto test : gOverlappingTests) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500152 sk_sp<GrSurfaceProxy> p1 = make_deferred(proxyProvider, test.fP1);
153 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, test.fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500154 overlap_test(reporter, resourceProvider,
155 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400156 }
157
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400158 int k2 = ctxInfo.grContext()->contextPriv().caps()->getRenderTargetSampleCount(2, kRGBA);
159 int k4 = ctxInfo.grContext()->contextPriv().caps()->getRenderTargetSampleCount(4, kRGBA);
Robert Phillips57aa3672017-07-21 11:38:13 -0400160
161 //--------------------------------------------------------------------------------------------
162 TestCase gNonOverlappingTests[] = {
163 //----------------------------------------------------------------------------------------
164 // Two non-overlapping intervals w/ compatible proxies should share
165 // both same size & approx
166 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kShare },
167 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
168 // diffs sizes but still approx
169 { { 64, kRT, kRGBA, kA, 0, kTL }, { 50, kRT, kRGBA, kA, 0, kTL }, kShare },
170 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 50, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
171 // sames sizes but exact
172 { { 64, kRT, kRGBA, kE, 0, kTL }, { 64, kRT, kRGBA, kE, 0, kTL }, kShare },
173 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kConditionallyShare },
174 //----------------------------------------------------------------------------------------
175 // Two non-overlapping intervals w/ different exact sizes should not share
176 { { 56, kRT, kRGBA, kE, 0, kTL }, { 54, kRT, kRGBA, kE, 0, kTL }, kDontShare },
177 // Two non-overlapping intervals w/ _very different_ approx sizes should not share
178 { { 255, kRT, kRGBA, kA, 0, kTL }, { 127, kRT, kRGBA, kA, 0, kTL }, kDontShare },
179 // Two non-overlapping intervals w/ different MSAA sample counts should not share
180 { { 64, kRT, kRGBA, kA, k2, kTL },{ 64, kRT, kRGBA, kA, k4, kTL}, k2 == k4 },
181 // Two non-overlapping intervals w/ different configs should not share
182 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kBGRA, kA, 0, kTL }, kDontShare },
183 // Two non-overlapping intervals w/ different RT classifications should never share
184 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
185 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400186 // Two non-overlapping intervals w/ different origins should share
187 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kBL }, kShare },
Robert Phillips57aa3672017-07-21 11:38:13 -0400188 };
189
190 for (auto test : gNonOverlappingTests) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500191 sk_sp<GrSurfaceProxy> p1 = make_deferred(proxyProvider, test.fP1);
192 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, test.fP2);
Robert Phillips57aa3672017-07-21 11:38:13 -0400193 if (!p1 || !p2) {
194 continue; // creation can fail (i.e., for msaa4 on iOS)
195 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500196 non_overlap_test(reporter, resourceProvider,
197 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400198 }
199
200 {
201 // Wrapped backend textures should never be reused
202 TestCase t[1] = {
203 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kDontShare }
204 };
205
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500206 GrBackendTexture backEndTex;
207 sk_sp<GrSurfaceProxy> p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndTex);
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500208 sk_sp<GrSurfaceProxy> p2 = make_deferred(proxyProvider, t[0].fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500209 non_overlap_test(reporter, resourceProvider,
210 std::move(p1), std::move(p2), t[0].fExpectation);
Brian Salomon26102cb2018-03-09 09:33:19 -0500211 cleanup_backend(ctxInfo.grContext(), backEndTex);
Robert Phillips57aa3672017-07-21 11:38:13 -0400212 }
Robert Phillips4150eea2018-02-07 17:08:21 -0500213
214 resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(orig);
Robert Phillips5af44de2017-07-18 14:49:38 -0400215}