TextureBindingsResetTest.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /*
  2. * Copyright 2019 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. #include "include/core/SkSurface.h"
  8. #include "src/gpu/GrContextPriv.h"
  9. #include "src/gpu/gl/GrGLDefines.h"
  10. #include "src/gpu/gl/GrGLGpu.h"
  11. #include "src/gpu/gl/GrGLUtil.h"
  12. #include "tests/Test.h"
  13. DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(TextureBindingsResetTest, reporter, ctxInfo) {
  14. #define GL(F) GR_GL_CALL(ctxInfo.glContext()->gl(), F)
  15. GrContext* context = ctxInfo.grContext();
  16. GrGpu* gpu = context->priv().getGpu();
  17. GrGLGpu* glGpu = static_cast<GrGLGpu*>(context->priv().getGpu());
  18. struct Target {
  19. GrGLenum fName;
  20. GrGLenum fQuery;
  21. };
  22. SkTDArray<Target> targets;
  23. targets.push_back({GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BINDING_2D});
  24. bool supportExternal;
  25. if ((supportExternal = glGpu->glCaps().shaderCaps()->externalTextureSupport())) {
  26. targets.push_back({GR_GL_TEXTURE_EXTERNAL, GR_GL_TEXTURE_BINDING_EXTERNAL});
  27. }
  28. bool supportRectangle;
  29. if ((supportRectangle = glGpu->glCaps().rectangleTextureSupport())) {
  30. targets.push_back({GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_BINDING_RECTANGLE});
  31. }
  32. GrGLint numUnits;
  33. GL(GetIntegerv(GR_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numUnits));
  34. SkTDArray<GrGLuint> claimedIDs;
  35. claimedIDs.setCount(numUnits * targets.count());
  36. GL(GenTextures(claimedIDs.count(), claimedIDs.begin()));
  37. auto resetBindings = [&] {
  38. int i = 0;
  39. for (int u = 0; u < numUnits; ++u) {
  40. GL(ActiveTexture(GR_GL_TEXTURE0 + u));
  41. for (auto target : targets) {
  42. GL(BindTexture(target.fName, claimedIDs[i++]));
  43. }
  44. }
  45. };
  46. auto checkBindings = [&] {
  47. int i = 0;
  48. for (int u = 0; u < numUnits; ++u) {
  49. GL(ActiveTexture(GR_GL_TEXTURE0 + u));
  50. for (auto target : targets) {
  51. GrGLuint boundID = ~0;
  52. GL(GetIntegerv(target.fQuery, reinterpret_cast<GrGLint*>(&boundID)));
  53. if (boundID != claimedIDs[i] && boundID != 0) {
  54. ERRORF(reporter, "Unit %d, target 0x%04x has ID %d bound. Expected %d or 0.", u,
  55. target.fName, boundID, claimedIDs[i]);
  56. return;
  57. }
  58. ++i;
  59. }
  60. }
  61. };
  62. // Initialize texture unit/target combo bindings to 0.
  63. context->flush();
  64. resetBindings();
  65. context->resetContext();
  66. // Test creating a texture and then resetting bindings.
  67. GrSurfaceDesc desc;
  68. desc.fWidth = desc.fHeight = 10;
  69. desc.fConfig = kRGBA_8888_GrPixelConfig;
  70. auto tex = gpu->createTexture(desc, GrRenderable::kNo, 1, SkBudgeted::kNo, GrProtected::kNo);
  71. REPORTER_ASSERT(reporter, tex);
  72. context->resetGLTextureBindings();
  73. checkBindings();
  74. resetBindings();
  75. context->resetContext();
  76. // Test drawing and then resetting bindings. This should force a MIP regeneration if MIP
  77. // maps are supported as well.
  78. auto info = SkImageInfo::Make(10, 10, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
  79. auto surf = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 1, nullptr);
  80. surf->getCanvas()->clear(0x80FF0000);
  81. auto img = surf->makeImageSnapshot();
  82. surf->getCanvas()->clear(SK_ColorBLUE);
  83. surf->getCanvas()->save();
  84. surf->getCanvas()->scale(0.25, 0.25);
  85. SkPaint paint;
  86. paint.setFilterQuality(kHigh_SkFilterQuality);
  87. surf->getCanvas()->drawImage(img, 0, 0, &paint);
  88. surf->getCanvas()->restore();
  89. surf->flush();
  90. context->resetGLTextureBindings();
  91. checkBindings();
  92. resetBindings();
  93. context->resetContext();
  94. if (supportExternal) {
  95. GrBackendTexture texture2D = context->createBackendTexture(
  96. 10, 10, kRGBA_8888_SkColorType,
  97. SkColors::kTransparent, GrMipMapped::kNo, GrRenderable::kNo, GrProtected::kNo);
  98. GrGLTextureInfo info2D;
  99. REPORTER_ASSERT(reporter, texture2D.getGLTextureInfo(&info2D));
  100. GrEGLImage eglImage = ctxInfo.glContext()->texture2DToEGLImage(info2D.fID);
  101. REPORTER_ASSERT(reporter, eglImage);
  102. GrGLTextureInfo infoExternal;
  103. infoExternal.fID = ctxInfo.glContext()->eglImageToExternalTexture(eglImage);
  104. infoExternal.fTarget = GR_GL_TEXTURE_EXTERNAL;
  105. infoExternal.fFormat = info2D.fFormat;
  106. REPORTER_ASSERT(reporter, infoExternal.fID);
  107. GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, infoExternal);
  108. // Above texture creation will have messed with GL state and bindings.
  109. resetBindings();
  110. context->resetContext();
  111. img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
  112. kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
  113. REPORTER_ASSERT(reporter, img);
  114. surf->getCanvas()->drawImage(img, 0, 0);
  115. img.reset();
  116. surf->flush();
  117. context->resetGLTextureBindings();
  118. checkBindings();
  119. resetBindings();
  120. GL(DeleteTextures(1, &infoExternal.fID));
  121. ctxInfo.glContext()->destroyEGLImage(eglImage);
  122. context->deleteBackendTexture(texture2D);
  123. context->resetContext();
  124. }
  125. if (supportRectangle) {
  126. GrGLuint id = ctxInfo.glContext()->createTextureRectangle(10, 10, GR_GL_RGBA, GR_GL_RGBA,
  127. GR_GL_UNSIGNED_BYTE, nullptr);
  128. // Above texture creation will have messed with GL state and bindings.
  129. resetBindings();
  130. context->resetContext();
  131. if (id) {
  132. GrGLTextureInfo info;
  133. info.fTarget = GR_GL_TEXTURE_RECTANGLE;
  134. info.fFormat = GR_GL_RGBA8;
  135. info.fID = id;
  136. GrBackendTexture backendTexture(10, 10, GrMipMapped::kNo, info);
  137. img = SkImage::MakeFromTexture(context, backendTexture, kTopLeft_GrSurfaceOrigin,
  138. kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
  139. REPORTER_ASSERT(reporter, img);
  140. surf->getCanvas()->drawImage(img, 0, 0);
  141. img.reset();
  142. surf->flush();
  143. context->resetGLTextureBindings();
  144. checkBindings();
  145. resetBindings();
  146. GL(DeleteTextures(1, &id));
  147. context->resetContext();
  148. }
  149. }
  150. GL(DeleteTextures(claimedIDs.count(), claimedIDs.begin()));
  151. #undef GL
  152. }