blob: fb9ac542caf547dc63bb049fb7874210460e0644 [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
11#if SK_SUPPORT_GPU
12#include "Test.h"
13
Robert Phillips57aa3672017-07-21 11:38:13 -040014#include "GrContextPriv.h"
15#include "GrGpu.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040016#include "GrResourceAllocator.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040017#include "GrResourceProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040018#include "GrSurfaceProxyPriv.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040019#include "GrTest.h"
20#include "GrTexture.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040021#include "GrTextureProxy.h"
22
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
33static sk_sp<GrSurfaceProxy> make_deferred(GrResourceProvider* resourceProvider,
34 const ProxyParams& p) {
35 GrSurfaceDesc desc;
36 desc.fFlags = p.fIsRT ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
37 desc.fOrigin = p.fOrigin;
38 desc.fWidth = p.fSize;
39 desc.fHeight = p.fSize;
40 desc.fConfig = p.fConfig;
41 desc.fSampleCnt = p.fSampleCnt;
42
43 return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, p.fFit, SkBudgeted::kNo);
44}
45
46static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
47 GrBackendObject* backendTexHandle) {
48 *backendTexHandle = context->getGpu()->createTestingOnlyBackendTexture(
49 nullptr, p.fSize, p.fSize, p.fConfig);
50 GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
51 p.fSize,
52 p.fSize,
53 p.fConfig,
54 *backendTexHandle);
55
Robert Phillipsb0e93a22017-08-29 08:26:54 -040056 sk_sp<GrSurface> tex = context->resourceProvider()->wrapBackendTexture(backendTex,
Robert Phillips16d8ec62017-07-27 16:16:25 -040057 kBorrow_GrWrapOwnership);
Robert Phillips066f0202017-07-25 10:16:35 -040058 return GrSurfaceProxy::MakeWrapped(std::move(tex), p.fOrigin);
Robert Phillips57aa3672017-07-21 11:38:13 -040059}
60
61static void cleanup_backend(GrContext* context, GrBackendObject* backendTexHandle) {
62 context->getGpu()->deleteTestingOnlyBackendTexture(*backendTexHandle);
63}
64
Robert Phillips5af44de2017-07-18 14:49:38 -040065// Basic test that two proxies with overlapping intervals and compatible descriptors are
66// assigned different GrSurfaces.
Robert Phillips57aa3672017-07-21 11:38:13 -040067static void overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
68 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
69 bool expectedResult) {
Robert Phillips5af44de2017-07-18 14:49:38 -040070 GrResourceAllocator alloc(resourceProvider);
71
72 alloc.addInterval(p1.get(), 0, 4);
73 alloc.addInterval(p2.get(), 1, 2);
74
75 alloc.assign();
76
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);
92
93 alloc.assign();
94
95 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
96 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
97 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
98 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
99}
100
101DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
Robert Phillips5af44de2017-07-18 14:49:38 -0400102 GrResourceProvider* resourceProvider = ctxInfo.grContext()->resourceProvider();
103
Robert Phillips57aa3672017-07-21 11:38:13 -0400104 struct TestCase {
105 ProxyParams fP1;
106 ProxyParams fP2;
107 bool fExpectation;
108 };
109
110 constexpr bool kRT = true;
111 constexpr bool kNotRT = false;
112
113 constexpr bool kShare = true;
114 constexpr bool kDontShare = false;
115 // Non-RT GrSurfaces are never recycled on some platforms.
116 bool kConditionallyShare = resourceProvider->caps()->reuseScratchTextures();
117
118 const GrPixelConfig kRGBA = kRGBA_8888_GrPixelConfig;
119 const GrPixelConfig kBGRA = kBGRA_8888_GrPixelConfig;
120
121 const SkBackingFit kE = SkBackingFit::kExact;
122 const SkBackingFit kA = SkBackingFit::kApprox;
123
124 const GrSurfaceOrigin kTL = kTopLeft_GrSurfaceOrigin;
125 const GrSurfaceOrigin kBL = kBottomLeft_GrSurfaceOrigin;
126
127 //--------------------------------------------------------------------------------------------
128 TestCase gOverlappingTests[] = {
129 //----------------------------------------------------------------------------------------
130 // Two proxies with overlapping intervals and compatible descriptors should never share
131 // RT version
132 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
133 // non-RT version
134 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
135 };
136
137 for (auto test : gOverlappingTests) {
138 sk_sp<GrSurfaceProxy> p1 = make_deferred(resourceProvider, test.fP1);
139 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, test.fP2);
140 overlap_test(reporter, resourceProvider, std::move(p1), std::move(p2), test.fExpectation);
141 }
142
143 int k2 = ctxInfo.grContext()->caps()->getSampleCount(2, kRGBA);
144 int k4 = ctxInfo.grContext()->caps()->getSampleCount(4, kRGBA);
145
146 //--------------------------------------------------------------------------------------------
147 TestCase gNonOverlappingTests[] = {
148 //----------------------------------------------------------------------------------------
149 // Two non-overlapping intervals w/ compatible proxies should share
150 // both same size & approx
151 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kShare },
152 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
153 // diffs sizes but still approx
154 { { 64, kRT, kRGBA, kA, 0, kTL }, { 50, kRT, kRGBA, kA, 0, kTL }, kShare },
155 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 50, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
156 // sames sizes but exact
157 { { 64, kRT, kRGBA, kE, 0, kTL }, { 64, kRT, kRGBA, kE, 0, kTL }, kShare },
158 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kConditionallyShare },
159 //----------------------------------------------------------------------------------------
160 // Two non-overlapping intervals w/ different exact sizes should not share
161 { { 56, kRT, kRGBA, kE, 0, kTL }, { 54, kRT, kRGBA, kE, 0, kTL }, kDontShare },
162 // Two non-overlapping intervals w/ _very different_ approx sizes should not share
163 { { 255, kRT, kRGBA, kA, 0, kTL }, { 127, kRT, kRGBA, kA, 0, kTL }, kDontShare },
164 // Two non-overlapping intervals w/ different MSAA sample counts should not share
165 { { 64, kRT, kRGBA, kA, k2, kTL },{ 64, kRT, kRGBA, kA, k4, kTL}, k2 == k4 },
166 // Two non-overlapping intervals w/ different configs should not share
167 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kBGRA, kA, 0, kTL }, kDontShare },
168 // Two non-overlapping intervals w/ different RT classifications should never share
169 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
170 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400171 // Two non-overlapping intervals w/ different origins should share
172 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kBL }, kShare },
Robert Phillips57aa3672017-07-21 11:38:13 -0400173 };
174
175 for (auto test : gNonOverlappingTests) {
176 sk_sp<GrSurfaceProxy> p1 = make_deferred(resourceProvider, test.fP1);
177 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, test.fP2);
178 if (!p1 || !p2) {
179 continue; // creation can fail (i.e., for msaa4 on iOS)
180 }
181 non_overlap_test(reporter, resourceProvider, std::move(p1), std::move(p2),
182 test.fExpectation);
183 }
184
185 {
186 // Wrapped backend textures should never be reused
187 TestCase t[1] = {
188 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kDontShare }
189 };
190
191 GrBackendObject backEndObj;
192 sk_sp<GrSurfaceProxy> p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndObj);
193 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, t[0].fP2);
194 non_overlap_test(reporter, resourceProvider, std::move(p1), std::move(p2),
195 t[0].fExpectation);
196 cleanup_backend(ctxInfo.grContext(), &backEndObj);
197 }
Robert Phillips5af44de2017-07-18 14:49:38 -0400198}
199
200#endif