ProxyTest.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /*
  2. * Copyright 2016 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. // This is a GPU-backend specific test.
  8. #include "tests/Test.h"
  9. #include "include/gpu/GrBackendSurface.h"
  10. #include "include/gpu/GrTexture.h"
  11. #include "src/gpu/GrContextPriv.h"
  12. #include "src/gpu/GrProxyProvider.h"
  13. #include "src/gpu/GrRenderTargetPriv.h"
  14. #include "src/gpu/GrRenderTargetProxy.h"
  15. #include "src/gpu/GrResourceProvider.h"
  16. #include "src/gpu/GrSurfacePriv.h"
  17. #include "src/gpu/GrSurfaceProxyPriv.h"
  18. #include "src/gpu/GrTextureProxy.h"
  19. #include "src/gpu/SkGr.h"
  20. #include "src/gpu/gl/GrGLDefines.h"
  21. // Check that the surface proxy's member vars are set as expected
  22. static void check_surface(skiatest::Reporter* reporter,
  23. GrSurfaceProxy* proxy,
  24. GrSurfaceOrigin origin,
  25. int width, int height,
  26. GrPixelConfig config,
  27. SkBudgeted budgeted) {
  28. REPORTER_ASSERT(reporter, proxy->origin() == origin);
  29. REPORTER_ASSERT(reporter, proxy->width() == width);
  30. REPORTER_ASSERT(reporter, proxy->height() == height);
  31. #ifdef SK_DEBUG
  32. REPORTER_ASSERT(reporter, GrCaps::AreConfigsCompatible(config, proxy->config()));
  33. #endif
  34. REPORTER_ASSERT(reporter, !proxy->uniqueID().isInvalid());
  35. REPORTER_ASSERT(reporter, proxy->isBudgeted() == budgeted);
  36. }
  37. static void check_rendertarget(skiatest::Reporter* reporter,
  38. const GrCaps& caps,
  39. GrResourceProvider* provider,
  40. GrRenderTargetProxy* rtProxy,
  41. int numSamples,
  42. SkBackingFit fit,
  43. int expectedMaxWindowRects) {
  44. REPORTER_ASSERT(reporter, rtProxy->maxWindowRectangles(caps) == expectedMaxWindowRects);
  45. REPORTER_ASSERT(reporter, rtProxy->numSamples() == numSamples);
  46. GrSurfaceProxy::UniqueID idBefore = rtProxy->uniqueID();
  47. bool preinstantiated = rtProxy->isInstantiated();
  48. REPORTER_ASSERT(reporter, rtProxy->instantiate(provider));
  49. GrRenderTarget* rt = rtProxy->peekRenderTarget();
  50. REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore);
  51. // Deferred resources should always have a different ID from their instantiated rendertarget
  52. if (preinstantiated) {
  53. REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() == rt->uniqueID().asUInt());
  54. } else {
  55. REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
  56. }
  57. if (SkBackingFit::kExact == fit) {
  58. REPORTER_ASSERT(reporter, rt->width() == rtProxy->width());
  59. REPORTER_ASSERT(reporter, rt->height() == rtProxy->height());
  60. } else {
  61. REPORTER_ASSERT(reporter, rt->width() >= rtProxy->width());
  62. REPORTER_ASSERT(reporter, rt->height() >= rtProxy->height());
  63. }
  64. REPORTER_ASSERT(reporter, rt->config() == rtProxy->config());
  65. REPORTER_ASSERT(reporter, rt->numSamples() == rtProxy->numSamples());
  66. REPORTER_ASSERT(reporter, rt->surfacePriv().flags() == rtProxy->testingOnly_getFlags());
  67. }
  68. static void check_texture(skiatest::Reporter* reporter,
  69. GrResourceProvider* provider,
  70. GrTextureProxy* texProxy,
  71. SkBackingFit fit) {
  72. GrSurfaceProxy::UniqueID idBefore = texProxy->uniqueID();
  73. bool preinstantiated = texProxy->isInstantiated();
  74. REPORTER_ASSERT(reporter, texProxy->instantiate(provider));
  75. GrTexture* tex = texProxy->peekTexture();
  76. REPORTER_ASSERT(reporter, texProxy->uniqueID() == idBefore);
  77. // Deferred resources should always have a different ID from their instantiated texture
  78. if (preinstantiated) {
  79. REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() == tex->uniqueID().asUInt());
  80. } else {
  81. REPORTER_ASSERT(reporter, texProxy->uniqueID().asUInt() != tex->uniqueID().asUInt());
  82. }
  83. if (SkBackingFit::kExact == fit) {
  84. REPORTER_ASSERT(reporter, tex->width() == texProxy->width());
  85. REPORTER_ASSERT(reporter, tex->height() == texProxy->height());
  86. } else {
  87. REPORTER_ASSERT(reporter, tex->width() >= texProxy->width());
  88. REPORTER_ASSERT(reporter, tex->height() >= texProxy->height());
  89. }
  90. REPORTER_ASSERT(reporter, tex->config() == texProxy->config());
  91. }
  92. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(DeferredProxyTest, reporter, ctxInfo) {
  93. GrProxyProvider* proxyProvider = ctxInfo.grContext()->priv().proxyProvider();
  94. GrResourceProvider* resourceProvider = ctxInfo.grContext()->priv().resourceProvider();
  95. const GrCaps& caps = *ctxInfo.grContext()->priv().caps();
  96. int attempt = 0; // useful for debugging
  97. for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
  98. for (auto widthHeight : { 100, 128, 1048576 }) {
  99. for (auto ct : { GrColorType::kAlpha_8, GrColorType::kBGR_565,
  100. GrColorType::kRGBA_8888, GrColorType::kRGBA_1010102 } ) {
  101. for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
  102. for (auto budgeted : { SkBudgeted::kYes, SkBudgeted::kNo }) {
  103. for (auto numSamples : {1, 4, 16, 128}) {
  104. auto config = GrColorTypeToPixelConfig(ct);
  105. SkASSERT(kUnknown_GrPixelConfig != config);
  106. GrSurfaceDesc desc;
  107. desc.fWidth = widthHeight;
  108. desc.fHeight = widthHeight;
  109. desc.fConfig = config;
  110. const GrBackendFormat format = caps.getBackendFormatFromColorType(ct);
  111. if (!format.isValid()) {
  112. continue;
  113. }
  114. // Renderable
  115. {
  116. sk_sp<GrTexture> tex;
  117. if (SkBackingFit::kApprox == fit) {
  118. tex = resourceProvider->createApproxTexture(
  119. desc, GrRenderable::kYes, numSamples, GrProtected::kNo,
  120. GrResourceProvider::Flags::kNoPendingIO);
  121. } else {
  122. tex = resourceProvider->createTexture(
  123. desc, GrRenderable::kYes, numSamples, budgeted,
  124. GrProtected::kNo,
  125. GrResourceProvider::Flags::kNoPendingIO);
  126. }
  127. sk_sp<GrTextureProxy> proxy = proxyProvider->createProxy(
  128. format, desc, GrRenderable::kYes, numSamples, origin, fit,
  129. budgeted, GrProtected::kNo);
  130. REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
  131. if (proxy) {
  132. REPORTER_ASSERT(reporter, proxy->asRenderTargetProxy());
  133. // This forces the proxy to compute and cache its
  134. // pre-instantiation size guess. Later, when it is actually
  135. // instantiated, it checks that the instantiated size is <= to
  136. // the pre-computation. If the proxy never computed its
  137. // pre-instantiation size then the check is skipped.
  138. proxy->gpuMemorySize();
  139. check_surface(reporter, proxy.get(), origin,
  140. widthHeight, widthHeight, config, budgeted);
  141. int supportedSamples =
  142. caps.getRenderTargetSampleCount(numSamples, config);
  143. check_rendertarget(reporter, caps, resourceProvider,
  144. proxy->asRenderTargetProxy(),
  145. supportedSamples,
  146. fit, caps.maxWindowRectangles());
  147. }
  148. }
  149. // Not renderable
  150. {
  151. sk_sp<GrTexture> tex;
  152. if (SkBackingFit::kApprox == fit) {
  153. tex = resourceProvider->createApproxTexture(
  154. desc, GrRenderable::kNo, numSamples, GrProtected::kNo,
  155. GrResourceProvider::Flags::kNoPendingIO);
  156. } else {
  157. tex = resourceProvider->createTexture(
  158. desc, GrRenderable::kNo, numSamples, budgeted,
  159. GrProtected::kNo,
  160. GrResourceProvider::Flags::kNoPendingIO);
  161. }
  162. sk_sp<GrTextureProxy> proxy(proxyProvider->createProxy(
  163. format, desc, GrRenderable::kNo, numSamples, origin, fit,
  164. budgeted, GrProtected::kNo));
  165. REPORTER_ASSERT(reporter, SkToBool(tex) == SkToBool(proxy));
  166. if (proxy) {
  167. // This forces the proxy to compute and cache its
  168. // pre-instantiation size guess. Later, when it is actually
  169. // instantiated, it checks that the instantiated size is <= to
  170. // the pre-computation. If the proxy never computed its
  171. // pre-instantiation size then the check is skipped.
  172. proxy->gpuMemorySize();
  173. check_surface(reporter, proxy.get(), origin,
  174. widthHeight, widthHeight, config, budgeted);
  175. check_texture(reporter, resourceProvider,
  176. proxy->asTextureProxy(), fit);
  177. }
  178. }
  179. attempt++;
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. }
  187. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(WrappedProxyTest, reporter, ctxInfo) {
  188. GrProxyProvider* proxyProvider = ctxInfo.grContext()->priv().proxyProvider();
  189. GrContext* context = ctxInfo.grContext();
  190. GrResourceProvider* resourceProvider = context->priv().resourceProvider();
  191. GrGpu* gpu = context->priv().getGpu();
  192. const GrCaps& caps = *context->priv().caps();
  193. static const int kWidthHeight = 100;
  194. for (auto origin : { kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin }) {
  195. for (auto colorType : { kAlpha_8_SkColorType, kRGBA_8888_SkColorType,
  196. kRGBA_1010102_SkColorType }) {
  197. GrColorType grColorType = SkColorTypeToGrColorType(colorType);
  198. GrPixelConfig config = GrColorTypeToPixelConfig(grColorType);
  199. SkASSERT(kUnknown_GrPixelConfig != config);
  200. // External on-screen render target.
  201. // Tests wrapBackendRenderTarget with a GrBackendRenderTarget
  202. // Our test-only function that creates a backend render target doesn't currently support
  203. // sample counts :(.
  204. if (ctxInfo.grContext()->colorTypeSupportedAsSurface(colorType)) {
  205. GrBackendRenderTarget backendRT = gpu->createTestingOnlyBackendRenderTarget(
  206. kWidthHeight, kWidthHeight, grColorType);
  207. sk_sp<GrSurfaceProxy> sProxy(
  208. proxyProvider->wrapBackendRenderTarget(backendRT, grColorType,
  209. origin, nullptr, nullptr));
  210. check_surface(reporter, sProxy.get(), origin, kWidthHeight, kWidthHeight,
  211. config, SkBudgeted::kNo);
  212. static constexpr int kExpectedNumSamples = 1;
  213. check_rendertarget(reporter, caps, resourceProvider, sProxy->asRenderTargetProxy(),
  214. kExpectedNumSamples, SkBackingFit::kExact,
  215. caps.maxWindowRectangles());
  216. gpu->deleteTestingOnlyBackendRenderTarget(backendRT);
  217. }
  218. for (auto numSamples : {1, 4}) {
  219. int supportedNumSamples = caps.getRenderTargetSampleCount(numSamples, config);
  220. if (!supportedNumSamples) {
  221. continue;
  222. }
  223. // Test wrapping FBO 0 (with made up properties). This tests sample count and the
  224. // special case where FBO 0 doesn't support window rectangles.
  225. if (GrBackendApi::kOpenGL == ctxInfo.backend()) {
  226. GrBackendFormat beFormat = caps.getBackendFormatFromColorType(grColorType);
  227. GrGLFramebufferInfo fboInfo;
  228. fboInfo.fFBOID = 0;
  229. SkASSERT(beFormat.getGLFormat());
  230. fboInfo.fFormat = *beFormat.getGLFormat();
  231. static constexpr int kStencilBits = 8;
  232. GrBackendRenderTarget backendRT(kWidthHeight, kWidthHeight, numSamples,
  233. kStencilBits, fboInfo);
  234. backendRT.setPixelConfig(config);
  235. sk_sp<GrSurfaceProxy> sProxy(
  236. proxyProvider->wrapBackendRenderTarget(backendRT, grColorType,
  237. origin, nullptr, nullptr));
  238. check_surface(reporter, sProxy.get(), origin,
  239. kWidthHeight, kWidthHeight,
  240. config, SkBudgeted::kNo);
  241. check_rendertarget(reporter, caps, resourceProvider,
  242. sProxy->asRenderTargetProxy(),
  243. supportedNumSamples, SkBackingFit::kExact, 0);
  244. }
  245. // Tests wrapBackendRenderTarget with a GrBackendTexture
  246. {
  247. GrBackendTexture backendTex =
  248. context->createBackendTexture(kWidthHeight, kWidthHeight,
  249. colorType,
  250. SkColors::kTransparent,
  251. GrMipMapped::kNo,
  252. GrRenderable::kYes,
  253. GrProtected::kNo);
  254. sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTextureAsRenderTarget(
  255. backendTex, grColorType, origin, supportedNumSamples);
  256. if (!sProxy) {
  257. context->deleteBackendTexture(backendTex);
  258. continue; // This can fail on Mesa
  259. }
  260. check_surface(reporter, sProxy.get(), origin,
  261. kWidthHeight, kWidthHeight,
  262. config, SkBudgeted::kNo);
  263. check_rendertarget(reporter, caps, resourceProvider,
  264. sProxy->asRenderTargetProxy(),
  265. supportedNumSamples, SkBackingFit::kExact,
  266. caps.maxWindowRectangles());
  267. context->deleteBackendTexture(backendTex);
  268. }
  269. // Tests wrapBackendTexture that is only renderable
  270. {
  271. GrBackendTexture backendTex =
  272. context->createBackendTexture(kWidthHeight, kWidthHeight,
  273. colorType,
  274. SkColors::kTransparent,
  275. GrMipMapped::kNo,
  276. GrRenderable::kYes,
  277. GrProtected::kNo);
  278. sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapRenderableBackendTexture(
  279. backendTex, origin, supportedNumSamples,
  280. grColorType, kBorrow_GrWrapOwnership,
  281. GrWrapCacheable::kNo, nullptr, nullptr);
  282. if (!sProxy) {
  283. context->deleteBackendTexture(backendTex);
  284. continue; // This can fail on Mesa
  285. }
  286. check_surface(reporter, sProxy.get(), origin,
  287. kWidthHeight, kWidthHeight,
  288. config, SkBudgeted::kNo);
  289. check_rendertarget(reporter, caps, resourceProvider,
  290. sProxy->asRenderTargetProxy(),
  291. supportedNumSamples, SkBackingFit::kExact,
  292. caps.maxWindowRectangles());
  293. context->deleteBackendTexture(backendTex);
  294. }
  295. // Tests wrapBackendTexture that is only textureable
  296. {
  297. // Internal offscreen texture
  298. GrBackendTexture backendTex =
  299. context->createBackendTexture(kWidthHeight, kWidthHeight,
  300. colorType,
  301. SkColors::kTransparent,
  302. GrMipMapped::kNo,
  303. GrRenderable::kNo,
  304. GrProtected::kNo);
  305. sk_sp<GrSurfaceProxy> sProxy = proxyProvider->wrapBackendTexture(
  306. backendTex, grColorType, origin, kBorrow_GrWrapOwnership,
  307. GrWrapCacheable::kNo, kRead_GrIOType);
  308. if (!sProxy) {
  309. context->deleteBackendTexture(backendTex);
  310. continue;
  311. }
  312. check_surface(reporter, sProxy.get(), origin,
  313. kWidthHeight, kWidthHeight,
  314. config, SkBudgeted::kNo);
  315. check_texture(reporter, resourceProvider, sProxy->asTextureProxy(),
  316. SkBackingFit::kExact);
  317. context->deleteBackendTexture(backendTex);
  318. }
  319. }
  320. }
  321. }
  322. }
  323. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ZeroSizedProxyTest, reporter, ctxInfo) {
  324. GrProxyProvider* provider = ctxInfo.grContext()->priv().proxyProvider();
  325. for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
  326. for (auto fit : { SkBackingFit::kExact, SkBackingFit::kApprox }) {
  327. for (int width : { 0, 100 }) {
  328. for (int height : { 0, 100}) {
  329. if (width && height) {
  330. continue; // not zero-sized
  331. }
  332. GrSurfaceDesc desc;
  333. desc.fWidth = width;
  334. desc.fHeight = height;
  335. desc.fConfig = kRGBA_8888_GrPixelConfig;
  336. const GrBackendFormat format =
  337. ctxInfo.grContext()->priv().caps()->getBackendFormatFromColorType(
  338. GrColorType::kRGBA_8888);
  339. sk_sp<GrTextureProxy> proxy = provider->createProxy(
  340. format, desc, renderable, 1, kBottomLeft_GrSurfaceOrigin, fit,
  341. SkBudgeted::kNo, GrProtected::kNo);
  342. REPORTER_ASSERT(reporter, !proxy);
  343. }
  344. }
  345. }
  346. }
  347. }