blob: 8cb6f7e403bf911056d5bad7713f5f28c1d99bbc [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"
Robert Phillips2890fbf2017-07-26 15:48:41 -040015#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"
Brian Osman48c99192017-06-02 08:45:06 -040019#include "SkMipMap.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;
kkinnunen15302832015-12-01 04:35:26 -080027 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips16d8ec62017-07-27 16:16:25 -040028 desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
kkinnunen15302832015-12-01 04:35:26 -080029 desc.fWidth = 256;
30 desc.fHeight = 256;
Robert Phillips16d8ec62017-07-27 16:16:25 -040031 desc.fConfig = kRGBA_8888_GrPixelConfig;
kkinnunen15302832015-12-01 04:35:26 -080032 desc.fSampleCnt = 0;
Robert Phillipse78b7252017-04-06 07:59:41 -040033 sk_sp<GrSurface> texRT1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
bsalomona2c23232014-11-25 07:41:12 -080034
Robert Phillipse78b7252017-04-06 07:59:41 -040035 REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asRenderTarget());
36 REPORTER_ASSERT(reporter, texRT1.get() == texRT1->asTexture());
kkinnunen15302832015-12-01 04:35:26 -080037 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
38 texRT1->asTexture());
39 REPORTER_ASSERT(reporter, texRT1->asRenderTarget() ==
40 static_cast<GrSurface*>(texRT1->asTexture()));
41 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT1->asRenderTarget()) ==
42 static_cast<GrSurface*>(texRT1->asTexture()));
bsalomona2c23232014-11-25 07:41:12 -080043
kkinnunen15302832015-12-01 04:35:26 -080044 desc.fFlags = kNone_GrSurfaceFlags;
Robert Phillips16d8ec62017-07-27 16:16:25 -040045 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
Robert Phillipse78b7252017-04-06 07:59:41 -040046 sk_sp<GrTexture> tex1 = context->resourceProvider()->createTexture(desc, SkBudgeted::kNo);
kkinnunen15302832015-12-01 04:35:26 -080047 REPORTER_ASSERT(reporter, nullptr == tex1->asRenderTarget());
Robert Phillipse78b7252017-04-06 07:59:41 -040048 REPORTER_ASSERT(reporter, tex1.get() == tex1->asTexture());
49 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(tex1.get()) == tex1->asTexture());
bsalomon@google.com686bcb82013-04-09 15:04:12 +000050
Greg Daniel7ef28f32017-04-20 16:41:55 +000051 GrBackendObject backendTexHandle = context->getGpu()->createTestingOnlyBackendTexture(
Brian Osman777b5632016-10-14 09:16:21 -040052 nullptr, 256, 256, kRGBA_8888_GrPixelConfig);
Greg Daniel7ef28f32017-04-20 16:41:55 +000053 GrBackendTexture backendTex = GrTest::CreateBackendTexture(context->contextPriv().getBackend(),
54 256,
55 256,
56 kRGBA_8888_GrPixelConfig,
Greg Daniel177e6952017-10-12 12:27:11 -040057 GrMipMapped::kNo,
Greg Daniel7ef28f32017-04-20 16:41:55 +000058 backendTexHandle);
bsalomon091f60c2015-11-10 11:54:56 -080059
Brian Salomond17f6582017-07-19 18:28:58 -040060 sk_sp<GrSurface> texRT2 = context->resourceProvider()->wrapRenderableBackendTexture(
Robert Phillipsb0e93a22017-08-29 08:26:54 -040061 backendTex, 0, kBorrow_GrWrapOwnership);
Greg Daniel7ef28f32017-04-20 16:41:55 +000062
bungeman6bd52842016-10-27 09:30:08 -070063 REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asRenderTarget());
64 REPORTER_ASSERT(reporter, texRT2.get() == texRT2->asTexture());
kkinnunen15302832015-12-01 04:35:26 -080065 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
66 texRT2->asTexture());
67 REPORTER_ASSERT(reporter, texRT2->asRenderTarget() ==
68 static_cast<GrSurface*>(texRT2->asTexture()));
69 REPORTER_ASSERT(reporter, static_cast<GrSurface*>(texRT2->asRenderTarget()) ==
70 static_cast<GrSurface*>(texRT2->asTexture()));
bsalomon@google.com686bcb82013-04-09 15:04:12 +000071
Greg Daniel7ef28f32017-04-20 16:41:55 +000072 context->getGpu()->deleteTestingOnlyBackendTexture(backendTexHandle);
bsalomon@google.com686bcb82013-04-09 15:04:12 +000073}
74
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040075// This test checks that the isConfigTexturable and isConfigRenderable are
76// consistent with createTexture's result.
77DEF_GPUTEST_FOR_ALL_CONTEXTS(GrSurfaceRenderability, reporter, ctxInfo) {
78 GrContext* context = ctxInfo.grContext();
Robert Phillips3b3307f2017-05-24 07:44:02 -040079 GrResourceProvider* resourceProvider = context->resourceProvider();
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040080 const GrCaps* caps = context->caps();
81
82 GrPixelConfig configs[] = {
83 kUnknown_GrPixelConfig,
84 kAlpha_8_GrPixelConfig,
Greg Danielef59d872017-11-17 16:47:21 -050085 kAlpha_8_as_Alpha_GrPixelConfig,
86 kAlpha_8_as_Red_GrPixelConfig,
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040087 kGray_8_GrPixelConfig,
Greg Daniel7af060a2017-12-05 16:27:11 -050088 kGray_8_as_Lum_GrPixelConfig,
89 kGray_8_as_Red_GrPixelConfig,
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040090 kRGB_565_GrPixelConfig,
91 kRGBA_4444_GrPixelConfig,
92 kRGBA_8888_GrPixelConfig,
93 kBGRA_8888_GrPixelConfig,
94 kSRGBA_8888_GrPixelConfig,
95 kSBGRA_8888_GrPixelConfig,
96 kRGBA_8888_sint_GrPixelConfig,
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -040097 kRGBA_float_GrPixelConfig,
98 kRG_float_GrPixelConfig,
99 kAlpha_half_GrPixelConfig,
Greg Danielef59d872017-11-17 16:47:21 -0500100 kAlpha_half_as_Red_GrPixelConfig,
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400101 kRGBA_half_GrPixelConfig,
102 };
103 SkASSERT(kGrPixelConfigCnt == SK_ARRAY_COUNT(configs));
104
105 GrSurfaceDesc desc;
106 desc.fWidth = 64;
107 desc.fHeight = 64;
108
Brian Osman48c99192017-06-02 08:45:06 -0400109 // Enough space for the first mip of our largest pixel config
110 const size_t pixelBufferSize = desc.fWidth * desc.fHeight *
111 GrBytesPerPixel(kRGBA_float_GrPixelConfig);
112 std::unique_ptr<char[]> pixelData(new char[pixelBufferSize]);
113 memset(pixelData.get(), 0, pixelBufferSize);
114
115 // We re-use the same mip level objects (with updated pointers and rowBytes) for each config
116 const int levelCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
117 std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[levelCount]);
118
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400119 for (GrPixelConfig config : configs) {
120 for (GrSurfaceOrigin origin : { kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin }) {
121 desc.fFlags = kNone_GrSurfaceFlags;
122 desc.fOrigin = origin;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400123 desc.fConfig = config;
Robert Phillips16d8ec62017-07-27 16:16:25 -0400124 desc.fSampleCnt = 0;
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400125
Robert Phillips3b3307f2017-05-24 07:44:02 -0400126 sk_sp<GrSurface> tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
127 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigTexturable(desc.fConfig));
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400128
Brian Osman48c99192017-06-02 08:45:06 -0400129 size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
130 for (int i = 0; i < levelCount; ++i) {
131 texels[i].fPixels = pixelData.get();
132 texels[i].fRowBytes = rowBytes >> i;
133 }
Robert Phillips8e8c7552017-07-10 12:06:05 -0400134 sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(resourceProvider,
135 desc, SkBudgeted::kNo,
136 texels.get(),
137 levelCount);
Brian Osman48c99192017-06-02 08:45:06 -0400138 REPORTER_ASSERT(reporter, SkToBool(proxy.get()) ==
139 (caps->isConfigTexturable(desc.fConfig) &&
140 caps->mipMapSupport() &&
141 !GrPixelConfigIsSint(desc.fConfig)));
142
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400143 desc.fFlags = kRenderTarget_GrSurfaceFlag;
Robert Phillips3b3307f2017-05-24 07:44:02 -0400144 tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400145 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, false));
146
147 desc.fSampleCnt = 4;
Robert Phillips3b3307f2017-05-24 07:44:02 -0400148 tex = resourceProvider->createTexture(desc, SkBudgeted::kNo);
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400149 REPORTER_ASSERT(reporter, SkToBool(tex.get()) == caps->isConfigRenderable(config, true));
150 }
151 }
152}
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -0400153
Brian Salomond17b4a62017-05-23 16:53:47 -0400154#include "GrDrawingManager.h"
155#include "GrSurfaceProxy.h"
156#include "GrTextureContext.h"
157
158DEF_GPUTEST_FOR_RENDERING_CONTEXTS(InitialTextureClear, reporter, context_info) {
159 static constexpr int kSize = 100;
160 GrSurfaceDesc desc;
161 desc.fWidth = desc.fHeight = kSize;
162 std::unique_ptr<uint32_t[]> data(new uint32_t[kSize * kSize]);
163 GrContext* context = context_info.grContext();
164 for (int c = 0; c <= kLast_GrPixelConfig; ++c) {
165 desc.fConfig = static_cast<GrPixelConfig>(c);
166 if (!context_info.grContext()->caps()->isConfigTexturable(desc.fConfig)) {
167 continue;
168 }
169 desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
170 for (bool rt : {false, true}) {
171 if (rt && !context->caps()->isConfigRenderable(desc.fConfig, false)) {
172 continue;
173 }
174 desc.fFlags |= rt ? kRenderTarget_GrSurfaceFlag : kNone_GrSurfaceFlags;
Greg Daniel90f28ec2017-09-25 12:26:58 -0400175 for (GrSurfaceOrigin origin :
176 {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
177 desc.fOrigin = origin;
178 for (bool approx : {false, true}) {
179 auto resourceProvider = context->resourceProvider();
180 // Try directly creating the texture.
181 // Do this twice in an attempt to hit the cache on the second time through.
182 for (int i = 0; i < 2; ++i) {
183 sk_sp<GrTexture> tex;
184 if (approx) {
185 tex = sk_sp<GrTexture>(
186 resourceProvider->createApproxTexture(desc, 0));
187 } else {
188 tex = resourceProvider->createTexture(desc, SkBudgeted::kYes);
189 }
190 if (!tex) {
191 continue;
192 }
193 auto proxy = GrSurfaceProxy::MakeWrapped(std::move(tex), desc.fOrigin);
194 auto texCtx = context->contextPriv().makeWrappedSurfaceContext(
195 std::move(proxy), nullptr);
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 (texCtx->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;
Brian Salomond17b4a62017-05-23 16:53:47 -0400205 }
206 }
Brian Salomond17b4a62017-05-23 16:53:47 -0400207 }
Greg Daniel90f28ec2017-09-25 12:26:58 -0400208 memset(data.get(), 0xBC, kSize * kSize * sizeof(uint32_t));
209 // Here we overwrite the texture so that the second time through we
210 // test against recycling without reclearing.
211 if (0 == i) {
212 texCtx->writePixels(info, data.get(), 0, 0, 0);
Greg Daniel52cb5fe2017-09-05 15:45:15 -0400213 }
Greg Daniel52cb5fe2017-09-05 15:45:15 -0400214 }
Greg Daniel90f28ec2017-09-25 12:26:58 -0400215 context->purgeAllUnlockedResources();
216
217 // Try creating the texture as a deferred proxy.
218 for (int i = 0; i < 2; ++i) {
219 auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
Greg Daniel65c7f662017-10-30 13:39:09 -0400220 desc, GrMipMapped::kNo,
221 approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
Greg Daniel90f28ec2017-09-25 12:26:58 -0400222 SkBudgeted::kYes);
223 if (!surfCtx) {
224 continue;
225 }
226 SkImageInfo info = SkImageInfo::Make(
227 kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
228 memset(data.get(), 0xAB, kSize * kSize * sizeof(uint32_t));
229 if (surfCtx->readPixels(info, data.get(), 0, 0, 0)) {
230 uint32_t cmp = GrPixelConfigIsOpaque(desc.fConfig) ? 0xFF000000 : 0;
231 for (int i = 0; i < kSize * kSize; ++i) {
232 if (cmp != data.get()[i]) {
233 ERRORF(reporter, "Failed on config %d", desc.fConfig);
234 break;
235 }
236 }
237 }
238 // Here we overwrite the texture so that the second time through we
239 // test against recycling without reclearing.
240 if (0 == i) {
241 surfCtx->writePixels(info, data.get(), 0, 0, 0);
242 }
243 }
244 context->purgeAllUnlockedResources();
Brian Salomond17b4a62017-05-23 16:53:47 -0400245 }
246 }
247 }
248 }
249}
bsalomon@google.com686bcb82013-04-09 15:04:12 +0000250#endif