blob: 4751803a6baf3815e11016c0320feef9396feaa9 [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 Phillips715d08c2018-07-18 13:56:48 -040033static 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
Robert Phillips715d08c2018-07-18 13:56:48 -040041 auto tmp = proxyProvider->createProxy(desc, p.fOrigin, p.fFit, SkBudgeted::kNo);
42 if (!tmp) {
43 return nullptr;
44 }
45 GrSurfaceProxy* ret = tmp.release();
46
47 // Add a read to keep the proxy around but unref it so its backing surfaces can be recycled
48 ret->addPendingRead();
49 ret->unref();
50 return ret;
Robert Phillips57aa3672017-07-21 11:38:13 -040051}
52
Robert Phillips715d08c2018-07-18 13:56:48 -040053static GrSurfaceProxy* make_backend(GrContext* context, const ProxyParams& p,
54 GrBackendTexture* backendTex) {
Robert Phillips0bd24dc2018-01-16 08:06:32 -050055 GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050056 GrGpu* gpu = context->contextPriv().getGpu();
Robert Phillips0bd24dc2018-01-16 08:06:32 -050057
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050058 *backendTex = gpu->createTestingOnlyBackendTexture(nullptr, p.fSize, p.fSize,
59 p.fConfig, false,
60 GrMipMapped::kNo);
Robert Phillips57aa3672017-07-21 11:38:13 -040061
Robert Phillips715d08c2018-07-18 13:56:48 -040062 auto tmp = proxyProvider->wrapBackendTexture(*backendTex, p.fOrigin);
63 if (!tmp) {
64 return nullptr;
65 }
66 GrSurfaceProxy* ret = tmp.release();
67
68 // Add a read to keep the proxy around but unref it so its backing surfaces can be recycled
69 ret->addPendingRead();
70 ret->unref();
71 return ret;
Robert Phillips57aa3672017-07-21 11:38:13 -040072}
73
Brian Salomon26102cb2018-03-09 09:33:19 -050074static void cleanup_backend(GrContext* context, const GrBackendTexture& backendTex) {
Robert Phillipsf35fd8d2018-01-22 10:48:15 -050075 context->contextPriv().getGpu()->deleteTestingOnlyBackendTexture(backendTex);
Robert Phillips57aa3672017-07-21 11:38:13 -040076}
77
Robert Phillips5af44de2017-07-18 14:49:38 -040078// Basic test that two proxies with overlapping intervals and compatible descriptors are
79// assigned different GrSurfaces.
Robert Phillips57aa3672017-07-21 11:38:13 -040080static void overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
Robert Phillips715d08c2018-07-18 13:56:48 -040081 GrSurfaceProxy* p1, GrSurfaceProxy* p2, bool expectedResult) {
Robert Phillips5af44de2017-07-18 14:49:38 -040082 GrResourceAllocator alloc(resourceProvider);
83
Robert Phillips715d08c2018-07-18 13:56:48 -040084 alloc.addInterval(p1, 0, 4);
85 alloc.addInterval(p2, 1, 2);
Robert Phillipseafd48a2017-11-16 07:52:08 -050086 alloc.markEndOfOpList(0);
Robert Phillips5af44de2017-07-18 14:49:38 -040087
Robert Phillipseafd48a2017-11-16 07:52:08 -050088 int startIndex, stopIndex;
Greg Danielaa3dfbe2018-01-29 10:34:25 -050089 GrResourceAllocator::AssignError error;
Greg Daniel4684f822018-03-08 15:27:36 -050090 GrUninstantiateProxyTracker uninstantiateTracker;
91 alloc.assign(&startIndex, &stopIndex, &uninstantiateTracker, &error);
Greg Danielaa3dfbe2018-01-29 10:34:25 -050092 REPORTER_ASSERT(reporter, GrResourceAllocator::AssignError::kNoError == error);
Robert Phillips5af44de2017-07-18 14:49:38 -040093
Brian Salomonfd98c2c2018-07-31 17:25:29 -040094 REPORTER_ASSERT(reporter, p1->peekSurface());
95 REPORTER_ASSERT(reporter, p2->peekSurface());
Robert Phillips57aa3672017-07-21 11:38:13 -040096 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
97 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
Robert Phillips5af44de2017-07-18 14:49:38 -040098}
99
Robert Phillips57aa3672017-07-21 11:38:13 -0400100// Test various cases when two proxies do not have overlapping intervals.
101// This mainly acts as a test of the ResourceAllocator's free pool.
102static void non_overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
Robert Phillips715d08c2018-07-18 13:56:48 -0400103 GrSurfaceProxy* p1, GrSurfaceProxy* p2,
Robert Phillips57aa3672017-07-21 11:38:13 -0400104 bool expectedResult) {
105 GrResourceAllocator alloc(resourceProvider);
106
Robert Phillips715d08c2018-07-18 13:56:48 -0400107 alloc.addInterval(p1, 0, 2);
108 alloc.addInterval(p2, 3, 5);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500109 alloc.markEndOfOpList(0);
Robert Phillips57aa3672017-07-21 11:38:13 -0400110
Robert Phillipseafd48a2017-11-16 07:52:08 -0500111 int startIndex, stopIndex;
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500112 GrResourceAllocator::AssignError error;
Greg Daniel4684f822018-03-08 15:27:36 -0500113 GrUninstantiateProxyTracker uninstantiateTracker;
114 alloc.assign(&startIndex, &stopIndex, &uninstantiateTracker, &error);
Greg Danielaa3dfbe2018-01-29 10:34:25 -0500115 REPORTER_ASSERT(reporter, GrResourceAllocator::AssignError::kNoError == error);
Robert Phillips57aa3672017-07-21 11:38:13 -0400116
Brian Salomonfd98c2c2018-07-31 17:25:29 -0400117 REPORTER_ASSERT(reporter, p1->peekSurface());
118 REPORTER_ASSERT(reporter, p2->peekSurface());
Robert Phillips57aa3672017-07-21 11:38:13 -0400119 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
120 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
121}
122
Robert Phillips4150eea2018-02-07 17:08:21 -0500123bool GrResourceProvider::testingOnly_setExplicitlyAllocateGPUResources(bool newValue) {
124 bool oldValue = fExplicitlyAllocateGPUResources;
125 fExplicitlyAllocateGPUResources = newValue;
126 return oldValue;
127}
128
Robert Phillips57aa3672017-07-21 11:38:13 -0400129DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
Robert Phillips1afd4cd2018-01-08 13:40:32 -0500130 GrProxyProvider* proxyProvider = ctxInfo.grContext()->contextPriv().proxyProvider();
Robert Phillips6be756b2018-01-16 15:07:54 -0500131 GrResourceProvider* resourceProvider = ctxInfo.grContext()->contextPriv().resourceProvider();
Robert Phillips5af44de2017-07-18 14:49:38 -0400132
Robert Phillips4150eea2018-02-07 17:08:21 -0500133 bool orig = resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(true);
134
Robert Phillips57aa3672017-07-21 11:38:13 -0400135 struct TestCase {
136 ProxyParams fP1;
137 ProxyParams fP2;
138 bool fExpectation;
139 };
140
141 constexpr bool kRT = true;
142 constexpr bool kNotRT = false;
143
144 constexpr bool kShare = true;
145 constexpr bool kDontShare = false;
146 // Non-RT GrSurfaces are never recycled on some platforms.
147 bool kConditionallyShare = resourceProvider->caps()->reuseScratchTextures();
148
149 const GrPixelConfig kRGBA = kRGBA_8888_GrPixelConfig;
150 const GrPixelConfig kBGRA = kBGRA_8888_GrPixelConfig;
151
152 const SkBackingFit kE = SkBackingFit::kExact;
153 const SkBackingFit kA = SkBackingFit::kApprox;
154
155 const GrSurfaceOrigin kTL = kTopLeft_GrSurfaceOrigin;
156 const GrSurfaceOrigin kBL = kBottomLeft_GrSurfaceOrigin;
157
158 //--------------------------------------------------------------------------------------------
159 TestCase gOverlappingTests[] = {
160 //----------------------------------------------------------------------------------------
161 // Two proxies with overlapping intervals and compatible descriptors should never share
162 // RT version
163 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
164 // non-RT version
165 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
166 };
167
168 for (auto test : gOverlappingTests) {
Robert Phillips715d08c2018-07-18 13:56:48 -0400169 GrSurfaceProxy* p1 = make_deferred(proxyProvider, test.fP1);
170 GrSurfaceProxy* p2 = make_deferred(proxyProvider, test.fP2);
171 overlap_test(reporter, resourceProvider, p1, p2, test.fExpectation);
172 p1->completedRead();
173 p2->completedRead();
Robert Phillips57aa3672017-07-21 11:38:13 -0400174 }
175
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400176 int k2 = ctxInfo.grContext()->contextPriv().caps()->getRenderTargetSampleCount(2, kRGBA);
177 int k4 = ctxInfo.grContext()->contextPriv().caps()->getRenderTargetSampleCount(4, kRGBA);
Robert Phillips57aa3672017-07-21 11:38:13 -0400178
179 //--------------------------------------------------------------------------------------------
180 TestCase gNonOverlappingTests[] = {
181 //----------------------------------------------------------------------------------------
182 // Two non-overlapping intervals w/ compatible proxies should share
183 // both same size & approx
184 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kShare },
185 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
186 // diffs sizes but still approx
187 { { 64, kRT, kRGBA, kA, 0, kTL }, { 50, kRT, kRGBA, kA, 0, kTL }, kShare },
188 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 50, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
189 // sames sizes but exact
190 { { 64, kRT, kRGBA, kE, 0, kTL }, { 64, kRT, kRGBA, kE, 0, kTL }, kShare },
191 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kConditionallyShare },
192 //----------------------------------------------------------------------------------------
193 // Two non-overlapping intervals w/ different exact sizes should not share
194 { { 56, kRT, kRGBA, kE, 0, kTL }, { 54, kRT, kRGBA, kE, 0, kTL }, kDontShare },
195 // Two non-overlapping intervals w/ _very different_ approx sizes should not share
196 { { 255, kRT, kRGBA, kA, 0, kTL }, { 127, kRT, kRGBA, kA, 0, kTL }, kDontShare },
197 // Two non-overlapping intervals w/ different MSAA sample counts should not share
198 { { 64, kRT, kRGBA, kA, k2, kTL },{ 64, kRT, kRGBA, kA, k4, kTL}, k2 == k4 },
199 // Two non-overlapping intervals w/ different configs should not share
200 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kBGRA, kA, 0, kTL }, kDontShare },
201 // Two non-overlapping intervals w/ different RT classifications should never share
202 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
203 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400204 // Two non-overlapping intervals w/ different origins should share
205 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kBL }, kShare },
Robert Phillips57aa3672017-07-21 11:38:13 -0400206 };
207
208 for (auto test : gNonOverlappingTests) {
Robert Phillips715d08c2018-07-18 13:56:48 -0400209 GrSurfaceProxy* p1 = make_deferred(proxyProvider, test.fP1);
210 GrSurfaceProxy* p2 = make_deferred(proxyProvider, test.fP2);
211
Robert Phillips57aa3672017-07-21 11:38:13 -0400212 if (!p1 || !p2) {
213 continue; // creation can fail (i.e., for msaa4 on iOS)
214 }
Robert Phillips715d08c2018-07-18 13:56:48 -0400215
216 non_overlap_test(reporter, resourceProvider, p1, p2, test.fExpectation);
217
218 p1->completedRead();
219 p2->completedRead();
Robert Phillips57aa3672017-07-21 11:38:13 -0400220 }
221
222 {
223 // Wrapped backend textures should never be reused
224 TestCase t[1] = {
225 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kDontShare }
226 };
227
Robert Phillipsd21b2a52017-12-12 13:01:25 -0500228 GrBackendTexture backEndTex;
Robert Phillips715d08c2018-07-18 13:56:48 -0400229 GrSurfaceProxy* p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndTex);
230 GrSurfaceProxy* p2 = make_deferred(proxyProvider, t[0].fP2);
231
232 non_overlap_test(reporter, resourceProvider, p1, p2, t[0].fExpectation);
233
234 p1->completedRead();
235 p2->completedRead();
236
Brian Salomon26102cb2018-03-09 09:33:19 -0500237 cleanup_backend(ctxInfo.grContext(), backEndTex);
Robert Phillips57aa3672017-07-21 11:38:13 -0400238 }
Robert Phillips4150eea2018-02-07 17:08:21 -0500239
240 resourceProvider->testingOnly_setExplicitlyAllocateGPUResources(orig);
Robert Phillips5af44de2017-07-18 14:49:38 -0400241}