blob: fc9fbfed2536b65028fcca65d2043fcbb6edf475 [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();
109 canvas->drawRect(SkRect::MakeXYWH(10, 10, 10, 10), SkPaint());
110 ddl = r.detach();
111
112 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
113 }
114
115 // Then, alter each parameter in turn and check that the DDL & surface are incompatible
116 for (int i = 0; i < SurfaceParameters::kNumParams; ++i) {
117 SurfaceParameters params;
118 params.modify(i);
119
120 sk_sp<SkSurface> s = params.make(context);
121 if (!s) {
122 continue;
123 }
124
125 if (SurfaceParameters::kSampleCount == i) {
126 SkSurface_Gpu* gpuSurf = static_cast<SkSurface_Gpu*>(s.get());
127
128 int supportedSampleCount = context->caps()->getSampleCount(
129 params.sampleCount(),
130 gpuSurf->getDevice()->accessRenderTargetContext()->asRenderTargetProxy()->config());
131 if (0 == supportedSampleCount) {
132 // If changing the sample count won't result in a different
133 // surface characterization, skip this step
134 continue;
135 }
136 }
137
138 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
139 }
Robert Phillips8d1e67e2017-12-04 13:48:14 -0500140
141 // Next test the compatibility of resource cache parameters
142 {
143 const SurfaceParameters params;
144 sk_sp<SkSurface> s = params.make(context);
145
146 int maxResourceCount;
147 size_t maxResourceBytes;
148 context->getResourceCacheLimits(&maxResourceCount, &maxResourceBytes);
149
150 context->setResourceCacheLimits(maxResourceCount/2, maxResourceBytes);
151 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
152
153 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes/2);
154 REPORTER_ASSERT(reporter, !s->draw(ddl.get()));
155
156 // resource limits >= those at characterization time are accepted
157 context->setResourceCacheLimits(2*maxResourceCount, maxResourceBytes);
158 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
159
160 context->setResourceCacheLimits(maxResourceCount, 2*maxResourceBytes);
161 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
162
163 context->setResourceCacheLimits(maxResourceCount, maxResourceBytes);
164 REPORTER_ASSERT(reporter, s->draw(ddl.get()));
165 }
166
167 // Make sure non-GPU-backed surfaces fail characterization
168 {
169 SkImageInfo ii = SkImageInfo::MakeN32(64, 64, kOpaque_SkAlphaType);
170
171 sk_sp<SkSurface> rasterSurface = SkSurface::MakeRaster(ii);
172 SkSurfaceCharacterization c;
173 REPORTER_ASSERT(reporter, !rasterSurface->characterize(&c));
174 }
Robert Phillips7ffbcf92017-12-04 12:52:46 -0500175}
176
177#endif