blob: 1d99d00c45e11accca5b5c43b3c4adec6003a9e9 [file] [log] [blame]
Robert Phillips7ffbcf92017-12-04 12:52:46 -05001/*
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 "SkTypes.h"
9
10#if SK_SUPPORT_GPU
11
12#include "SkCanvas.h"
13#include "SkDeferredDisplayListRecorder.h"
14#include "SkGpuDevice.h"
15#include "SkSurface.h"
16#include "SkSurface_Gpu.h"
17#include "SkSurfaceCharacterization.h"
18#include "SkSurfaceProps.h"
19#include "Test.h"
20
21class SurfaceParameters {
22public:
23 static const int kNumParams = 8;
24 static const int kSampleCount = 5;
25
26 SurfaceParameters()
27 : fWidth(64)
28 , fHeight(64)
29 , fOrigin(kTopLeft_GrSurfaceOrigin)
30 , fColorType(kRGBA_8888_SkColorType)
31 , fColorSpace(SkColorSpace::MakeSRGB())
32 , fSampleCount(0)
33 , fSurfaceProps(0x0, kUnknown_SkPixelGeometry) {
34 }
35
36 int sampleCount() const { return fSampleCount; }
37
38 // Modify the SurfaceParameters in just one way
39 void modify(int i) {
40 switch (i) {
41 case 0:
42 fWidth = 63;
43 break;
44 case 1:
45 fHeight = 63;
46 break;
47 case 2:
48 fOrigin = kBottomLeft_GrSurfaceOrigin;
49 break;
50 case 3:
51 fColorType = kRGBA_F16_SkColorType;
52 break;
53 case 4:
54 fColorSpace = SkColorSpace::MakeSRGBLinear();
55 break;
56 case kSampleCount:
57 fSampleCount = 4;
58 break;
59 case 6:
60 fSurfaceProps = SkSurfaceProps(0x0, kRGB_H_SkPixelGeometry);
61 break;
62 case 7:
63 fSurfaceProps = SkSurfaceProps(SkSurfaceProps::kUseDeviceIndependentFonts_Flag,
64 kUnknown_SkPixelGeometry);
65 break;
66 }
67 }
68
69 // Create the surface with the current set of parameters
70 sk_sp<SkSurface> make(GrContext* context) const {
71 // Note that Ganesh doesn't make use of the SkImageInfo's alphaType
72 SkImageInfo ii = SkImageInfo::Make(fWidth, fHeight, fColorType,
73 kPremul_SkAlphaType, fColorSpace);
74
75 return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, ii, fSampleCount,
76 fOrigin, &fSurfaceProps);
77 }
78
79private:
80 int fWidth;
81 int fHeight;
82 GrSurfaceOrigin fOrigin;
83 SkColorType fColorType;
84 sk_sp<SkColorSpace> fColorSpace;
85 int fSampleCount;
86 SkSurfaceProps fSurfaceProps;
87};
88
89// This tests SkSurfaceCharacterization/SkSurface compatibility
90DEF_GPUTEST_FOR_ALL_CONTEXTS(SkSurfaceCharacterization, reporter, ctxInfo) {
91 GrContext* context = ctxInfo.grContext();
92
93 std::unique_ptr<SkDeferredDisplayList> ddl;
94
95 // First, create a DDL using the stock SkSurface parameters
96 {
97 SurfaceParameters params;
98
99 sk_sp<SkSurface> s = params.make(context);
100 if (!s) {
101 return;
102 }
103
104 SkSurfaceCharacterization c;
105 SkAssertResult(s->characterize(&c));
106
107 SkDeferredDisplayListRecorder r(c);
108 SkCanvas* canvas = r.getCanvas();
Robert Phillipse42edcc2017-12-13 11:50:22 -0500109 if (!canvas) {
110 return;
111 }
112
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500113 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
114 ddl = r.detach();
115
116 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
117 }
118
119 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
120 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
121 SurfaceParameters params;
122 params.modify(i);
123
124 sk_sp<SkSurface> s = params.make(context);
125 if (!s) {
126 continue;
127 }
128
129 if (SurfaceParameters::kSampleCount == i) {
130 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
131
132 int supportedSampleCount = context->caps()->getSampleCount(
133 params.sampleCount(),
134 gpuSurf->getDevice()->accessRenderTargetContext()->asRenderTargetProxy()->config());
135 if (0 == supportedSampleCount) {
136 // If changing the sample count won't result in a different
137 // surface characterization, skip this step
138 continue;
139 }
140 }
141
142 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
143 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500144
145 // Next test the compatibility of resource cache parameters
146 {
147 const SurfaceParameters params;
148 sk_sp<SkSurface> s = params.make(context);
149
150 int maxResourceCount;
151 size_t maxResourceBytes;
152 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
153
154 context->setResourceCacheLimits(maxResourceCount/2, maxResourceBytes);
155 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
156
157 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
158 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
159
160 // resource limits >= those at characterization time are accepted
161 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
162 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
163
164 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
165 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
166
167 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
168 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
169 }
170
171 // Make sure non-GPU-backed surfaces fail characterization
172 {
173 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
174
175 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
176 SkSurfaceCharacterization c;
177 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
178 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500179}
180
181#endif