blob: 8c596d915bbae2268612951e4a7be7fb153fd02b [file] [log] [blame]
bsalomon@google.com686bcb82013-04-09 15:04:12 +00001/*
2 * Copyright 2013 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
bsalomona2c23232014-11-25 07:41:12 -08008#include "SkTypes.h"
9
bsalomon@google.com686bcb82013-04-09 15:04:12 +000010#if SK_SUPPORT_GPU
11
bsalomon@google.com686bcb82013-04-09 15:04:12 +000012#include "GrContext.h"
Greg Daniel7ef28f32017-04-20 16:41:55 +000013#include "GrContextPriv.h"
bsalomon091f60c2015-11-10 11:54:56 -080014#include "GrGpu.h"
bsalomon@google.com686bcb82013-04-09 15:04:12 +000015#include "GrRenderTarget.h"
Brian Osman32342f02017-03-04 08:12:46 -050016#include "GrResourceProvider.h"
Greg Daniel7ef28f32017-04-20 16:41:55 +000017#include "GrTest.h"
bsalomon@google.com686bcb82013-04-09 15:04:12 +000018#include "GrTexture.h"
bsalomonafbf2d62014-09-30 12:18:44 -070019#include "GrSurfacePriv.h"
tfarina@chromium.org4ee16bf2014-01-10 22:08:27 +000020#include "Test.h"
bsalomon@google.com686bcb82013-04-09 15:04:12 +000021
bsalomona2c23232014-11-25 07:41:12 -080022// Tests that GrSurface::asTexture(), GrSurface::asRenderTarget(), and static upcasting of texture
23// and render targets to GrSurface all work as expected.
bsalomon758586c2016-04-06 14:02:39 -070024DEF_GPUTEST_FOR_NULLGL_CONTEXT(GrSurface, reporter, ctxInfo) {
bsalomon8b7451a2016-05-11 06:33:06 -070025 GrContext* context = ctxInfo.grContext();
kkinnunen15302832015-12-01 04:35:26 -080026 GrSurfaceDesc desc;
Brian Osman777b5632016-10-14 09:16:21 -040027 desc.fConfig = kRGBA_8888_GrPixelConfig;
kkinnunen15302832015-12-01 04:35:26 -080028 desc.fFlags = kRenderTarget_GrSurfaceFlag;
29 desc.fWidth = 256;
30 desc.fHeight = 256;
31 desc.fSampleCnt = 0;
Robert Phillipse78b7252017-04-06 07:59:41 -040032 sk_sp<GrSurface> texRT1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
bsalomona2c23232014-11-25 07:41:12 -080033
Robert Phillipse78b7252017-04-06 07:59:41 -040034 REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asRenderTarget());
35 REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asTexture());
kkinnunen15302832015-12-01 04:35:26 -080036 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
37 texRT1->asTexture());
38 REPORTER_ASSERT(reporter, texRT1->asRenderTarget() ==
39 static_cast<GrSurface*>(texRT1->asTexture()));
40 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
41 static_cast<GrSurface*>(texRT1->asTexture()));
bsalomona2c23232014-11-25 07:41:12 -080042
kkinnunen15302832015-12-01 04:35:26 -080043 desc.fFlags = kNone_GrSurfaceFlags;
Robert Phillipse78b7252017-04-06 07:59:41 -040044 sk_sp<GrTexture> tex1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
kkinnunen15302832015-12-01 04:35:26 -080045 REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
Robert Phillipse78b7252017-04-06 07:59:41 -040046 REPORTER_ASSERT(reporter, tex1.get() == tex1->asTexture());
47 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(tex1.get()) == tex1->asTexture());
bsalomon@google.com686bcb82013-04-09 15:04:12 +000048
Greg Daniel7ef28f32017-04-20 16:41:55 +000049 GrBackendObject backendTexHandle = context->getGpu()->createTestingOnlyBackendTexture(
Brian Osman777b5632016-10-14 09:16:21 -040050 nullptr, 256, 256, kRGBA_8888_GrPixelConfig);
Greg Daniel7ef28f32017-04-20 16:41:55 +000051 GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
52 256,
53 256,
54 kRGBA_8888_GrPixelConfig,
55 backendTexHandle);
bsalomon091f60c2015-11-10 11:54:56 -080056
Brian Osman32342f02017-03-04 08:12:46 -050057 sk_sp<GrSurface> texRT2 = context->resourceProvider()->wrapBackendTexture(
Greg Daniel7ef28f32017-04-20 16:41:55 +000058 backendTex, kTopLeft_GrSurfaceOrigin, kRenderTarget_GrBackendTextureFlag, 0,
59 kBorrow_GrWrapOwnership);
60
bungeman6bd52842016-10-27 09:30:08 -070061 REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asRenderTarget());
62 REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asTexture());
kkinnunen15302832015-12-01 04:35:26 -080063 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
64 texRT2->asTexture());
65 REPORTER_ASSERT(reporter, texRT2->asRenderTarget() ==
66 static_cast<GrSurface*>(texRT2->asTexture()));
67 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
68 static_cast<GrSurface*>(texRT2->asTexture()));
bsalomon@google.com686bcb82013-04-09 15:04:12 +000069
Greg Daniel7ef28f32017-04-20 16:41:55 +000070 context->getGpu()->deleteTestingOnlyBackendTexture(backendTexHandle);
bsalomon@google.com686bcb82013-04-09 15:04:12 +000071}
72
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040073// This test checks that the isConfigTexturable and isConfigRenderable are
74// consistent with createTexture's result.
75DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
76 GrContext* context = ctxInfo.grContext();
Robert Phillips3b3307f2017-05-24 07:44:02 -040077 GrResourceProvider* resourceProvider = context->resourceProvider();
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040078 const GrCaps* caps = context->caps();
79
80 GrPixelConfig configs[] = {
81 kUnknown_GrPixelConfig,
82 kAlpha_8_GrPixelConfig,
83 kGray_8_GrPixelConfig,
84 kRGB_565_GrPixelConfig,
85 kRGBA_4444_GrPixelConfig,
86 kRGBA_8888_GrPixelConfig,
87 kBGRA_8888_GrPixelConfig,
88 kSRGBA_8888_GrPixelConfig,
89 kSBGRA_8888_GrPixelConfig,
90 kRGBA_8888_sint_GrPixelConfig,
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040091 kRGBA_float_GrPixelConfig,
92 kRG_float_GrPixelConfig,
93 kAlpha_half_GrPixelConfig,
94 kRGBA_half_GrPixelConfig,
95 };
96 SkASSERT(kGrPixelConfigCnt == SK_ARRAY_COUNT(configs));
97
98 GrSurfaceDesc desc;
99 desc.fWidth = 64;
100 desc.fHeight = 64;
101
102 for (GrPixelConfig config : configs) {
103 for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
104 desc.fFlags = kNone_GrSurfaceFlags;
105 desc.fOrigin = origin;
106 desc.fSampleCnt = 0;
107 desc.fConfig = config;
108
Robert Phillips3b3307f2017-05-24 07:44:02 -0400109 sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
110 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig));
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400111
112 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips3b3307f2017-05-24 07:44:02 -0400113 tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400114 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false));
115
116 desc.fSampleCnt = 4;
Robert Phillips3b3307f2017-05-24 07:44:02 -0400117 tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400118 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, true));
119 }
120 }
121}
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400122
Brian Salomond17b4a62017-05-23 16:53:47 -0400123#include "GrDrawingManager.h"
124#include "GrSurfaceProxy.h"
125#include "GrTextureContext.h"
126
127DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info) {
128 static constexpr int kSize = 100;
129 GrSurfaceDesc desc;
130 desc.fWidth = desc.fHeight = kSize;
131 std::unique_ptr<uint32_t[]> data(new uint32_t[kSize * kSize]);
132 GrContext* context = context_info.grContext();
133 for (int c = 0; c <= kLast_GrPixelConfig; ++c) {
134 desc.fConfig = static_cast<GrPixelConfig>(c);
135 if (!context_info.grContext()->caps()->isConfigTexturable(desc.fConfig)) {
136 continue;
137 }
138 desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
139 for (bool rt : {false, true}) {
140 if (rt && !context->caps()->isConfigRenderable(desc.fConfig, false)) {
141 continue;
142 }
143 desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
144 for (bool mipped : {false, true}) {
145 desc.fIsMipMapped = mipped;
146 for (GrSurfaceOrigin origin :
147 {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
148 desc.fOrigin = origin;
149 for (bool approx : {false, true}) {
150 auto resourceProvider = context->resourceProvider();
151 // Try directly creating the texture.
152 // Do this twice in an attempt to hit the cache on the second time through.
153 for (int i = 0; i < 2; ++i) {
154 sk_sp<GrTexture> tex;
155 if (approx) {
156 tex = sk_sp<GrTexture>(
157 resourceProvider->createApproxTexture(desc, 0));
158 } else {
159 tex = resourceProvider->createTexture(desc, SkBudgeted::kYes);
160 }
161 if (!tex) {
162 continue;
163 }
164 auto proxy = GrSurfaceProxy::MakeWrapped(std::move(tex));
165 auto texCtx = context->contextPriv().makeWrappedSurfaceContext(
166 std::move(proxy), nullptr);
167 SkImageInfo info = SkImageInfo::Make(
168 kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
169 memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
170 if (texCtx->readPixels(info, data.get(), 0, 0, 0)) {
171 uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0;
172 for (int i = 0; i < kSize * kSize; ++i) {
173 if (cmp != data.get()[i]) {
174 ERRORF(reporter, "Failed on config %d", desc.fConfig);
175 break;
176 }
177 }
178 }
179 memset(data.get(), 0xBC, kSize * kSize * sizeof(uint32_t));
180 // Here we overwrite the texture so that the second time through we
181 // test against recycling without reclearing.
182 if (0 == i) {
183 texCtx->writePixels(info, data.get(), 0, 0, 0);
184 }
185 }
186 context->purgeAllUnlockedResources();
187
188 // Try creating the texture as a deferred proxy.
189 for (int i = 0; i < 2; ++i) {
190 auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
191 desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
192 SkBudgeted::kYes);
193 if (!surfCtx) {
194 continue;
195 }
196 SkImageInfo info = SkImageInfo::Make(
197 kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
198 memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
199 if (surfCtx->readPixels(info, data.get(), 0, 0, 0)) {
200 uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0;
201 for (int i = 0; i < kSize * kSize; ++i) {
202 if (cmp != data.get()[i]) {
203 ERRORF(reporter, "Failed on config %d", desc.fConfig);
204 break;
205 }
206 }
207 }
208 // Here we overwrite the texture so that the second time through we
209 // test against recycling without reclearing.
210 if (0 == i) {
211 surfCtx->writePixels(info, data.get(), 0, 0, 0);
212 }
213 }
214 context->purgeAllUnlockedResources();
215 }
216 }
217 }
218 }
219 }
220}
bsalomon@google.com686bcb82013-04-09 15:04:12 +0000221#endif