GrTextureMipMapInvalidationTest.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkSurface.h"
  9. #include "include/gpu/GrContext.h"
  10. #include "src/gpu/GrContextPriv.h"
  11. #include "src/gpu/GrTexturePriv.h"
  12. #include "src/image/SkImage_Base.h"
  13. #include "tests/Test.h"
  14. // Tests that MIP maps are created and invalidated as expected when drawing to and from GrTextures.
  15. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureMipMapInvalidationTest, reporter, ctxInfo) {
  16. GrContext* context = ctxInfo.grContext();
  17. if (!context->priv().caps()->mipMapSupport()) {
  18. return;
  19. }
  20. auto isMipped = [] (SkSurface* surf) {
  21. const GrTexture* texture = surf->makeImageSnapshot()->getTexture();
  22. return GrMipMapped::kYes == texture->texturePriv().mipMapped();
  23. };
  24. auto mipsAreDirty = [] (SkSurface* surf) {
  25. return surf->makeImageSnapshot()->getTexture()->texturePriv().mipMapsAreDirty();
  26. };
  27. auto info = SkImageInfo::MakeN32Premul(256, 256);
  28. for (auto allocateMips : {false, true}) {
  29. auto surf1 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
  30. kBottomLeft_GrSurfaceOrigin, nullptr,
  31. allocateMips);
  32. auto surf2 = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
  33. // Draw something just in case we ever had a solid color optimization
  34. surf1->getCanvas()->drawCircle(128, 128, 50, SkPaint());
  35. surf1->flush();
  36. // No mipmaps initially
  37. REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
  38. // Painting with downscale and medium filter quality should result in mipmap creation
  39. // Flush the context rather than the canvas as flushing the canvas triggers MIP level
  40. // generation.
  41. SkPaint paint;
  42. paint.setFilterQuality(kMedium_SkFilterQuality);
  43. surf2->getCanvas()->scale(0.2f, 0.2f);
  44. surf2->getCanvas()->drawImage(surf1->makeImageSnapshot(), 0, 0, &paint);
  45. context->flush();
  46. REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
  47. REPORTER_ASSERT(reporter, !allocateMips || !mipsAreDirty(surf1.get()));
  48. // Changing the contents of the surface should invalidate the mipmap, but not de-allocate
  49. surf1->getCanvas()->drawCircle(128, 128, 100, SkPaint());
  50. context->flush();
  51. REPORTER_ASSERT(reporter, isMipped(surf1.get()) == allocateMips);
  52. REPORTER_ASSERT(reporter, mipsAreDirty(surf1.get()));
  53. }
  54. }
  55. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ReimportImageTextureWithMipLevels, reporter, ctxInfo) {
  56. auto* ctx = ctxInfo.grContext();
  57. if (!ctx->priv().caps()->mipMapSupport()) {
  58. return;
  59. }
  60. static constexpr auto kCreateWithMipMaps = true;
  61. auto surf = SkSurface::MakeRenderTarget(
  62. ctx, SkBudgeted::kYes,
  63. SkImageInfo::Make(100, 100, kRGBA_8888_SkColorType, kPremul_SkAlphaType), 1,
  64. kTopLeft_GrSurfaceOrigin, nullptr, kCreateWithMipMaps);
  65. if (!surf) {
  66. return;
  67. }
  68. surf->getCanvas()->drawColor(SK_ColorDKGRAY);
  69. auto img = surf->makeImageSnapshot();
  70. if (!img) {
  71. return;
  72. }
  73. surf.reset();
  74. GrBackendTexture btex;
  75. SkImage::BackendTextureReleaseProc texRelease;
  76. if (!SkImage::MakeBackendTextureFromSkImage(ctx, std::move(img), &btex, &texRelease)) {
  77. // Not all backends support stealing textures yet.
  78. // ERRORF(reporter, "Could not turn image into texture");
  79. return;
  80. }
  81. REPORTER_ASSERT(reporter, btex.hasMipMaps());
  82. // Reimport the texture as an image and perform a downsampling draw with medium quality which
  83. // should use the upper MIP levels.
  84. img = SkImage::MakeFromTexture(ctx, btex, kTopLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType,
  85. kPremul_SkAlphaType, nullptr);
  86. const auto singlePixelInfo =
  87. SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
  88. surf = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kYes, singlePixelInfo, 1,
  89. kTopLeft_GrSurfaceOrigin, nullptr);
  90. SkPaint paint;
  91. paint.setFilterQuality(kMedium_SkFilterQuality);
  92. surf->getCanvas()->drawImageRect(img, SkRect::MakeWH(1, 1), &paint);
  93. uint32_t pixel;
  94. surf->readPixels(singlePixelInfo, &pixel, sizeof(uint32_t), 0, 0);
  95. REPORTER_ASSERT(reporter, pixel == SkPreMultiplyColor(SK_ColorDKGRAY));
  96. img.reset();
  97. texRelease(btex);
  98. }