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