/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkBlendMode.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkSurface.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypes.h"
#include "include/gpu/GpuTypes.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrContextOptions.h"
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/GrRecordingContext.h"
#include "include/gpu/GrTypes.h"
#include "include/gpu/ganesh/SkImageGanesh.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "include/gpu/mock/GrMockTypes.h"
#include "include/private/SkColorData.h"
#include "include/private/gpu/ganesh/GrTextureGenerator.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/gpu/SkBackingFit.h"
#include "src/gpu/Swizzle.h"
#include "src/gpu/ganesh/Device.h"
#include "src/gpu/ganesh/GrBackendTextureImageGenerator.h"
#include "src/gpu/ganesh/GrCaps.h"
#include "src/gpu/ganesh/GrColorSpaceXform.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrDrawingManager.h"
#include "src/gpu/ganesh/GrProxyProvider.h"
#include "src/gpu/ganesh/GrRecordingContextPriv.h"
#include "src/gpu/ganesh/GrSamplerState.h"
#include "src/gpu/ganesh/GrSemaphore.h"
#include "src/gpu/ganesh/GrSurfaceProxy.h"
#include "src/gpu/ganesh/GrSurfaceProxyPriv.h"
#include "src/gpu/ganesh/GrSurfaceProxyView.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/gpu/ganesh/GrTextureProxy.h"
#include "src/gpu/ganesh/SkGr.h"
#include "src/gpu/ganesh/SurfaceDrawContext.h"
#include "src/gpu/ganesh/ops/OpsTask.h"
#include "src/gpu/ganesh/surface/SkSurface_Ganesh.h"
#include "tests/CtsEnforcement.h"
#include "tests/Test.h"
#include "tools/gpu/BackendSurfaceFactory.h"
#include "tools/gpu/BackendTextureImageFactory.h"
#include "tools/gpu/ManagedBackendTexture.h"
#include "tools/gpu/ProxyUtils.h"

#include <initializer_list>
#include <memory>
#include <utility>

class GrRenderTask;

#if defined(SK_DIRECT3D)
#include "include/gpu/d3d/GrD3DTypes.h"
#endif

#if defined(SK_GL)
#include "include/gpu/ganesh/gl/GrGLBackendSurface.h"
#include "include/gpu/gl/GrGLTypes.h"
#endif

#if defined(SK_VULKAN)
#include "include/gpu/ganesh/vk/GrVkBackendSurface.h"
#include "include/gpu/vk/GrVkTypes.h"
#endif

static constexpr int kSize = 8;

// Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in
// SkImages and SkSurfaces
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using namespace skgpu;

    auto dContext = ctxInfo.directContext();
    if (!dContext->priv().caps()->mipmapSupport()) {
        return;
    }

    Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());

    for (auto mipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
        for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
            // createBackendTexture currently doesn't support uploading data to mip maps
            // so we don't send any. However, we pretend there is data for the checks below which is
            // fine since we are never actually using these textures for any work on the gpu.
            auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithData(dContext,
                                                                         kSize,
                                                                         kSize,
                                                                         kRGBA_8888_SkColorType,
                                                                         SkColors::kTransparent,
                                                                         mipmapped,
                                                                         renderable,
                                                                         isProtected);
            if (!mbet) {
                ERRORF(reporter, "Could not make texture.");
                return;
            }

            sk_sp<GrTextureProxy> proxy;
            sk_sp<SkImage> image;
            if (renderable == GrRenderable::kYes) {
                sk_sp<SkSurface> surface = SkSurfaces::WrapBackendTexture(
                        dContext,
                        mbet->texture(),
                        kTopLeft_GrSurfaceOrigin,
                        0,
                        kRGBA_8888_SkColorType,
                        /*color space*/ nullptr,
                        /*surface props*/ nullptr,
                        sk_gpu_test::ManagedBackendTexture::ReleaseProc,
                        mbet->releaseContext());

                auto device = ((SkSurface_Ganesh*)surface.get())->getDevice();
                proxy = device->readSurfaceView().asTextureProxyRef();
            } else {
                image = SkImages::BorrowTextureFrom(dContext,
                                                    mbet->texture(),
                                                    kTopLeft_GrSurfaceOrigin,
                                                    kRGBA_8888_SkColorType,
                                                    kPremul_SkAlphaType,
                                                    /* color space */ nullptr,
                                                    sk_gpu_test::ManagedBackendTexture::ReleaseProc,
                                                    mbet->releaseContext());
                REPORTER_ASSERT(reporter, (mipmapped == Mipmapped::kYes) == image->hasMipmaps());
                proxy = sk_ref_sp(sk_gpu_test::GetTextureImageProxy(image.get(), dContext));
            }
            REPORTER_ASSERT(reporter, proxy);
            if (!proxy) {
                continue;
            }

            REPORTER_ASSERT(reporter, proxy->isInstantiated());

            GrTexture* texture = proxy->peekTexture();
            REPORTER_ASSERT(reporter, texture);
            if (!texture) {
                continue;
            }

            if (mipmapped == Mipmapped::kYes) {
                REPORTER_ASSERT(reporter, Mipmapped::kYes == texture->mipmapped());
                if (GrRenderable::kYes == renderable) {
                    REPORTER_ASSERT(reporter, texture->mipmapsAreDirty());
                } else {
                    REPORTER_ASSERT(reporter, !texture->mipmapsAreDirty());
                }
            } else {
                REPORTER_ASSERT(reporter, Mipmapped::kNo == texture->mipmapped());
            }
        }
    }
}

// Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator
// based on if we will use mips in the draw and the mip status of the GrBackendTexture.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    using namespace skgpu;

    auto dContext = ctxInfo.directContext();
    if (!dContext->priv().caps()->mipmapSupport()) {
        return;
    }

    Protected isProtected = Protected(dContext->priv().caps()->supportsProtectedContent());

    for (auto betMipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
        for (auto requestMipmapped : { Mipmapped::kNo, Mipmapped::kYes }) {
            auto ii =
                    SkImageInfo::Make({kSize, kSize}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
            sk_sp<SkImage> image = sk_gpu_test::MakeBackendTextureImage(
                    dContext, ii, SkColors::kTransparent, betMipmapped,
                    Renderable::kNo,
                    GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
                    isProtected);
            REPORTER_ASSERT(reporter, (betMipmapped == Mipmapped::kYes) == image->hasMipmaps());

            GrTextureProxy* proxy = sk_gpu_test::GetTextureImageProxy(image.get(), dContext);
            REPORTER_ASSERT(reporter, proxy);
            if (!proxy) {
                return;
            }

            REPORTER_ASSERT(reporter, proxy->isInstantiated());

            sk_sp<GrTexture> texture = sk_ref_sp(proxy->peekTexture());
            REPORTER_ASSERT(reporter, texture);
            if (!texture) {
                return;
            }

            std::unique_ptr<GrTextureGenerator> textureGen = GrBackendTextureImageGenerator::Make(
                    texture, kTopLeft_GrSurfaceOrigin, nullptr, kRGBA_8888_SkColorType,
                    kPremul_SkAlphaType, nullptr);
            REPORTER_ASSERT(reporter, textureGen);
            if (!textureGen) {
                return;
            }

            SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
                                                      kPremul_SkAlphaType);
            GrSurfaceProxyView genView = textureGen->generateTexture(
                    dContext, imageInfo, requestMipmapped, GrImageTexGenPolicy::kDraw);
            GrSurfaceProxy* genProxy = genView.proxy();

            REPORTER_ASSERT(reporter, genProxy);
            if (!genProxy) {
                return;
            }

            if (genProxy->isLazy()) {
                genProxy->priv().doLazyInstantiation(dContext->priv().resourceProvider());
            } else if (!genProxy->isInstantiated()) {
                genProxy->instantiate(dContext->priv().resourceProvider());
            }

            REPORTER_ASSERT(reporter, genProxy->isInstantiated());
            if (!genProxy->isInstantiated()) {
                return;
            }

            GrTexture* genTexture = genProxy->peekTexture();
            REPORTER_ASSERT(reporter, genTexture);
            if (!genTexture) {
                return;
            }

            GrBackendTexture backendTex = texture->getBackendTexture();
            GrBackendTexture genBackendTex = genTexture->getBackendTexture();

            if (GrBackendApi::kOpenGL == genBackendTex.backend()) {
#ifdef SK_GL
                GrGLTextureInfo genTexInfo;
                GrGLTextureInfo origTexInfo;
                if (GrBackendTextures::GetGLTextureInfo(genBackendTex, &genTexInfo) &&
                    GrBackendTextures::GetGLTextureInfo(backendTex, &origTexInfo)) {
                    if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
                        // We did a copy so the texture IDs should be different
                        REPORTER_ASSERT(reporter, origTexInfo.fID != genTexInfo.fID);
                    } else {
                        REPORTER_ASSERT(reporter, origTexInfo.fID == genTexInfo.fID);
                    }
                } else {
                    ERRORF(reporter, "Failed to get GrGLTextureInfo");
                }
#endif
#ifdef SK_VULKAN
            } else if (GrBackendApi::kVulkan == genBackendTex.backend()) {
                GrVkImageInfo genImageInfo;
                GrVkImageInfo origImageInfo;
                if (GrBackendTextures::GetVkImageInfo(genBackendTex, &genImageInfo) &&
                    GrBackendTextures::GetVkImageInfo(backendTex, &origImageInfo)) {
                    if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
                        // We did a copy so the texture IDs should be different
                        REPORTER_ASSERT(reporter, origImageInfo.fImage != genImageInfo.fImage);
                    } else {
                        REPORTER_ASSERT(reporter, origImageInfo.fImage == genImageInfo.fImage);
                    }
                } else {
                    ERRORF(reporter, "Failed to get GrVkImageInfo");
                }
#endif
#ifdef SK_METAL
            } else if (GrBackendApi::kMetal == genBackendTex.backend()) {
                GrMtlTextureInfo genImageInfo;
                GrMtlTextureInfo origImageInfo;
                if (genBackendTex.getMtlTextureInfo(&genImageInfo) &&
                    backendTex.getMtlTextureInfo(&origImageInfo)) {
                    if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
                        // We did a copy so the texture IDs should be different
                        REPORTER_ASSERT(reporter, origImageInfo.fTexture != genImageInfo.fTexture);
                    } else {
                        REPORTER_ASSERT(reporter, origImageInfo.fTexture == genImageInfo.fTexture);
                    }
                } else {
                    ERRORF(reporter, "Failed to get GrMtlTextureInfo");
                }
#endif
#ifdef SK_DIRECT3D
            } else if (GrBackendApi::kDirect3D == genBackendTex.backend()) {
                GrD3DTextureResourceInfo genImageInfo;
                GrD3DTextureResourceInfo origImageInfo;
                if (genBackendTex.getD3DTextureResourceInfo(&genImageInfo) &&
                    backendTex.getD3DTextureResourceInfo(&origImageInfo)) {
                    if (requestMipmapped == Mipmapped::kYes && betMipmapped == Mipmapped::kNo) {
                        // We did a copy so the texture resources should be different
                        REPORTER_ASSERT(reporter,
                                        origImageInfo.fResource != genImageInfo.fResource);
                    } else {
                        REPORTER_ASSERT(reporter,
                                        origImageInfo.fResource == genImageInfo.fResource);
                    }
                } else {
                    ERRORF(reporter, "Failed to get GrMtlTextureInfo");
                }
#endif
            } else {
                REPORTER_ASSERT(reporter, false);
            }
        }
    }
}

// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the
// resource we took the snapshot of.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    auto dContext = ctxInfo.directContext();
    if (!dContext->priv().caps()->mipmapSupport()) {
        return;
    }

    GrProtected isProtected = GrProtected(dContext->priv().caps()->supportsProtectedContent());

    auto resourceProvider = dContext->priv().resourceProvider();

    for (auto willUseMips : {false, true}) {
        for (auto isWrapped : {false, true}) {
            skgpu::Mipmapped mipmapped =
                    willUseMips ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
            sk_sp<SkSurface> surface;
            SkImageInfo info =
                    SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
            if (isWrapped) {
                surface = sk_gpu_test::MakeBackendTextureSurface(dContext,
                                                                 info,
                                                                 kTopLeft_GrSurfaceOrigin,
                                                                 /* sample count */ 1,
                                                                 mipmapped,
                                                                 isProtected);
            } else {
                surface = SkSurfaces::RenderTarget(dContext,
                                                   skgpu::Budgeted::kYes,
                                                   info,
                                                   /* sample count */ 1,
                                                   kTopLeft_GrSurfaceOrigin,
                                                   nullptr,
                                                   willUseMips);
            }
            REPORTER_ASSERT(reporter, surface);
            auto device = ((SkSurface_Ganesh*)surface.get())->getDevice();
            GrTextureProxy* texProxy = device->readSurfaceView().asTextureProxy();
            REPORTER_ASSERT(reporter, mipmapped == texProxy->mipmapped());

            texProxy->instantiate(resourceProvider);
            GrTexture* texture = texProxy->peekTexture();
            REPORTER_ASSERT(reporter, mipmapped == texture->mipmapped());

            sk_sp<SkImage> image = surface->makeImageSnapshot();
            REPORTER_ASSERT(reporter, willUseMips == image->hasMipmaps());
            REPORTER_ASSERT(reporter, image);
            texProxy = sk_gpu_test::GetTextureImageProxy(image.get(), dContext);
            REPORTER_ASSERT(reporter, mipmapped == texProxy->mipmapped());

            texProxy->instantiate(resourceProvider);
            texture = texProxy->peekTexture();
            REPORTER_ASSERT(reporter, mipmapped == texture->mipmapped());
        }
    }
}

// Test that we don't create a mip mapped texture if the size is 1x1 even if the filter mode is set
// to use mips. This test passes by not crashing or hitting asserts in code.
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(Gr1x1TextureMipMappedTest,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kApiLevel_T) {
    auto dContext = ctxInfo.directContext();
    if (!dContext->priv().caps()->mipmapSupport()) {
        return;
    }

    // Make surface to draw into
    SkImageInfo info = SkImageInfo::MakeN32(16, 16, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, info);

    // Make 1x1 raster bitmap
    SkBitmap bmp;
    bmp.allocN32Pixels(1, 1);
    SkPMColor* pixel = reinterpret_cast<SkPMColor*>(bmp.getPixels());
    *pixel = 0;

    sk_sp<SkImage> bmpImage = bmp.asImage();

    // Make sure we scale so we don't optimize out the use of mips.
    surface->getCanvas()->scale(0.5f, 0.5f);

    // This should upload the image to a non mipped GrTextureProxy.
    surface->getCanvas()->drawImage(bmpImage, 0, 0);
    dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);

    // Now set the filter quality to high so we use mip maps. We should find the non mipped texture
    // in the cache for the SkImage. Since the texture is 1x1 we should just use that texture
    // instead of trying to do a copy to a mipped texture.
    surface->getCanvas()->drawImage(bmpImage, 0, 0, SkSamplingOptions({1.0f/3, 1.0f/3}));
    dContext->flushAndSubmit(surface.get(), GrSyncCpu::kNo);
}

// Create a new render target and draw 'mipmapView' into it using the provided 'filter'.
static std::unique_ptr<skgpu::ganesh::SurfaceDrawContext> draw_mipmap_into_new_render_target(
        GrRecordingContext* rContext,
        GrColorType colorType,
        SkAlphaType alphaType,
        GrSurfaceProxyView mipmapView,
        GrSamplerState::MipmapMode mm) {
    auto proxyProvider = rContext->priv().proxyProvider();
    sk_sp<GrSurfaceProxy> renderTarget =
            proxyProvider->createProxy(mipmapView.proxy()->backendFormat(),
                                       {1, 1},
                                       GrRenderable::kYes,
                                       1,
                                       skgpu::Mipmapped::kNo,
                                       SkBackingFit::kApprox,
                                       skgpu::Budgeted::kYes,
                                       GrProtected::kNo,
                                       /*label=*/"DrawMipMapViewTest");

    auto sdc = skgpu::ganesh::SurfaceDrawContext::Make(rContext,
                                                       colorType,
                                                       std::move(renderTarget),
                                                       nullptr,
                                                       kTopLeft_GrSurfaceOrigin,
                                                       SkSurfaceProps());

    sdc->drawTexture(nullptr,
                     std::move(mipmapView),
                     alphaType,
                     GrSamplerState::Filter::kLinear,
                     mm,
                     SkBlendMode::kSrcOver,
                     {1, 1, 1, 1},
                     SkRect::MakeWH(4, 4),
                     SkRect::MakeWH(1, 1),
                     GrQuadAAFlags::kAll,
                     SkCanvas::kFast_SrcRectConstraint,
                     SkMatrix::I(),
                     nullptr);
    return sdc;
}

// Test that two opsTasks using the same mipmaps both depend on the same GrTextureResolveRenderTask.
DEF_GANESH_TEST(GrManyDependentsMipMappedTest,
                reporter,
                /* options */,
                CtsEnforcement::kApiLevel_T) {
    using Enable = GrContextOptions::Enable;
    using MipmapMode = GrSamplerState::MipmapMode;

    for (auto enableSortingAndReduction : {Enable::kYes, Enable::kNo}) {
        GrMockOptions mockOptions;
        mockOptions.fMipmapSupport = true;
        GrContextOptions ctxOptions;
        ctxOptions.fReduceOpsTaskSplitting = enableSortingAndReduction;
        sk_sp<GrDirectContext> dContext = GrDirectContext::MakeMock(&mockOptions, ctxOptions);
        GrDrawingManager* drawingManager = dContext->priv().drawingManager();
        if (!dContext) {
            ERRORF(reporter, "could not create mock dContext with fReduceOpsTaskSplitting %s.",
                   (Enable::kYes == enableSortingAndReduction) ? "enabled" : "disabled");
            continue;
        }

        SkASSERT(dContext->priv().caps()->mipmapSupport());

        GrBackendFormat format = dContext->defaultBackendFormat(
                kRGBA_8888_SkColorType, GrRenderable::kYes);
        GrColorType colorType = GrColorType::kRGBA_8888;
        SkAlphaType alphaType = kPremul_SkAlphaType;

        GrProxyProvider* proxyProvider = dContext->priv().proxyProvider();

        // Create a mipmapped render target.

        sk_sp<GrTextureProxy> mipmapProxy =
                proxyProvider->createProxy(format,
                                           {4, 4},
                                           GrRenderable::kYes,
                                           1,
                                           skgpu::Mipmapped::kYes,
                                           SkBackingFit::kExact,
                                           skgpu::Budgeted::kYes,
                                           GrProtected::kNo,
                                           /*label=*/"ManyDependentsMipMappedTest");

        // Mark the mipmaps clean to ensure things still work properly when they won't be marked
        // dirty again until GrRenderTask::makeClosed().
        mipmapProxy->markMipmapsClean();

        auto mipmapSDC = skgpu::ganesh::SurfaceDrawContext::Make(dContext.get(),
                                                                 colorType,
                                                                 mipmapProxy,
                                                                 nullptr,
                                                                 kTopLeft_GrSurfaceOrigin,
                                                                 SkSurfaceProps());

        mipmapSDC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
        REPORTER_ASSERT(reporter, drawingManager->getLastRenderTask(mipmapProxy.get()));
        // mipmapProxy's last render task should now just be the opsTask containing the clear.
        REPORTER_ASSERT(reporter,
                mipmapSDC->testingOnly_PeekLastOpsTask() ==
                        drawingManager->getLastRenderTask(mipmapProxy.get()));

        // Mipmaps don't get marked dirty until makeClosed().
        REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());

        skgpu::Swizzle swizzle = dContext->priv().caps()->getReadSwizzle(format, colorType);
        GrSurfaceProxyView mipmapView(mipmapProxy, kTopLeft_GrSurfaceOrigin, swizzle);

        // Draw the dirty mipmap texture into a render target.
        auto sdc1 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
                                                       mipmapView, MipmapMode::kLinear);
        auto sdc1Task = sk_ref_sp(sdc1->testingOnly_PeekLastOpsTask());

        // Mipmaps should have gotten marked dirty during makeClosed, then marked clean again as
        // soon as a GrTextureResolveRenderTask was inserted. The way we know they were resolved is
        // if mipmapProxy->getLastRenderTask() has switched from the opsTask that drew to it, to the
        // task that resolved its mips.
        GrRenderTask* initialMipmapRegenTask = drawingManager->getLastRenderTask(mipmapProxy.get());
        REPORTER_ASSERT(reporter, initialMipmapRegenTask);
        REPORTER_ASSERT(reporter,
                initialMipmapRegenTask != mipmapSDC->testingOnly_PeekLastOpsTask());
        REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());

        // Draw the now-clean mipmap texture into a second target.
        auto sdc2 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
                                                       mipmapView, MipmapMode::kLinear);
        auto sdc2Task = sk_ref_sp(sdc2->testingOnly_PeekLastOpsTask());

        // Make sure the mipmap texture still has the same regen task.
        REPORTER_ASSERT(reporter,
                    drawingManager->getLastRenderTask(mipmapProxy.get()) == initialMipmapRegenTask);
        SkASSERT(!mipmapProxy->mipmapsAreDirty());

        // Reset everything so we can go again, this time with the first draw not mipmapped.
        dContext->flushAndSubmit();

        // Mip regen tasks don't get added as dependencies until makeClosed().
        REPORTER_ASSERT(reporter, sdc1Task->dependsOn(initialMipmapRegenTask));
        REPORTER_ASSERT(reporter, sdc2Task->dependsOn(initialMipmapRegenTask));

        // Render something to dirty the mips.
        mipmapSDC->clear(SkPMColor4f{.1f, .2f, .3f, .4f});
        auto mipmapRTCTask = sk_ref_sp(mipmapSDC->testingOnly_PeekLastOpsTask());
        REPORTER_ASSERT(reporter, mipmapRTCTask);

        // mipmapProxy's last render task should now just be the opsTask containing the clear.
        REPORTER_ASSERT(reporter,
                    mipmapRTCTask.get() == drawingManager->getLastRenderTask(mipmapProxy.get()));

        // Mipmaps don't get marked dirty until makeClosed().
        REPORTER_ASSERT(reporter, !mipmapProxy->mipmapsAreDirty());

        // Draw the dirty mipmap texture into a render target, but don't do mipmap filtering.
        sdc1 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
                                                  mipmapView, MipmapMode::kNone);

        // Mipmaps should have gotten marked dirty during makeClosed() when adding the dependency.
        // Since the last draw did not use mips, they will not have been regenerated and should
        // therefore still be dirty.
        REPORTER_ASSERT(reporter, mipmapProxy->mipmapsAreDirty());

        // Since mips weren't regenerated, the last render task shouldn't have changed.
        REPORTER_ASSERT(reporter,
                    mipmapRTCTask.get() == drawingManager->getLastRenderTask(mipmapProxy.get()));

        // Draw the stil-dirty mipmap texture into a second target with mipmap filtering.
        sdc2 = draw_mipmap_into_new_render_target(dContext.get(), colorType, alphaType,
                                                  std::move(mipmapView), MipmapMode::kLinear);
        sdc2Task = sk_ref_sp(sdc2->testingOnly_PeekLastOpsTask());

        // Make sure the mipmap texture now has a new last render task that regenerates the mips,
        // and that the mipmaps are now clean.
        auto mipRegenTask2 = drawingManager->getLastRenderTask(mipmapProxy.get());
        REPORTER_ASSERT(reporter, mipRegenTask2);
        REPORTER_ASSERT(reporter, mipmapRTCTask.get() != mipRegenTask2);
        SkASSERT(!mipmapProxy->mipmapsAreDirty());

        // Mip regen tasks don't get added as dependencies until makeClosed().
        dContext->flushAndSubmit();
        REPORTER_ASSERT(reporter, sdc2Task->dependsOn(mipRegenTask2));
    }
}
