blob: 02785e6aa171688f8716620e4f86ae5f1cbfe642 [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 Phillips5af44de2017-07-18 14:49:38 -040017#include "GrResourceAllocator.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040018#include "GrResourceProvider.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040019#include "GrSurfaceProxyPriv.h"
Robert Phillips57aa3672017-07-21 11:38:13 -040020#include "GrTest.h"
21#include "GrTexture.h"
Robert Phillips5af44de2017-07-18 14:49:38 -040022#include "GrTextureProxy.h"
23
Robert Phillips57aa3672017-07-21 11:38:13 -040024struct ProxyParams {
25 int fSize;
26 bool fIsRT;
27 GrPixelConfig fConfig;
28 SkBackingFit fFit;
29 int fSampleCnt;
30 GrSurfaceOrigin fOrigin;
31 // TODO: do we care about mipmapping
32};
33
34static sk_sp<GrSurfaceProxy> make_deferred(GrResourceProvider* resourceProvider,
35 const ProxyParams& p) {
36 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
44 return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, p.fFit, SkBudgeted::kNo);
45}
46
47static sk_sp<GrSurfaceProxy> make_backend(GrContext* context, const ProxyParams& p,
48 GrBackendObject* backendTexHandle) {
49 *backendTexHandle = context->getGpu()->createTestingOnlyBackendTexture(
50 nullptr, p.fSize, p.fSize, p.fConfig);
51 GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
52 p.fSize,
53 p.fSize,
54 p.fConfig,
Greg Daniel177e6952017-10-12 12:27:11 -040055 GrMipMapped::kNo,
Robert Phillips57aa3672017-07-21 11:38:13 -040056 *backendTexHandle);
57
Robert Phillipsb0e93a22017-08-29 08:26:54 -040058 sk_sp<GrSurface> tex = context->resourceProvider()->wrapBackendTexture(backendTex,
Robert Phillips16d8ec62017-07-27 16:16:25 -040059 kBorrow_GrWrapOwnership);
Robert Phillips066f0202017-07-25 10:16:35 -040060 return GrSurfaceProxy::MakeWrapped(std::move(tex), p.fOrigin);
Robert Phillips57aa3672017-07-21 11:38:13 -040061}
62
63static void cleanup_backend(GrContext* context, GrBackendObject* backendTexHandle) {
64 context->getGpu()->deleteTestingOnlyBackendTexture(*backendTexHandle);
65}
66
Robert Phillips5af44de2017-07-18 14:49:38 -040067// Basic test that two proxies with overlapping intervals and compatible descriptors are
68// assigned different GrSurfaces.
Robert Phillips57aa3672017-07-21 11:38:13 -040069static void overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
70 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
71 bool expectedResult) {
Robert Phillips5af44de2017-07-18 14:49:38 -040072 GrResourceAllocator alloc(resourceProvider);
73
74 alloc.addInterval(p1.get(), 0, 4);
75 alloc.addInterval(p2.get(), 1, 2);
Robert Phillipseafd48a2017-11-16 07:52:08 -050076 alloc.markEndOfOpList(0);
Robert Phillips5af44de2017-07-18 14:49:38 -040077
Robert Phillipseafd48a2017-11-16 07:52:08 -050078 int startIndex, stopIndex;
79 alloc.assign(&startIndex, &stopIndex);
Robert Phillips5af44de2017-07-18 14:49:38 -040080
81 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
82 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
Robert Phillips57aa3672017-07-21 11:38:13 -040083 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
84 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
Robert Phillips5af44de2017-07-18 14:49:38 -040085}
86
Robert Phillips57aa3672017-07-21 11:38:13 -040087// Test various cases when two proxies do not have overlapping intervals.
88// This mainly acts as a test of the ResourceAllocator's free pool.
89static void non_overlap_test(skiatest::Reporter* reporter, GrResourceProvider* resourceProvider,
90 sk_sp<GrSurfaceProxy> p1, sk_sp<GrSurfaceProxy> p2,
91 bool expectedResult) {
92 GrResourceAllocator alloc(resourceProvider);
93
94 alloc.addInterval(p1.get(), 0, 2);
95 alloc.addInterval(p2.get(), 3, 5);
Robert Phillipseafd48a2017-11-16 07:52:08 -050096 alloc.markEndOfOpList(0);
Robert Phillips57aa3672017-07-21 11:38:13 -040097
Robert Phillipseafd48a2017-11-16 07:52:08 -050098 int startIndex, stopIndex;
99 alloc.assign(&startIndex, &stopIndex);
Robert Phillips57aa3672017-07-21 11:38:13 -0400100
101 REPORTER_ASSERT(reporter, p1->priv().peekSurface());
102 REPORTER_ASSERT(reporter, p2->priv().peekSurface());
103 bool doTheBackingStoresMatch = p1->underlyingUniqueID() == p2->underlyingUniqueID();
104 REPORTER_ASSERT(reporter, expectedResult == doTheBackingStoresMatch);
105}
106
107DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceAllocatorTest, reporter, ctxInfo) {
Robert Phillips5af44de2017-07-18 14:49:38 -0400108 GrResourceProvider* resourceProvider = ctxInfo.grContext()->resourceProvider();
109
Robert Phillips57aa3672017-07-21 11:38:13 -0400110 struct TestCase {
111 ProxyParams fP1;
112 ProxyParams fP2;
113 bool fExpectation;
114 };
115
116 constexpr bool kRT = true;
117 constexpr bool kNotRT = false;
118
119 constexpr bool kShare = true;
120 constexpr bool kDontShare = false;
121 // Non-RT GrSurfaces are never recycled on some platforms.
122 bool kConditionallyShare = resourceProvider->caps()->reuseScratchTextures();
123
124 const GrPixelConfig kRGBA = kRGBA_8888_GrPixelConfig;
125 const GrPixelConfig kBGRA = kBGRA_8888_GrPixelConfig;
126
127 const SkBackingFit kE = SkBackingFit::kExact;
128 const SkBackingFit kA = SkBackingFit::kApprox;
129
130 const GrSurfaceOrigin kTL = kTopLeft_GrSurfaceOrigin;
131 const GrSurfaceOrigin kBL = kBottomLeft_GrSurfaceOrigin;
132
133 //--------------------------------------------------------------------------------------------
134 TestCase gOverlappingTests[] = {
135 //----------------------------------------------------------------------------------------
136 // Two proxies with overlapping intervals and compatible descriptors should never share
137 // RT version
138 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
139 // non-RT version
140 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
141 };
142
143 for (auto test : gOverlappingTests) {
144 sk_sp<GrSurfaceProxy> p1 = make_deferred(resourceProvider, test.fP1);
145 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, test.fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500146 overlap_test(reporter, resourceProvider,
147 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400148 }
149
150 int k2 = ctxInfo.grContext()->caps()->getSampleCount(2, kRGBA);
151 int k4 = ctxInfo.grContext()->caps()->getSampleCount(4, kRGBA);
152
153 //--------------------------------------------------------------------------------------------
154 TestCase gNonOverlappingTests[] = {
155 //----------------------------------------------------------------------------------------
156 // Two non-overlapping intervals w/ compatible proxies should share
157 // both same size & approx
158 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kShare },
159 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
160 // diffs sizes but still approx
161 { { 64, kRT, kRGBA, kA, 0, kTL }, { 50, kRT, kRGBA, kA, 0, kTL }, kShare },
162 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 50, kNotRT, kRGBA, kA, 0, kTL }, kConditionallyShare },
163 // sames sizes but exact
164 { { 64, kRT, kRGBA, kE, 0, kTL }, { 64, kRT, kRGBA, kE, 0, kTL }, kShare },
165 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kConditionallyShare },
166 //----------------------------------------------------------------------------------------
167 // Two non-overlapping intervals w/ different exact sizes should not share
168 { { 56, kRT, kRGBA, kE, 0, kTL }, { 54, kRT, kRGBA, kE, 0, kTL }, kDontShare },
169 // Two non-overlapping intervals w/ _very different_ approx sizes should not share
170 { { 255, kRT, kRGBA, kA, 0, kTL }, { 127, kRT, kRGBA, kA, 0, kTL }, kDontShare },
171 // Two non-overlapping intervals w/ different MSAA sample counts should not share
172 { { 64, kRT, kRGBA, kA, k2, kTL },{ 64, kRT, kRGBA, kA, k4, kTL}, k2 == k4 },
173 // Two non-overlapping intervals w/ different configs should not share
174 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kBGRA, kA, 0, kTL }, kDontShare },
175 // Two non-overlapping intervals w/ different RT classifications should never share
176 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kNotRT, kRGBA, kA, 0, kTL }, kDontShare },
177 { { 64, kNotRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kTL }, kDontShare },
Robert Phillipsb0e93a22017-08-29 08:26:54 -0400178 // Two non-overlapping intervals w/ different origins should share
179 { { 64, kRT, kRGBA, kA, 0, kTL }, { 64, kRT, kRGBA, kA, 0, kBL }, kShare },
Robert Phillips57aa3672017-07-21 11:38:13 -0400180 };
181
182 for (auto test : gNonOverlappingTests) {
183 sk_sp<GrSurfaceProxy> p1 = make_deferred(resourceProvider, test.fP1);
184 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, test.fP2);
185 if (!p1 || !p2) {
186 continue; // creation can fail (i.e., for msaa4 on iOS)
187 }
Robert Phillipseafd48a2017-11-16 07:52:08 -0500188 non_overlap_test(reporter, resourceProvider,
189 std::move(p1), std::move(p2), test.fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400190 }
191
192 {
193 // Wrapped backend textures should never be reused
194 TestCase t[1] = {
195 { { 64, kNotRT, kRGBA, kE, 0, kTL }, { 64, kNotRT, kRGBA, kE, 0, kTL }, kDontShare }
196 };
197
198 GrBackendObject backEndObj;
199 sk_sp<GrSurfaceProxy> p1 = make_backend(ctxInfo.grContext(), t[0].fP1, &backEndObj);
200 sk_sp<GrSurfaceProxy> p2 = make_deferred(resourceProvider, t[0].fP2);
Robert Phillipseafd48a2017-11-16 07:52:08 -0500201 non_overlap_test(reporter, resourceProvider,
202 std::move(p1), std::move(p2), t[0].fExpectation);
Robert Phillips57aa3672017-07-21 11:38:13 -0400203 cleanup_backend(ctxInfo.grContext(), &backEndObj);
204 }
Robert Phillips5af44de2017-07-18 14:49:38 -0400205}
206
207#endif
Robert Phillipsfa8c0802017-10-04 08:42:28 -0400208#endif