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

#include "tools/viewer/Viewer.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkData.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkStream.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "include/private/SkTPin.h"
#include "include/private/SkTo.h"
#include "include/utils/SkPaintFilterCanvas.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkGlyphRun.h"
#include "src/core/SkImagePriv.h"
#include "src/core/SkMD5.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkScan.h"
#include "src/core/SkStringUtils.h"
#include "src/core/SkSurfacePriv.h"
#include "src/core/SkTSort.h"
#include "src/core/SkTaskGroup.h"
#include "src/core/SkTextBlobPriv.h"
#include "src/core/SkVMBlitter.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrPersistentCacheUtils.h"
#include "src/image/SkImage_Base.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/utils/SkJSONWriter.h"
#include "src/utils/SkOSPath.h"
#include "src/utils/SkShaderUtils.h"
#include "tools/Resources.h"
#include "tools/RuntimeBlendUtils.h"
#include "tools/ToolUtils.h"
#include "tools/flags/CommandLineFlags.h"
#include "tools/flags/CommonFlags.h"
#include "tools/trace/EventTracingPriv.h"
#include "tools/viewer/BisectSlide.h"
#include "tools/viewer/GMSlide.h"
#include "tools/viewer/ImageSlide.h"
#include "tools/viewer/MSKPSlide.h"
#include "tools/viewer/ParticlesSlide.h"
#include "tools/viewer/SKPSlide.h"
#include "tools/viewer/SampleSlide.h"
#include "tools/viewer/SkSLDebuggerSlide.h"
#include "tools/viewer/SkSLSlide.h"
#include "tools/viewer/SlideDir.h"
#include "tools/viewer/SvgSlide.h"

#if SK_GPU_V1
#include "src/gpu/ganesh/ops/AtlasPathRenderer.h"
#include "src/gpu/ganesh/ops/TessellationPathRenderer.h"
#endif

#include <cstdlib>
#include <map>

#include "imgui.h"
#include "misc/cpp/imgui_stdlib.h"  // For ImGui support of std::string

#ifdef SK_VULKAN
#include "spirv-tools/libspirv.hpp"
#endif

#if defined(SK_ENABLE_SKOTTIE)
    #include "tools/viewer/SkottieSlide.h"
#endif

#if defined(SK_ENABLE_SVG)
    #include "modules/svg/include/SkSVGOpenTypeSVGDecoder.h"
#endif

class CapturingShaderErrorHandler : public GrContextOptions::ShaderErrorHandler {
public:
    void compileError(const char* shader, const char* errors) override {
        fShaders.push_back(SkString(shader));
        fErrors.push_back(SkString(errors));
    }

    void reset() {
        fShaders.reset();
        fErrors.reset();
    }

    SkTArray<SkString> fShaders;
    SkTArray<SkString> fErrors;
};

static CapturingShaderErrorHandler gShaderErrorHandler;

GrContextOptions::ShaderErrorHandler* Viewer::ShaderErrorHandler() { return &gShaderErrorHandler; }

using namespace sk_app;
using SkSL::Compiler;
using OverrideFlag = SkSL::Compiler::OverrideFlag;

static std::map<GpuPathRenderers, std::string> gPathRendererNames;

Application* Application::Create(int argc, char** argv, void* platformData) {
    return new Viewer(argc, argv, platformData);
}

static DEFINE_string(slide, "", "Start on this sample.");
static DEFINE_bool(list, false, "List samples?");

#ifdef SK_GL
#define GL_BACKEND_STR ", \"gl\""
#else
#define GL_BACKEND_STR
#endif
#ifdef SK_VULKAN
#define VK_BACKEND_STR ", \"vk\""
#else
#define VK_BACKEND_STR
#endif
#ifdef SK_METAL
#define MTL_BACKEND_STR ", \"mtl\""
#else
#define MTL_BACKEND_STR
#endif
#ifdef SK_DIRECT3D
#define D3D_BACKEND_STR ", \"d3d\""
#else
#define D3D_BACKEND_STR
#endif
#ifdef SK_DAWN
#define DAWN_BACKEND_STR ", \"dawn\""
#else
#define DAWN_BACKEND_STR
#endif
#define BACKENDS_STR_EVALUATOR(sw, gl, vk, mtl, d3d, dawn) sw gl vk mtl d3d dawn
#define BACKENDS_STR BACKENDS_STR_EVALUATOR( \
    "\"sw\"", GL_BACKEND_STR, VK_BACKEND_STR, MTL_BACKEND_STR, D3D_BACKEND_STR, DAWN_BACKEND_STR)

static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BACKENDS_STR ".");

static DEFINE_int(msaa, 1, "Number of subpixel samples. 0 for no HW antialiasing.");
static DEFINE_bool(dmsaa, false, "Use internal MSAA to render to non-MSAA surfaces?");

static DEFINE_string(bisect, "", "Path to a .skp or .svg file to bisect.");

static DEFINE_string2(file, f, "", "Open a single file for viewing.");

static DEFINE_string2(match, m, nullptr,
               "[~][^]substring[$] [...] of name to run.\n"
               "Multiple matches may be separated by spaces.\n"
               "~ causes a matching name to always be skipped\n"
               "^ requires the start of the name to match\n"
               "$ requires the end of the name to match\n"
               "^ and $ requires an exact match\n"
               "If a name does not match any list entry,\n"
               "it is skipped unless some list entry starts with ~");

#if defined(SK_BUILD_FOR_ANDROID)
#   define PATH_PREFIX "/data/local/tmp/"
#else
#   define PATH_PREFIX ""
#endif

static DEFINE_string(jpgs   , PATH_PREFIX "jpgs"   , "Directory to read jpgs from.");
static DEFINE_string(jxls   , PATH_PREFIX "jxls"   , "Directory to read jxls from.");
static DEFINE_string(skps   , PATH_PREFIX "skps"   , "Directory to read skps from.");
static DEFINE_string(mskps  , PATH_PREFIX "mskps"  , "Directory to read mskps from.");
static DEFINE_string(lotties, PATH_PREFIX "lotties", "Directory to read (Bodymovin) jsons from.");
#undef PATH_PREFIX

static DEFINE_string(svgs, "", "Directory to read SVGs from, or a single SVG file.");

static DEFINE_int_2(threads, j, -1,
               "Run threadsafe tests on a threadpool with this many extra threads, "
               "defaulting to one extra thread per core.");

static DEFINE_bool(redraw, false, "Toggle continuous redraw.");

static DEFINE_bool(offscreen, false, "Force rendering to an offscreen surface.");
static DEFINE_bool(skvm, false, "Force skvm blitters for raster.");
static DEFINE_bool(jit, true, "JIT SkVM?");
static DEFINE_bool(dylib, false, "JIT via dylib (much slower compile but easier to debug/profile)");
static DEFINE_bool(stats, false, "Display stats overlay on startup.");
static DEFINE_bool(binaryarchive, false, "Enable MTLBinaryArchive use (if available).");

#ifndef SK_GL
static_assert(false, "viewer requires GL backend for raster.")
#endif

const char* kBackendTypeStrings[sk_app::Window::kBackendTypeCount] = {
    "OpenGL",
#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
    "ANGLE",
#endif
#ifdef SK_DAWN
    "Dawn",
#endif
#ifdef SK_VULKAN
    "Vulkan",
#endif
#ifdef SK_METAL
    "Metal",
#ifdef SK_GRAPHITE_ENABLED
    "Metal (Graphite)",
#endif
#endif
#ifdef SK_DIRECT3D
    "Direct3D",
#endif
    "Raster"
};

static sk_app::Window::BackendType get_backend_type(const char* str) {
#ifdef SK_DAWN
    if (0 == strcmp(str, "dawn")) {
        return sk_app::Window::kDawn_BackendType;
    } else
#endif
#ifdef SK_VULKAN
    if (0 == strcmp(str, "vk")) {
        return sk_app::Window::kVulkan_BackendType;
    } else
#endif
#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
    if (0 == strcmp(str, "angle")) {
        return sk_app::Window::kANGLE_BackendType;
    } else
#endif
#ifdef SK_METAL
    if (0 == strcmp(str, "mtl")) {
        return sk_app::Window::kMetal_BackendType;
    } else
#ifdef SK_GRAPHITE_ENABLED
    if (0 == strcmp(str, "grmtl")) {
        return sk_app::Window::kGraphiteMetal_BackendType;
    } else
#endif
#endif
#ifdef SK_DIRECT3D
    if (0 == strcmp(str, "d3d")) {
        return sk_app::Window::kDirect3D_BackendType;
    } else
#endif

    if (0 == strcmp(str, "gl")) {
        return sk_app::Window::kNativeGL_BackendType;
    } else if (0 == strcmp(str, "sw")) {
        return sk_app::Window::kRaster_BackendType;
    } else {
        SkDebugf("Unknown backend type, %s, defaulting to sw.", str);
        return sk_app::Window::kRaster_BackendType;
    }
}

static SkColorSpacePrimaries gSrgbPrimaries = {
    0.64f, 0.33f,
    0.30f, 0.60f,
    0.15f, 0.06f,
    0.3127f, 0.3290f };

static SkColorSpacePrimaries gAdobePrimaries = {
    0.64f, 0.33f,
    0.21f, 0.71f,
    0.15f, 0.06f,
    0.3127f, 0.3290f };

static SkColorSpacePrimaries gP3Primaries = {
    0.680f, 0.320f,
    0.265f, 0.690f,
    0.150f, 0.060f,
    0.3127f, 0.3290f };

static SkColorSpacePrimaries gRec2020Primaries = {
    0.708f, 0.292f,
    0.170f, 0.797f,
    0.131f, 0.046f,
    0.3127f, 0.3290f };

struct NamedPrimaries {
    const char* fName;
    SkColorSpacePrimaries* fPrimaries;
} gNamedPrimaries[] = {
    { "sRGB", &gSrgbPrimaries },
    { "AdobeRGB", &gAdobePrimaries },
    { "P3", &gP3Primaries },
    { "Rec. 2020", &gRec2020Primaries },
};

static bool primaries_equal(const SkColorSpacePrimaries& a, const SkColorSpacePrimaries& b) {
    return memcmp(&a, &b, sizeof(SkColorSpacePrimaries)) == 0;
}

static Window::BackendType backend_type_for_window(Window::BackendType backendType) {
    // In raster mode, we still use GL for the window.
    // This lets us render the GUI faster (and correct).
    return Window::kRaster_BackendType == backendType ? Window::kNativeGL_BackendType : backendType;
}

class NullSlide : public Slide {
    SkISize getDimensions() const override {
        return SkISize::Make(640, 480);
    }

    void draw(SkCanvas* canvas) override {
        canvas->clear(0xffff11ff);
    }
};

static const char kName[] = "name";
static const char kValue[] = "value";
static const char kOptions[] = "options";
static const char kSlideStateName[] = "Slide";
static const char kBackendStateName[] = "Backend";
static const char kMSAAStateName[] = "MSAA";
static const char kPathRendererStateName[] = "Path renderer";
static const char kSoftkeyStateName[] = "Softkey";
static const char kSoftkeyHint[] = "Please select a softkey";
static const char kON[] = "ON";
static const char kRefreshStateName[] = "Refresh";

extern bool gUseSkVMBlitter;
extern bool gSkVMAllowJIT;
extern bool gSkVMJITViaDylib;

Viewer::Viewer(int argc, char** argv, void* platformData)
    : fCurrentSlide(-1)
    , fRefresh(false)
    , fSaveToSKP(false)
    , fShowSlideDimensions(false)
    , fShowImGuiDebugWindow(false)
    , fShowSlidePicker(false)
    , fShowImGuiTestWindow(false)
    , fShowHistogramWindow(false)
    , fShowZoomWindow(false)
    , fZoomWindowFixed(false)
    , fZoomWindowLocation{0.0f, 0.0f}
    , fLastImage(nullptr)
    , fZoomUI(false)
    , fBackendType(sk_app::Window::kNativeGL_BackendType)
    , fColorMode(ColorMode::kLegacy)
    , fColorSpacePrimaries(gSrgbPrimaries)
    // Our UI can only tweak gamma (currently), so start out gamma-only
    , fColorSpaceTransferFn(SkNamedTransferFn::k2Dot2)
    , fApplyBackingScale(true)
    , fZoomLevel(0.0f)
    , fRotation(0.0f)
    , fOffset{0.5f, 0.5f}
    , fGestureDevice(GestureDevice::kNone)
    , fTiled(false)
    , fDrawTileBoundaries(false)
    , fTileScale{0.25f, 0.25f}
    , fPerspectiveMode(kPerspective_Off)
{
    SkGraphics::Init();
#if defined(SK_ENABLE_SVG)
    SkGraphics::SetOpenTypeSVGDecoderFactory(SkSVGOpenTypeSVGDecoder::Make);
#endif

    gPathRendererNames[GpuPathRenderers::kDefault] = "Default Path Renderers";
    gPathRendererNames[GpuPathRenderers::kAtlas] = "Atlas (tessellation)";
    gPathRendererNames[GpuPathRenderers::kTessellation] = "Tessellation";
    gPathRendererNames[GpuPathRenderers::kSmall] = "Small paths (cached sdf or alpha masks)";
    gPathRendererNames[GpuPathRenderers::kTriangulating] = "Triangulating";
    gPathRendererNames[GpuPathRenderers::kNone] = "Software masks";

    SkDebugf("Command line arguments: ");
    for (int i = 1; i < argc; ++i) {
        SkDebugf("%s ", argv[i]);
    }
    SkDebugf("\n");

    CommandLineFlags::Parse(argc, argv);
#ifdef SK_BUILD_FOR_ANDROID
    SetResourcePath("/data/local/tmp/resources");
#endif

    gUseSkVMBlitter = FLAGS_skvm;
    gSkVMAllowJIT = FLAGS_jit;
    gSkVMJITViaDylib = FLAGS_dylib;

    CommonFlags::SetDefaultFontMgr();

    initializeEventTracingForTools();
    static SkTaskGroup::Enabler kTaskGroupEnabler(FLAGS_threads);

    fBackendType = get_backend_type(FLAGS_backend[0]);
    fWindow = Window::CreateNativeWindow(platformData);

    DisplayParams displayParams;
    displayParams.fMSAASampleCount = FLAGS_msaa;
    displayParams.fEnableBinaryArchive = FLAGS_binaryarchive;
    CommonFlags::SetCtxOptions(&displayParams.fGrContextOptions);
    displayParams.fGrContextOptions.fPersistentCache = &fPersistentCache;
    displayParams.fGrContextOptions.fShaderCacheStrategy =
            GrContextOptions::ShaderCacheStrategy::kSkSL;
    displayParams.fGrContextOptions.fShaderErrorHandler = &gShaderErrorHandler;
    displayParams.fGrContextOptions.fSuppressPrints = true;
    if (FLAGS_dmsaa) {
        displayParams.fSurfaceProps = SkSurfaceProps(
                displayParams.fSurfaceProps.flags() | SkSurfaceProps::kDynamicMSAA_Flag,
                displayParams.fSurfaceProps.pixelGeometry());
    }
    fWindow->setRequestedDisplayParams(displayParams);
    fDisplay = fWindow->getRequestedDisplayParams();
    fRefresh = FLAGS_redraw;

    fImGuiLayer.setScaleFactor(fWindow->scaleFactor());
    fStatsLayer.setDisplayScale((fZoomUI ? 2.0f : 1.0f) * fWindow->scaleFactor());

    // Configure timers
    fStatsLayer.setActive(FLAGS_stats);
    fAnimateTimer = fStatsLayer.addTimer("Animate", SK_ColorMAGENTA, 0xffff66ff);
    fPaintTimer = fStatsLayer.addTimer("Paint", SK_ColorGREEN);
    fFlushTimer = fStatsLayer.addTimer("Flush", SK_ColorRED, 0xffff6666);

    // register callbacks
    fCommands.attach(fWindow);
    fWindow->pushLayer(this);
    fWindow->pushLayer(&fStatsLayer);
    fWindow->pushLayer(&fImGuiLayer);

    // add key-bindings
    fCommands.addCommand(' ', "GUI", "Toggle Debug GUI", [this]() {
        this->fShowImGuiDebugWindow = !this->fShowImGuiDebugWindow;
        fWindow->inval();
    });
    // Command to jump directly to the slide picker and give it focus
    fCommands.addCommand('/', "GUI", "Jump to slide picker", [this]() {
        this->fShowImGuiDebugWindow = true;
        this->fShowSlidePicker = true;
        fWindow->inval();
    });
    // Alias that to Backspace, to match SampleApp
    fCommands.addCommand(skui::Key::kBack, "Backspace", "GUI", "Jump to slide picker", [this]() {
        this->fShowImGuiDebugWindow = true;
        this->fShowSlidePicker = true;
        fWindow->inval();
    });
    fCommands.addCommand('g', "GUI", "Toggle GUI Demo", [this]() {
        this->fShowImGuiTestWindow = !this->fShowImGuiTestWindow;
        fWindow->inval();
    });
    fCommands.addCommand('z', "GUI", "Toggle zoom window", [this]() {
        this->fShowZoomWindow = !this->fShowZoomWindow;
        fWindow->inval();
    });
    fCommands.addCommand('Z', "GUI", "Toggle zoom window state", [this]() {
        this->fZoomWindowFixed = !this->fZoomWindowFixed;
        fWindow->inval();
    });
    fCommands.addCommand('v', "Swapchain", "Toggle vsync on/off", [this]() {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        params.fDisableVsync = !params.fDisableVsync;
        fWindow->setRequestedDisplayParams(params);
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('V', "Swapchain", "Toggle delayed acquire on/off (Metal only)", [this]() {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        params.fDelayDrawableAcquisition = !params.fDelayDrawableAcquisition;
        fWindow->setRequestedDisplayParams(params);
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('r', "Redraw", "Toggle redraw", [this]() {
        fRefresh = !fRefresh;
        fWindow->inval();
    });
    fCommands.addCommand('s', "Overlays", "Toggle stats display", [this]() {
        fStatsLayer.setActive(!fStatsLayer.getActive());
        fWindow->inval();
    });
    fCommands.addCommand('0', "Overlays", "Reset stats", [this]() {
        fStatsLayer.resetMeasurements();
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('C', "GUI", "Toggle color histogram", [this]() {
        this->fShowHistogramWindow = !this->fShowHistogramWindow;
        fWindow->inval();
    });
    fCommands.addCommand('c', "Modes", "Cycle color mode", [this]() {
        switch (fColorMode) {
            case ColorMode::kLegacy:
                this->setColorMode(ColorMode::kColorManaged8888);
                break;
            case ColorMode::kColorManaged8888:
                this->setColorMode(ColorMode::kColorManagedF16);
                break;
            case ColorMode::kColorManagedF16:
                this->setColorMode(ColorMode::kColorManagedF16Norm);
                break;
            case ColorMode::kColorManagedF16Norm:
                this->setColorMode(ColorMode::kLegacy);
                break;
        }
    });
    fCommands.addCommand('w', "Modes", "Toggle wireframe", [this]() {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        params.fGrContextOptions.fWireframeMode = !params.fGrContextOptions.fWireframeMode;
        fWindow->setRequestedDisplayParams(params);
        fWindow->inval();
    });
    fCommands.addCommand('w', "Modes", "Toggle reduced shaders", [this]() {
      DisplayParams params = fWindow->getRequestedDisplayParams();
      params.fGrContextOptions.fReducedShaderVariations =
              !params.fGrContextOptions.fReducedShaderVariations;
      fWindow->setRequestedDisplayParams(params);
      fWindow->inval();
    });
    fCommands.addCommand(skui::Key::kRight, "Right", "Navigation", "Next slide", [this]() {
        this->setCurrentSlide(fCurrentSlide < fSlides.count() - 1 ? fCurrentSlide + 1 : 0);
    });
    fCommands.addCommand(skui::Key::kLeft, "Left", "Navigation", "Previous slide", [this]() {
        this->setCurrentSlide(fCurrentSlide > 0 ? fCurrentSlide - 1 : fSlides.count() - 1);
    });
    fCommands.addCommand(skui::Key::kUp, "Up", "Transform", "Zoom in", [this]() {
        this->changeZoomLevel(1.f / 32.f);
        fWindow->inval();
    });
    fCommands.addCommand(skui::Key::kDown, "Down", "Transform", "Zoom out", [this]() {
        this->changeZoomLevel(-1.f / 32.f);
        fWindow->inval();
    });
    fCommands.addCommand('d', "Modes", "Change rendering backend", [this]() {
        sk_app::Window::BackendType newBackend = (sk_app::Window::BackendType)(
                (fBackendType + 1) % sk_app::Window::kBackendTypeCount);
        // Switching to and from Vulkan is problematic on Linux so disabled for now
#if defined(SK_BUILD_FOR_UNIX) && defined(SK_VULKAN)
        if (newBackend == sk_app::Window::kVulkan_BackendType) {
            newBackend = (sk_app::Window::BackendType)((newBackend + 1) %
                                                       sk_app::Window::kBackendTypeCount);
        } else if (fBackendType == sk_app::Window::kVulkan_BackendType) {
            newBackend = sk_app::Window::kVulkan_BackendType;
        }
#endif
        this->setBackend(newBackend);
    });
    fCommands.addCommand('K', "IO", "Save slide to SKP", [this]() {
        fSaveToSKP = true;
        fWindow->inval();
    });
    fCommands.addCommand('&', "Overlays", "Show slide dimensios", [this]() {
        fShowSlideDimensions = !fShowSlideDimensions;
        fWindow->inval();
    });
    fCommands.addCommand('G', "Modes", "Geometry", [this]() {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        uint32_t flags = params.fSurfaceProps.flags();
        SkPixelGeometry defaultPixelGeometry = fDisplay.fSurfaceProps.pixelGeometry();
        if (!fDisplayOverrides.fSurfaceProps.fPixelGeometry) {
            fDisplayOverrides.fSurfaceProps.fPixelGeometry = true;
            params.fSurfaceProps = SkSurfaceProps(flags, kUnknown_SkPixelGeometry);
        } else {
            switch (params.fSurfaceProps.pixelGeometry()) {
                case kUnknown_SkPixelGeometry:
                    params.fSurfaceProps = SkSurfaceProps(flags, kRGB_H_SkPixelGeometry);
                    break;
                case kRGB_H_SkPixelGeometry:
                    params.fSurfaceProps = SkSurfaceProps(flags, kBGR_H_SkPixelGeometry);
                    break;
                case kBGR_H_SkPixelGeometry:
                    params.fSurfaceProps = SkSurfaceProps(flags, kRGB_V_SkPixelGeometry);
                    break;
                case kRGB_V_SkPixelGeometry:
                    params.fSurfaceProps = SkSurfaceProps(flags, kBGR_V_SkPixelGeometry);
                    break;
                case kBGR_V_SkPixelGeometry:
                    params.fSurfaceProps = SkSurfaceProps(flags, defaultPixelGeometry);
                    fDisplayOverrides.fSurfaceProps.fPixelGeometry = false;
                    break;
            }
        }
        fWindow->setRequestedDisplayParams(params);
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('H', "Font", "Hinting mode", [this]() {
        if (!fFontOverrides.fHinting) {
            fFontOverrides.fHinting = true;
            fFont.setHinting(SkFontHinting::kNone);
        } else {
            switch (fFont.getHinting()) {
                case SkFontHinting::kNone:
                    fFont.setHinting(SkFontHinting::kSlight);
                    break;
                case SkFontHinting::kSlight:
                    fFont.setHinting(SkFontHinting::kNormal);
                    break;
                case SkFontHinting::kNormal:
                    fFont.setHinting(SkFontHinting::kFull);
                    break;
                case SkFontHinting::kFull:
                    fFont.setHinting(SkFontHinting::kNone);
                    fFontOverrides.fHinting = false;
                    break;
            }
        }
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('A', "Paint", "Antialias Mode", [this]() {
        if (!fPaintOverrides.fAntiAlias) {
            fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::Alias;
            fPaintOverrides.fAntiAlias = true;
            fPaint.setAntiAlias(false);
            gSkUseAnalyticAA = gSkForceAnalyticAA = false;
        } else {
            fPaint.setAntiAlias(true);
            switch (fPaintOverrides.fAntiAliasState) {
                case SkPaintFields::AntiAliasState::Alias:
                    fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::Normal;
                    gSkUseAnalyticAA = gSkForceAnalyticAA = false;
                    break;
                case SkPaintFields::AntiAliasState::Normal:
                    fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::AnalyticAAEnabled;
                    gSkUseAnalyticAA = true;
                    gSkForceAnalyticAA = false;
                    break;
                case SkPaintFields::AntiAliasState::AnalyticAAEnabled:
                    fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::AnalyticAAForced;
                    gSkUseAnalyticAA = gSkForceAnalyticAA = true;
                    break;
                case SkPaintFields::AntiAliasState::AnalyticAAForced:
                    fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::Alias;
                    fPaintOverrides.fAntiAlias = false;
                    gSkUseAnalyticAA = fPaintOverrides.fOriginalSkUseAnalyticAA;
                    gSkForceAnalyticAA = fPaintOverrides.fOriginalSkForceAnalyticAA;
                    break;
            }
        }
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('D', "Modes", "DFT", [this]() {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        uint32_t flags = params.fSurfaceProps.flags();
        flags ^= SkSurfaceProps::kUseDeviceIndependentFonts_Flag;
        params.fSurfaceProps = SkSurfaceProps(flags, params.fSurfaceProps.pixelGeometry());
        fWindow->setRequestedDisplayParams(params);
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('L', "Font", "Subpixel Antialias Mode", [this]() {
        if (!fFontOverrides.fEdging) {
            fFontOverrides.fEdging = true;
            fFont.setEdging(SkFont::Edging::kAlias);
        } else {
            switch (fFont.getEdging()) {
                case SkFont::Edging::kAlias:
                    fFont.setEdging(SkFont::Edging::kAntiAlias);
                    break;
                case SkFont::Edging::kAntiAlias:
                    fFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
                    break;
                case SkFont::Edging::kSubpixelAntiAlias:
                    fFont.setEdging(SkFont::Edging::kAlias);
                    fFontOverrides.fEdging = false;
                    break;
            }
        }
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('S', "Font", "Subpixel Position Mode", [this]() {
        if (!fFontOverrides.fSubpixel) {
            fFontOverrides.fSubpixel = true;
            fFont.setSubpixel(false);
        } else {
            if (!fFont.isSubpixel()) {
                fFont.setSubpixel(true);
            } else {
                fFontOverrides.fSubpixel = false;
            }
        }
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('B', "Font", "Baseline Snapping", [this]() {
        if (!fFontOverrides.fBaselineSnap) {
            fFontOverrides.fBaselineSnap = true;
            fFont.setBaselineSnap(false);
        } else {
            if (!fFont.isBaselineSnap()) {
                fFont.setBaselineSnap(true);
            } else {
                fFontOverrides.fBaselineSnap = false;
            }
        }
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('p', "Transform", "Toggle Perspective Mode", [this]() {
        fPerspectiveMode = (kPerspective_Real == fPerspectiveMode) ? kPerspective_Fake
                                                                   : kPerspective_Real;
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('P', "Transform", "Toggle Perspective", [this]() {
        fPerspectiveMode = (kPerspective_Off == fPerspectiveMode) ? kPerspective_Real
                                                                  : kPerspective_Off;
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('a', "Transform", "Toggle Animation", [this]() {
        fAnimTimer.togglePauseResume();
    });
    fCommands.addCommand('u', "GUI", "Zoom UI", [this]() {
        fZoomUI = !fZoomUI;
        fStatsLayer.setDisplayScale((fZoomUI ? 2.0f : 1.0f) * fWindow->scaleFactor());
        fWindow->inval();
    });
    fCommands.addCommand('$', "ViaSerialize", "Toggle ViaSerialize", [this]() {
        fDrawViaSerialize = !fDrawViaSerialize;
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('!', "SkVM", "Toggle SkVM blitter", [this]() {
        gUseSkVMBlitter = !gUseSkVMBlitter;
        this->updateTitle();
        fWindow->inval();
    });
    fCommands.addCommand('@', "SkVM", "Toggle SkVM JIT", [this]() {
        gSkVMAllowJIT = !gSkVMAllowJIT;
        this->updateTitle();
        fWindow->inval();
    });

    // set up slides
    this->initSlides();
    if (FLAGS_list) {
        this->listNames();
    }

    fPerspectivePoints[0].set(0, 0);
    fPerspectivePoints[1].set(1, 0);
    fPerspectivePoints[2].set(0, 1);
    fPerspectivePoints[3].set(1, 1);
    fAnimTimer.run();

    auto gamutImage = GetResourceAsImage("images/gamut.png");
    if (gamutImage) {
        fImGuiGamutPaint.setShader(gamutImage->makeShader(SkSamplingOptions(SkFilterMode::kLinear)));
    }
    fImGuiGamutPaint.setColor(SK_ColorWHITE);

    fWindow->attach(backend_type_for_window(fBackendType));
    this->setCurrentSlide(this->startupSlide());
}

void Viewer::initSlides() {
    using SlideFactory = sk_sp<Slide>(*)(const SkString& name, const SkString& path);
    static const struct {
        const char*                            fExtension;
        const char*                            fDirName;
        const CommandLineFlags::StringArray&   fFlags;
        const SlideFactory                     fFactory;
    } gExternalSlidesInfo[] = {
        { ".mskp", "mskp-dir", FLAGS_mskps,
          [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
            return sk_make_sp<MSKPSlide>(name, path);}
        },
        { ".skp", "skp-dir", FLAGS_skps,
            [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
                return sk_make_sp<SKPSlide>(name, path);}
        },
        { ".jpg", "jpg-dir", FLAGS_jpgs,
            [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
                return sk_make_sp<ImageSlide>(name, path);}
        },
        { ".jxl", "jxl-dir", FLAGS_jxls,
            [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
                return sk_make_sp<ImageSlide>(name, path);}
        },
#if defined(SK_ENABLE_SKOTTIE)
        { ".json", "skottie-dir", FLAGS_lotties,
            [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
                return sk_make_sp<SkottieSlide>(name, path);}
        },
#endif
#if defined(SK_ENABLE_SVG)
        { ".svg", "svg-dir", FLAGS_svgs,
            [](const SkString& name, const SkString& path) -> sk_sp<Slide> {
                return sk_make_sp<SvgSlide>(name, path);}
        },
#endif
    };

    SkTArray<sk_sp<Slide>> dirSlides;

    const auto addSlide =
            [&](const SkString& name, const SkString& path, const SlideFactory& fact) {
                if (CommandLineFlags::ShouldSkip(FLAGS_match, name.c_str())) {
                    return;
                }

                if (auto slide = fact(name, path)) {
                    dirSlides.push_back(slide);
                    fSlides.push_back(std::move(slide));
                }
            };

    if (!FLAGS_file.isEmpty()) {
        // single file mode
        const SkString file(FLAGS_file[0]);

        if (sk_exists(file.c_str(), kRead_SkFILE_Flag)) {
            for (const auto& sinfo : gExternalSlidesInfo) {
                if (file.endsWith(sinfo.fExtension)) {
                    addSlide(SkOSPath::Basename(file.c_str()), file, sinfo.fFactory);
                    return;
                }
            }

            fprintf(stderr, "Unsupported file type \"%s\"\n", file.c_str());
        } else {
            fprintf(stderr, "Cannot read \"%s\"\n", file.c_str());
        }

        return;
    }

    // Bisect slide.
    if (!FLAGS_bisect.isEmpty()) {
        sk_sp<BisectSlide> bisect = BisectSlide::Create(FLAGS_bisect[0]);
        if (bisect && !CommandLineFlags::ShouldSkip(FLAGS_match, bisect->getName().c_str())) {
            if (FLAGS_bisect.count() >= 2) {
                for (const char* ch = FLAGS_bisect[1]; *ch; ++ch) {
                    bisect->onChar(*ch);
                }
            }
            fSlides.push_back(std::move(bisect));
        }
    }

    // GMs
    int firstGM = fSlides.count();
    for (skiagm::GMFactory gmFactory : skiagm::GMRegistry::Range()) {
        std::unique_ptr<skiagm::GM> gm = gmFactory();
        if (!CommandLineFlags::ShouldSkip(FLAGS_match, gm->getName())) {
            auto slide = sk_make_sp<GMSlide>(std::move(gm));
            fSlides.push_back(std::move(slide));
        }
    }

    auto orderBySlideName = [](sk_sp<Slide> a, sk_sp<Slide> b) {
        return SK_strcasecmp(a->getName().c_str(), b->getName().c_str()) < 0;
    };
    std::sort(fSlides.begin() + firstGM, fSlides.end(), orderBySlideName);

    // samples
    int firstSample = fSlides.count();
    for (const SampleFactory factory : SampleRegistry::Range()) {
        auto slide = sk_make_sp<SampleSlide>(factory);
        if (!CommandLineFlags::ShouldSkip(FLAGS_match, slide->getName().c_str())) {
            fSlides.push_back(slide);
        }
    }

    std::sort(fSlides.begin() + firstSample, fSlides.end(), orderBySlideName);

    // Particle demo
    {
        // TODO: Convert this to a sample
        auto slide = sk_make_sp<ParticlesSlide>();
        if (!CommandLineFlags::ShouldSkip(FLAGS_match, slide->getName().c_str())) {
            fSlides.push_back(std::move(slide));
        }
    }

    // Runtime shader editor
    {
        auto slide = sk_make_sp<SkSLSlide>();
        if (!CommandLineFlags::ShouldSkip(FLAGS_match, slide->getName().c_str())) {
            fSlides.push_back(std::move(slide));
        }
    }

    // Runtime shader debugger
    {
        auto slide = sk_make_sp<SkSLDebuggerSlide>();
        if (!CommandLineFlags::ShouldSkip(FLAGS_match, slide->getName().c_str())) {
            fSlides.push_back(std::move(slide));
        }
    }

    for (const auto& info : gExternalSlidesInfo) {
        for (const auto& flag : info.fFlags) {
            if (SkStrEndsWith(flag.c_str(), info.fExtension)) {
                // single file
                addSlide(SkOSPath::Basename(flag.c_str()), flag, info.fFactory);
            } else {
                // directory
                SkString name;
                SkTArray<SkString> sortedFilenames;
                SkOSFile::Iter it(flag.c_str(), info.fExtension);
                while (it.next(&name)) {
                    sortedFilenames.push_back(name);
                }
                if (sortedFilenames.count()) {
                    SkTQSort(sortedFilenames.begin(), sortedFilenames.end(),
                             [](const SkString& a, const SkString& b) {
                                 return strcmp(a.c_str(), b.c_str()) < 0;
                             });
                }
                for (const SkString& filename : sortedFilenames) {
                    addSlide(filename, SkOSPath::Join(flag.c_str(), filename.c_str()),
                             info.fFactory);
                }
            }
            if (!dirSlides.empty()) {
                fSlides.push_back(
                    sk_make_sp<SlideDir>(SkStringPrintf("%s[%s]", info.fDirName, flag.c_str()),
                                         std::move(dirSlides)));
                dirSlides.reset();  // NOLINT(bugprone-use-after-move)
            }
        }
    }

    if (!fSlides.count()) {
        auto slide = sk_make_sp<NullSlide>();
        fSlides.push_back(std::move(slide));
    }
}


Viewer::~Viewer() {
    for(auto& slide : fSlides) {
        slide->gpuTeardown();
    }

    fWindow->detach();
    delete fWindow;
}

struct SkPaintTitleUpdater {
    SkPaintTitleUpdater(SkString* title) : fTitle(title), fCount(0) {}
    void append(const char* s) {
        if (fCount == 0) {
            fTitle->append(" {");
        } else {
            fTitle->append(", ");
        }
        fTitle->append(s);
        ++fCount;
    }
    void done() {
        if (fCount > 0) {
            fTitle->append("}");
        }
    }
    SkString* fTitle;
    int fCount;
};

void Viewer::updateTitle() {
    if (!fWindow) {
        return;
    }
    if (fWindow->sampleCount() < 1) {
        return; // Surface hasn't been created yet.
    }

    SkString title("Viewer: ");
    title.append(fSlides[fCurrentSlide]->getName());

    if (gSkUseAnalyticAA) {
        if (gSkForceAnalyticAA) {
            title.append(" <FAAA>");
        } else {
            title.append(" <AAA>");
        }
    }
    if (fDrawViaSerialize) {
        title.append(" <serialize>");
    }
    if (gUseSkVMBlitter) {
        title.append(" <SkVMBlitter>");
    }
    if (!gSkVMAllowJIT) {
        title.append(" <SkVM interpreter>");
    }

    SkPaintTitleUpdater paintTitle(&title);
    auto paintFlag = [this, &paintTitle](bool SkPaintFields::* flag,
                                         bool (SkPaint::* isFlag)() const,
                                         const char* on, const char* off)
    {
        if (fPaintOverrides.*flag) {
            paintTitle.append((fPaint.*isFlag)() ? on : off);
        }
    };

    auto fontFlag = [this, &paintTitle](bool SkFontFields::* flag, bool (SkFont::* isFlag)() const,
                                        const char* on, const char* off)
    {
        if (fFontOverrides.*flag) {
            paintTitle.append((fFont.*isFlag)() ? on : off);
        }
    };

    paintFlag(&SkPaintFields::fAntiAlias, &SkPaint::isAntiAlias, "Antialias", "Alias");
    paintFlag(&SkPaintFields::fDither, &SkPaint::isDither, "DITHER", "No Dither");

    fontFlag(&SkFontFields::fForceAutoHinting, &SkFont::isForceAutoHinting,
             "Force Autohint", "No Force Autohint");
    fontFlag(&SkFontFields::fEmbolden, &SkFont::isEmbolden, "Fake Bold", "No Fake Bold");
    fontFlag(&SkFontFields::fBaselineSnap, &SkFont::isBaselineSnap, "BaseSnap", "No BaseSnap");
    fontFlag(&SkFontFields::fLinearMetrics, &SkFont::isLinearMetrics,
             "Linear Metrics", "Non-Linear Metrics");
    fontFlag(&SkFontFields::fEmbeddedBitmaps, &SkFont::isEmbeddedBitmaps,
             "Bitmap Text", "No Bitmap Text");
    fontFlag(&SkFontFields::fSubpixel, &SkFont::isSubpixel, "Subpixel Text", "Pixel Text");

    if (fFontOverrides.fEdging) {
        switch (fFont.getEdging()) {
            case SkFont::Edging::kAlias:
                paintTitle.append("Alias Text");
                break;
            case SkFont::Edging::kAntiAlias:
                paintTitle.append("Antialias Text");
                break;
            case SkFont::Edging::kSubpixelAntiAlias:
                paintTitle.append("Subpixel Antialias Text");
                break;
        }
    }

    if (fFontOverrides.fHinting) {
        switch (fFont.getHinting()) {
            case SkFontHinting::kNone:
                paintTitle.append("No Hinting");
                break;
            case SkFontHinting::kSlight:
                paintTitle.append("Slight Hinting");
                break;
            case SkFontHinting::kNormal:
                paintTitle.append("Normal Hinting");
                break;
            case SkFontHinting::kFull:
                paintTitle.append("Full Hinting");
                break;
        }
    }
    paintTitle.done();

    switch (fColorMode) {
        case ColorMode::kLegacy:
            title.append(" Legacy 8888");
            break;
        case ColorMode::kColorManaged8888:
            title.append(" ColorManaged 8888");
            break;
        case ColorMode::kColorManagedF16:
            title.append(" ColorManaged F16");
            break;
        case ColorMode::kColorManagedF16Norm:
            title.append(" ColorManaged F16 Norm");
            break;
    }

    if (ColorMode::kLegacy != fColorMode) {
        int curPrimaries = -1;
        for (size_t i = 0; i < SK_ARRAY_COUNT(gNamedPrimaries); ++i) {
            if (primaries_equal(*gNamedPrimaries[i].fPrimaries, fColorSpacePrimaries)) {
                curPrimaries = i;
                break;
            }
        }
        title.appendf(" %s Gamma %f",
                      curPrimaries >= 0 ? gNamedPrimaries[curPrimaries].fName : "Custom",
                      fColorSpaceTransferFn.g);
    }

    const DisplayParams& params = fWindow->getRequestedDisplayParams();
    if (fDisplayOverrides.fSurfaceProps.fPixelGeometry) {
        switch (params.fSurfaceProps.pixelGeometry()) {
            case kUnknown_SkPixelGeometry:
                title.append( " Flat");
                break;
            case kRGB_H_SkPixelGeometry:
                title.append( " RGB");
                break;
            case kBGR_H_SkPixelGeometry:
                title.append( " BGR");
                break;
            case kRGB_V_SkPixelGeometry:
                title.append( " RGBV");
                break;
            case kBGR_V_SkPixelGeometry:
                title.append( " BGRV");
                break;
        }
    }

    if (params.fSurfaceProps.isUseDeviceIndependentFonts()) {
        title.append(" DFT");
    }

    title.append(" [");
    title.append(kBackendTypeStrings[fBackendType]);
    int msaa = fWindow->sampleCount();
    if (msaa > 1) {
        title.appendf(" MSAA: %i", msaa);
    }
    title.append("]");

    GpuPathRenderers pr = fWindow->getRequestedDisplayParams().fGrContextOptions.fGpuPathRenderers;
    if (GpuPathRenderers::kDefault != pr) {
        title.appendf(" [Path renderer: %s]", gPathRendererNames[pr].c_str());
    }

    if (kPerspective_Real == fPerspectiveMode) {
        title.append(" Perpsective (Real)");
    } else if (kPerspective_Fake == fPerspectiveMode) {
        title.append(" Perspective (Fake)");
    }

    fWindow->setTitle(title.c_str());
}

int Viewer::startupSlide() const {

    if (!FLAGS_slide.isEmpty()) {
        int count = fSlides.count();
        for (int i = 0; i < count; i++) {
            if (fSlides[i]->getName().equals(FLAGS_slide[0])) {
                return i;
            }
        }

        fprintf(stderr, "Unknown slide \"%s\"\n", FLAGS_slide[0]);
        this->listNames();
    }

    return 0;
}

void Viewer::listNames() const {
    SkDebugf("All Slides:\n");
    for (const auto& slide : fSlides) {
        SkDebugf("    %s\n", slide->getName().c_str());
    }
}

void Viewer::setCurrentSlide(int slide) {
    SkASSERT(slide >= 0 && slide < fSlides.count());

    if (slide == fCurrentSlide) {
        return;
    }

    if (fCurrentSlide >= 0) {
        fSlides[fCurrentSlide]->unload();
    }

    SkScalar scaleFactor = 1.0;
    if (fApplyBackingScale) {
        scaleFactor = fWindow->scaleFactor();
    }
    fSlides[slide]->load(SkIntToScalar(fWindow->width()) / scaleFactor,
                         SkIntToScalar(fWindow->height()) / scaleFactor);
    fCurrentSlide = slide;
    this->setupCurrentSlide();
}

void Viewer::setupCurrentSlide() {
    if (fCurrentSlide >= 0) {
        // prepare dimensions for image slides
        fGesture.resetTouchState();
        fDefaultMatrix.reset();

        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
        const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
        const SkRect windowRect = SkRect::MakeIWH(fWindow->width(), fWindow->height());

        // Start with a matrix that scales the slide to the available screen space
        if (fWindow->scaleContentToFit()) {
            if (windowRect.width() > 0 && windowRect.height() > 0) {
                fDefaultMatrix = SkMatrix::RectToRect(slideBounds, windowRect,
                                                      SkMatrix::kStart_ScaleToFit);
            }
        }

        // Prevent the user from dragging content so far outside the window they can't find it again
        fGesture.setTransLimit(slideBounds, windowRect, this->computePreTouchMatrix());

        this->updateTitle();
        this->updateUIState();

        fStatsLayer.resetMeasurements();

        fWindow->inval();
    }
}

#define MAX_ZOOM_LEVEL  8.0f
#define MIN_ZOOM_LEVEL  -8.0f

void Viewer::changeZoomLevel(float delta) {
    fZoomLevel += delta;
    fZoomLevel = SkTPin(fZoomLevel, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL);
    this->preTouchMatrixChanged();
}

void Viewer::preTouchMatrixChanged() {
    // Update the trans limit as the transform changes.
    const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
    const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
    const SkRect windowRect = SkRect::MakeIWH(fWindow->width(), fWindow->height());
    fGesture.setTransLimit(slideBounds, windowRect, this->computePreTouchMatrix());
}

SkMatrix Viewer::computePerspectiveMatrix() {
    SkScalar w = fWindow->width(), h = fWindow->height();
    SkPoint orthoPts[4] = { { 0, 0 }, { w, 0 }, { 0, h }, { w, h } };
    SkPoint perspPts[4] = {
        { fPerspectivePoints[0].fX * w, fPerspectivePoints[0].fY * h },
        { fPerspectivePoints[1].fX * w, fPerspectivePoints[1].fY * h },
        { fPerspectivePoints[2].fX * w, fPerspectivePoints[2].fY * h },
        { fPerspectivePoints[3].fX * w, fPerspectivePoints[3].fY * h }
    };
    SkMatrix m;
    m.setPolyToPoly(orthoPts, perspPts, 4);
    return m;
}

SkMatrix Viewer::computePreTouchMatrix() {
    SkMatrix m = fDefaultMatrix;

    SkScalar zoomScale = exp(fZoomLevel);
    if (fApplyBackingScale) {
        zoomScale *= fWindow->scaleFactor();
    }
    m.preTranslate((fOffset.x() - 0.5f) * 2.0f, (fOffset.y() - 0.5f) * 2.0f);
    m.preScale(zoomScale, zoomScale);

    const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
    m.preRotate(fRotation, slideSize.width() * 0.5f, slideSize.height() * 0.5f);

    if (kPerspective_Real == fPerspectiveMode) {
        SkMatrix persp = this->computePerspectiveMatrix();
        m.postConcat(persp);
    }

    return m;
}

SkMatrix Viewer::computeMatrix() {
    SkMatrix m = fGesture.localM();
    m.preConcat(fGesture.globalM());
    m.preConcat(this->computePreTouchMatrix());
    return m;
}

void Viewer::setBackend(sk_app::Window::BackendType backendType) {
    fPersistentCache.reset();
    fCachedShaders.reset();
    fBackendType = backendType;

    // The active context is going away in 'detach'
    for(auto& slide : fSlides) {
        slide->gpuTeardown();
    }

    fWindow->detach();

#if defined(SK_BUILD_FOR_WIN)
    // Switching between OpenGL, Vulkan, and ANGLE in the same window is problematic at this point
    // on Windows, so we just delete the window and recreate it.
    DisplayParams params = fWindow->getRequestedDisplayParams();
    delete fWindow;
    fWindow = Window::CreateNativeWindow(nullptr);

    // re-register callbacks
    fCommands.attach(fWindow);
    fWindow->pushLayer(this);
    fWindow->pushLayer(&fStatsLayer);
    fWindow->pushLayer(&fImGuiLayer);

    // Don't allow the window to re-attach. If we're in MSAA mode, the params we grabbed above
    // will still include our correct sample count. But the re-created fWindow will lose that
    // information. On Windows, we need to re-create the window when changing sample count,
    // so we'll incorrectly detect that situation, then re-initialize the window in GL mode,
    // rendering this tear-down step pointless (and causing the Vulkan window context to fail
    // as if we had never changed windows at all).
    fWindow->setRequestedDisplayParams(params, false);
#endif

    fWindow->attach(backend_type_for_window(fBackendType));
}

void Viewer::setColorMode(ColorMode colorMode) {
    fColorMode = colorMode;
    this->updateTitle();
    fWindow->inval();
}

class OveridePaintFilterCanvas : public SkPaintFilterCanvas {
public:
    OveridePaintFilterCanvas(SkCanvas* canvas,
                             SkPaint* paint, Viewer::SkPaintFields* pfields,
                             SkFont* font, Viewer::SkFontFields* ffields)
        : SkPaintFilterCanvas(canvas)
        , fPaint(paint)
        , fPaintOverrides(pfields)
        , fFont(font)
        , fFontOverrides(ffields) {
    }

    const SkTextBlob* filterTextBlob(const SkPaint& paint,
                                     const SkTextBlob* blob,
                                     sk_sp<SkTextBlob>* cache) {
        bool blobWillChange = false;
        for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
            SkTCopyOnFirstWrite<SkFont> filteredFont(it.font());
            bool shouldDraw = this->filterFont(&filteredFont);
            if (it.font() != *filteredFont || !shouldDraw) {
                blobWillChange = true;
                break;
            }
        }
        if (!blobWillChange) {
            return blob;
        }

        SkTextBlobBuilder builder;
        for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
            SkTCopyOnFirstWrite<SkFont> filteredFont(it.font());
            bool shouldDraw = this->filterFont(&filteredFont);
            if (!shouldDraw) {
                continue;
            }

            SkFont font = *filteredFont;

            const SkTextBlobBuilder::RunBuffer& runBuffer
                = it.positioning() == SkTextBlobRunIterator::kDefault_Positioning
                    ? builder.allocRunText(font, it.glyphCount(), it.offset().x(),it.offset().y(),
                                           it.textSize())
                : it.positioning() == SkTextBlobRunIterator::kHorizontal_Positioning
                    ? builder.allocRunTextPosH(font, it.glyphCount(), it.offset().y(),
                                               it.textSize())
                : it.positioning() == SkTextBlobRunIterator::kFull_Positioning
                    ? builder.allocRunTextPos(font, it.glyphCount(), it.textSize())
                : it.positioning() == SkTextBlobRunIterator::kRSXform_Positioning
                    ? builder.allocRunTextRSXform(font, it.glyphCount(), it.textSize())
                : (SkASSERT_RELEASE(false), SkTextBlobBuilder::RunBuffer());
            uint32_t glyphCount = it.glyphCount();
            if (it.glyphs()) {
                size_t glyphSize = sizeof(decltype(*it.glyphs()));
                memcpy(runBuffer.glyphs, it.glyphs(), glyphCount * glyphSize);
            }
            if (it.pos()) {
                size_t posSize = sizeof(decltype(*it.pos()));
                unsigned posPerGlyph = it.scalarsPerGlyph();
                memcpy(runBuffer.pos, it.pos(), glyphCount * posPerGlyph * posSize);
            }
            if (it.text()) {
                size_t textSize = sizeof(decltype(*it.text()));
                uint32_t textCount = it.textSize();
                memcpy(runBuffer.utf8text, it.text(), textCount * textSize);
            }
            if (it.clusters()) {
                size_t clusterSize = sizeof(decltype(*it.clusters()));
                memcpy(runBuffer.clusters, it.clusters(), glyphCount * clusterSize);
            }
        }
        *cache = builder.make();
        return cache->get();
    }
    void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                        const SkPaint& paint) override {
        sk_sp<SkTextBlob> cache;
        this->SkPaintFilterCanvas::onDrawTextBlob(
            this->filterTextBlob(paint, blob, &cache), x, y, paint);
    }

    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override {
        sk_sp<SkTextBlob> cache;
        sk_sp<SkTextBlob> blob = glyphRunList.makeBlob();
        this->filterTextBlob(paint, blob.get(), &cache);
        if (!cache) {
            this->SkPaintFilterCanvas::onDrawGlyphRunList(glyphRunList, paint);
            return;
        }
        SkGlyphRunBuilder builder;
        const SkGlyphRunList& filtered = builder.blobToGlyphRunList(*cache, glyphRunList.origin());
        this->SkPaintFilterCanvas::onDrawGlyphRunList(filtered, paint);
    }

    bool filterFont(SkTCopyOnFirstWrite<SkFont>* font) const {
        if (fFontOverrides->fTypeface) {
            font->writable()->setTypeface(fFont->refTypeface());
        }
        if (fFontOverrides->fSize) {
            font->writable()->setSize(fFont->getSize());
        }
        if (fFontOverrides->fScaleX) {
            font->writable()->setScaleX(fFont->getScaleX());
        }
        if (fFontOverrides->fSkewX) {
            font->writable()->setSkewX(fFont->getSkewX());
        }
        if (fFontOverrides->fHinting) {
            font->writable()->setHinting(fFont->getHinting());
        }
        if (fFontOverrides->fEdging) {
            font->writable()->setEdging(fFont->getEdging());
        }
        if (fFontOverrides->fSubpixel) {
            font->writable()->setSubpixel(fFont->isSubpixel());
        }
        if (fFontOverrides->fForceAutoHinting) {
            font->writable()->setForceAutoHinting(fFont->isForceAutoHinting());
        }
        if (fFontOverrides->fEmbeddedBitmaps) {
            font->writable()->setEmbeddedBitmaps(fFont->isEmbeddedBitmaps());
        }
        if (fFontOverrides->fLinearMetrics) {
            font->writable()->setLinearMetrics(fFont->isLinearMetrics());
        }
        if (fFontOverrides->fEmbolden) {
            font->writable()->setEmbolden(fFont->isEmbolden());
        }
        if (fFontOverrides->fBaselineSnap) {
            font->writable()->setBaselineSnap(fFont->isBaselineSnap());
        }

        return true; // we, currently, never elide a draw
    }

    bool onFilter(SkPaint& paint) const override {
        if (fPaintOverrides->fPathEffect) {
            paint.setPathEffect(fPaint->refPathEffect());
        }
        if (fPaintOverrides->fShader) {
            paint.setShader(fPaint->refShader());
        }
        if (fPaintOverrides->fMaskFilter) {
            paint.setMaskFilter(fPaint->refMaskFilter());
        }
        if (fPaintOverrides->fColorFilter) {
            paint.setColorFilter(fPaint->refColorFilter());
        }
        if (fPaintOverrides->fImageFilter) {
            paint.setImageFilter(fPaint->refImageFilter());
        }
        if (fPaintOverrides->fColor) {
            paint.setColor4f(fPaint->getColor4f());
        }
        if (fPaintOverrides->fStrokeWidth) {
            paint.setStrokeWidth(fPaint->getStrokeWidth());
        }
        if (fPaintOverrides->fMiterLimit) {
            paint.setStrokeMiter(fPaint->getStrokeMiter());
        }
        if (fPaintOverrides->fBlendMode) {
            paint.setBlendMode(fPaint->getBlendMode_or(SkBlendMode::kSrc));
        }
        if (fPaintOverrides->fAntiAlias) {
            paint.setAntiAlias(fPaint->isAntiAlias());
        }
        if (fPaintOverrides->fDither) {
            paint.setDither(fPaint->isDither());
        }
        if (fPaintOverrides->fForceRuntimeBlend) {
            if (std::optional<SkBlendMode> mode = paint.asBlendMode()) {
                paint.setBlender(GetRuntimeBlendForBlendMode(*mode));
            }
        }
        if (fPaintOverrides->fCapType) {
            paint.setStrokeCap(fPaint->getStrokeCap());
        }
        if (fPaintOverrides->fJoinType) {
            paint.setStrokeJoin(fPaint->getStrokeJoin());
        }
        if (fPaintOverrides->fStyle) {
            paint.setStyle(fPaint->getStyle());
        }
        return true; // we, currently, never elide a draw
    }
    SkPaint* fPaint;
    Viewer::SkPaintFields* fPaintOverrides;
    SkFont* fFont;
    Viewer::SkFontFields* fFontOverrides;
};

void Viewer::drawSlide(SkSurface* surface) {
    if (fCurrentSlide < 0) {
        return;
    }

    SkAutoCanvasRestore autorestore(surface->getCanvas(), false);

    // By default, we render directly into the window's surface/canvas
    SkSurface* slideSurface = surface;
    SkCanvas* slideCanvas = surface->getCanvas();
    fLastImage.reset();

    // If we're in any of the color managed modes, construct the color space we're going to use
    sk_sp<SkColorSpace> colorSpace = nullptr;
    if (ColorMode::kLegacy != fColorMode) {
        skcms_Matrix3x3 toXYZ;
        SkAssertResult(fColorSpacePrimaries.toXYZD50(&toXYZ));
        colorSpace = SkColorSpace::MakeRGB(fColorSpaceTransferFn, toXYZ);
    }

    if (fSaveToSKP) {
        SkPictureRecorder recorder;
        SkCanvas* recorderCanvas = recorder.beginRecording(
                SkRect::Make(fSlides[fCurrentSlide]->getDimensions()));
        fSlides[fCurrentSlide]->draw(recorderCanvas);
        sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
        SkFILEWStream stream("sample_app.skp");
        picture->serialize(&stream);
        fSaveToSKP = false;
    }

    // Grab some things we'll need to make surfaces (for tiling or general offscreen rendering)
    SkColorType colorType;
    switch (fColorMode) {
        case ColorMode::kLegacy:
        case ColorMode::kColorManaged8888:
            colorType = kN32_SkColorType;
            break;
        case ColorMode::kColorManagedF16:
            colorType = kRGBA_F16_SkColorType;
            break;
        case ColorMode::kColorManagedF16Norm:
            colorType = kRGBA_F16Norm_SkColorType;
            break;
    }

    auto make_surface = [=](int w, int h) {
        SkSurfaceProps props(fWindow->getRequestedDisplayParams().fSurfaceProps);
        slideCanvas->getProps(&props);

        SkImageInfo info = SkImageInfo::Make(w, h, colorType, kPremul_SkAlphaType, colorSpace);
        return Window::kRaster_BackendType == this->fBackendType
                ? SkSurface::MakeRaster(info, &props)
                : slideCanvas->makeSurface(info, &props);
    };

    // We need to render offscreen if we're...
    // ... in fake perspective or zooming (so we have a snapped copy of the results)
    // ... in any raster mode, because the window surface is actually GL
    // ... in any color managed mode, because we always make the window surface with no color space
    // ... or if the user explicitly requested offscreen rendering
    sk_sp<SkSurface> offscreenSurface = nullptr;
    if (kPerspective_Fake == fPerspectiveMode ||
        fShowZoomWindow ||
        fShowHistogramWindow ||
        Window::kRaster_BackendType == fBackendType ||
        colorSpace != nullptr ||
        FLAGS_offscreen) {

        offscreenSurface = make_surface(fWindow->width(), fWindow->height());
        slideSurface = offscreenSurface.get();
        slideCanvas = offscreenSurface->getCanvas();
    }

    SkPictureRecorder recorder;
    SkCanvas* recorderRestoreCanvas = nullptr;
    if (fDrawViaSerialize) {
        recorderRestoreCanvas = slideCanvas;
        slideCanvas = recorder.beginRecording(
                SkRect::Make(fSlides[fCurrentSlide]->getDimensions()));
    }

    int count = slideCanvas->save();
    slideCanvas->clear(SK_ColorWHITE);
    // Time the painting logic of the slide
    fStatsLayer.beginTiming(fPaintTimer);
    if (fTiled) {
        int tileW = SkScalarCeilToInt(fWindow->width() * fTileScale.width());
        int tileH = SkScalarCeilToInt(fWindow->height() * fTileScale.height());
        for (int y = 0; y < fWindow->height(); y += tileH) {
            for (int x = 0; x < fWindow->width(); x += tileW) {
                SkAutoCanvasRestore acr(slideCanvas, true);
                slideCanvas->clipRect(SkRect::MakeXYWH(x, y, tileW, tileH));
                fSlides[fCurrentSlide]->draw(slideCanvas);
            }
        }

        // Draw borders between tiles
        if (fDrawTileBoundaries) {
            SkPaint border;
            border.setColor(0x60FF00FF);
            border.setStyle(SkPaint::kStroke_Style);
            for (int y = 0; y < fWindow->height(); y += tileH) {
                for (int x = 0; x < fWindow->width(); x += tileW) {
                    slideCanvas->drawRect(SkRect::MakeXYWH(x, y, tileW, tileH), border);
                }
            }
        }
    } else {
        slideCanvas->concat(this->computeMatrix());
        if (kPerspective_Real == fPerspectiveMode) {
            slideCanvas->clipRect(SkRect::MakeWH(fWindow->width(), fWindow->height()));
        }
        if (fPaintOverrides.overridesSomething() || fFontOverrides.overridesSomething()) {
            OveridePaintFilterCanvas filterCanvas(slideCanvas,
                                                  &fPaint, &fPaintOverrides,
                                                  &fFont, &fFontOverrides);
            fSlides[fCurrentSlide]->draw(&filterCanvas);
        } else {
            fSlides[fCurrentSlide]->draw(slideCanvas);
        }
    }
    fStatsLayer.endTiming(fPaintTimer);
    slideCanvas->restoreToCount(count);

    if (recorderRestoreCanvas) {
        sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());
        auto data = picture->serialize();
        slideCanvas = recorderRestoreCanvas;
        slideCanvas->drawPicture(SkPicture::MakeFromData(data.get()));
    }

    // Force a flush so we can time that, too
    fStatsLayer.beginTiming(fFlushTimer);
    slideSurface->flushAndSubmit();
    fStatsLayer.endTiming(fFlushTimer);

    // If we rendered offscreen, snap an image and push the results to the window's canvas
    if (offscreenSurface) {
        fLastImage = offscreenSurface->makeImageSnapshot();

        SkCanvas* canvas = surface->getCanvas();
        SkPaint paint;
        paint.setBlendMode(SkBlendMode::kSrc);
        SkSamplingOptions sampling;
        int prePerspectiveCount = canvas->save();
        if (kPerspective_Fake == fPerspectiveMode) {
            sampling = SkSamplingOptions({1.0f/3, 1.0f/3});
            canvas->clear(SK_ColorWHITE);
            canvas->concat(this->computePerspectiveMatrix());
        }
        canvas->drawImage(fLastImage, 0, 0, sampling, &paint);
        canvas->restoreToCount(prePerspectiveCount);
    }

    if (fShowSlideDimensions) {
        SkCanvas* canvas = surface->getCanvas();
        SkAutoCanvasRestore acr(canvas, true);
        canvas->concat(this->computeMatrix());
        SkRect r = SkRect::Make(fSlides[fCurrentSlide]->getDimensions());
        SkPaint paint;
        paint.setColor(0x40FFFF00);
        canvas->drawRect(r, paint);
    }
}

void Viewer::onBackendCreated() {
    this->setupCurrentSlide();
    fWindow->show();
}

void Viewer::onPaint(SkSurface* surface) {
    this->drawSlide(surface);

    fCommands.drawHelp(surface->getCanvas());

    this->drawImGui();

    fLastImage.reset();

    if (auto direct = fWindow->directContext()) {
        // Clean out cache items that haven't been used in more than 10 seconds.
        direct->performDeferredCleanup(std::chrono::seconds(10));
    }
}

void Viewer::onResize(int width, int height) {
    if (fCurrentSlide >= 0) {
        SkScalar scaleFactor = 1.0;
        if (fApplyBackingScale) {
            scaleFactor = fWindow->scaleFactor();
        }
        fSlides[fCurrentSlide]->resize(width / scaleFactor, height / scaleFactor);
    }
}

SkPoint Viewer::mapEvent(float x, float y) {
    const auto m = this->computeMatrix();
    SkMatrix inv;

    SkAssertResult(m.invert(&inv));

    return inv.mapXY(x, y);
}

bool Viewer::onTouch(intptr_t owner, skui::InputState state, float x, float y) {
    if (GestureDevice::kMouse == fGestureDevice) {
        return false;
    }

    const auto slidePt = this->mapEvent(x, y);
    if (fSlides[fCurrentSlide]->onMouse(slidePt.x(), slidePt.y(), state, skui::ModifierKey::kNone)) {
        fWindow->inval();
        return true;
    }

    void* castedOwner = reinterpret_cast<void*>(owner);
    switch (state) {
        case skui::InputState::kUp: {
            fGesture.touchEnd(castedOwner);
#if defined(SK_BUILD_FOR_IOS)
            // TODO: move IOS swipe detection higher up into the platform code
            SkPoint dir;
            if (fGesture.isFling(&dir)) {
                // swiping left or right
                if (SkTAbs(dir.fX) > SkTAbs(dir.fY)) {
                    if (dir.fX < 0) {
                        this->setCurrentSlide(fCurrentSlide < fSlides.count() - 1 ?
                                              fCurrentSlide + 1 : 0);
                    } else {
                        this->setCurrentSlide(fCurrentSlide > 0 ?
                                              fCurrentSlide - 1 : fSlides.count() - 1);
                    }
                }
                fGesture.reset();
            }
#endif
            break;
        }
        case skui::InputState::kDown: {
            fGesture.touchBegin(castedOwner, x, y);
            break;
        }
        case skui::InputState::kMove: {
            fGesture.touchMoved(castedOwner, x, y);
            break;
        }
        default: {
            // kLeft and kRight are only for swipes
            SkASSERT(false);
            break;
        }
    }
    fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kTouch : GestureDevice::kNone;
    fWindow->inval();
    return true;
}

bool Viewer::onMouse(int x, int y, skui::InputState state, skui::ModifierKey modifiers) {
    if (GestureDevice::kTouch == fGestureDevice) {
        return false;
    }

    const auto slidePt = this->mapEvent(x, y);
    if (fSlides[fCurrentSlide]->onMouse(slidePt.x(), slidePt.y(), state, modifiers)) {
        fWindow->inval();
        return true;
    }

    switch (state) {
        case skui::InputState::kUp: {
            fGesture.touchEnd(nullptr);
            break;
        }
        case skui::InputState::kDown: {
            fGesture.touchBegin(nullptr, x, y);
            break;
        }
        case skui::InputState::kMove: {
            fGesture.touchMoved(nullptr, x, y);
            break;
        }
        default: {
            SkASSERT(false); // shouldn't see kRight or kLeft here
            break;
        }
    }
    fGestureDevice = fGesture.isBeingTouched() ? GestureDevice::kMouse : GestureDevice::kNone;

    if (state != skui::InputState::kMove || fGesture.isBeingTouched()) {
        fWindow->inval();
    }
    return true;
}

bool Viewer::onFling(skui::InputState state) {
    if (skui::InputState::kRight == state) {
        this->setCurrentSlide(fCurrentSlide > 0 ? fCurrentSlide - 1 : fSlides.count() - 1);
        return true;
    } else if (skui::InputState::kLeft == state) {
        this->setCurrentSlide(fCurrentSlide < fSlides.count() - 1 ? fCurrentSlide + 1 : 0);
        return true;
    }
    return false;
}

bool Viewer::onPinch(skui::InputState state, float scale, float x, float y) {
    switch (state) {
        case skui::InputState::kDown:
            fGesture.startZoom();
            return true;
            break;
        case skui::InputState::kMove:
            fGesture.updateZoom(scale, x, y, x, y);
            return true;
            break;
        case skui::InputState::kUp:
            fGesture.endZoom();
            return true;
            break;
        default:
            SkASSERT(false);
            break;
    }

    return false;
}

static void ImGui_Primaries(SkColorSpacePrimaries* primaries, SkPaint* gamutPaint) {
    // The gamut image covers a (0.8 x 0.9) shaped region
    ImGui::DragCanvas dc(primaries, { 0.0f, 0.9f }, { 0.8f, 0.0f });

    // Background image. Only draw a subset of the image, to avoid the regions less than zero.
    // Simplifes re-mapping math, clipping behavior, and increases resolution in the useful area.
    // Magic numbers are pixel locations of the origin and upper-right corner.
    dc.fDrawList->AddImage(gamutPaint, dc.fPos,
                           ImVec2(dc.fPos.x + dc.fSize.x, dc.fPos.y + dc.fSize.y),
                           ImVec2(242, 61), ImVec2(1897, 1922));

    dc.dragPoint((SkPoint*)(&primaries->fRX), true, 0xFF000040);
    dc.dragPoint((SkPoint*)(&primaries->fGX), true, 0xFF004000);
    dc.dragPoint((SkPoint*)(&primaries->fBX), true, 0xFF400000);
    dc.dragPoint((SkPoint*)(&primaries->fWX), true);
    dc.fDrawList->AddPolyline(dc.fScreenPoints.begin(), 3, 0xFFFFFFFF, true, 1.5f);
}

static bool ImGui_DragLocation(SkPoint* pt) {
    ImGui::DragCanvas dc(pt);
    dc.fillColor(IM_COL32(0, 0, 0, 128));
    dc.dragPoint(pt);
    return dc.fDragging;
}

static bool ImGui_DragQuad(SkPoint* pts) {
    ImGui::DragCanvas dc(pts);
    dc.fillColor(IM_COL32(0, 0, 0, 128));

    for (int i = 0; i < 4; ++i) {
        dc.dragPoint(pts + i);
    }

    dc.fDrawList->AddLine(dc.fScreenPoints[0], dc.fScreenPoints[1], 0xFFFFFFFF);
    dc.fDrawList->AddLine(dc.fScreenPoints[1], dc.fScreenPoints[3], 0xFFFFFFFF);
    dc.fDrawList->AddLine(dc.fScreenPoints[3], dc.fScreenPoints[2], 0xFFFFFFFF);
    dc.fDrawList->AddLine(dc.fScreenPoints[2], dc.fScreenPoints[0], 0xFFFFFFFF);

    return dc.fDragging;
}

static std::string build_sksl_highlight_shader() {
    return std::string("out half4 sk_FragColor;\n"
                        "void main() { sk_FragColor = half4(1, 0, 1, 0.5); }");
}

static std::string build_metal_highlight_shader(const std::string& inShader) {
    // Metal fragment shaders need a lot of non-trivial boilerplate that we don't want to recompute
    // here. So keep all shader code, but right before `return *_out;`, swap out the sk_FragColor.
    size_t pos = inShader.rfind("return *_out;\n");
    if (pos == std::string::npos) {
        return inShader;
    }

    std::string replacementShader = inShader;
    replacementShader.insert(pos, "_out->sk_FragColor = float4(1.0, 0.0, 1.0, 0.5); ");
    return replacementShader;
}

static std::string build_glsl_highlight_shader(const GrShaderCaps& shaderCaps) {
    const char* versionDecl = shaderCaps.versionDeclString();
    std::string highlight = versionDecl ? versionDecl : "";
    if (shaderCaps.usesPrecisionModifiers()) {
        highlight.append("precision mediump float;\n");
    }
    SkSL::String::appendf(&highlight, "out vec4 sk_FragColor;\n"
                                      "void main() { sk_FragColor = vec4(1, 0, 1, 0.5); }");
    return highlight;
}

static skvm::Program build_skvm_highlight_program(SkColorType ct, int nargs) {
    // Code here is heavily tied to (and inspired by) SkVMBlitter::BuildProgram
    skvm::Builder b;

    // All VM blitters start with two arguments (uniforms, dst surface)
    SkASSERT(nargs >= 2);
    (void)b.uniform();
    skvm::Ptr dst_ptr = b.varying(SkColorTypeBytesPerPixel(ct));

    // Depending on coverage and shader, there can be additional arguments.
    // Make sure that we append the right number, so that we don't assert when
    // the CPU backend tries to run this program.
    for (int i = 2; i < nargs; ++i) {
        (void)b.uniform();
    }

    skvm::Color magenta = {b.splat(1.0f), b.splat(0.0f), b.splat(1.0f), b.splat(0.5f)};
    skvm::PixelFormat dstFormat = skvm::SkColorType_to_PixelFormat(ct);
    store(dstFormat, dst_ptr, magenta);

    return b.done();
}

void Viewer::drawImGui() {
    // Support drawing the ImGui demo window. Superfluous, but gives a good idea of what's possible
    if (fShowImGuiTestWindow) {
        ImGui::ShowDemoWindow(&fShowImGuiTestWindow);
    }

    if (fShowImGuiDebugWindow) {
        // We have some dynamic content that sizes to fill available size. If the scroll bar isn't
        // always visible, we can end up in a layout feedback loop.
        ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
        DisplayParams params = fWindow->getRequestedDisplayParams();
        bool displayParamsChanged = false; // heavy-weight, might recreate entire context
        bool uiParamsChanged = false;      // light weight, just triggers window invalidation
        auto ctx = fWindow->directContext();

        if (ImGui::Begin("Tools", &fShowImGuiDebugWindow,
                         ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
            if (ImGui::CollapsingHeader("Backend")) {
                int newBackend = static_cast<int>(fBackendType);
                ImGui::RadioButton("Raster", &newBackend, sk_app::Window::kRaster_BackendType);
                ImGui::SameLine();
                ImGui::RadioButton("OpenGL", &newBackend, sk_app::Window::kNativeGL_BackendType);
#if SK_ANGLE && defined(SK_BUILD_FOR_WIN)
                ImGui::SameLine();
                ImGui::RadioButton("ANGLE", &newBackend, sk_app::Window::kANGLE_BackendType);
#endif
#if defined(SK_DAWN)
                ImGui::SameLine();
                ImGui::RadioButton("Dawn", &newBackend, sk_app::Window::kDawn_BackendType);
#endif
#if defined(SK_VULKAN) && !defined(SK_BUILD_FOR_MAC)
                ImGui::SameLine();
                ImGui::RadioButton("Vulkan", &newBackend, sk_app::Window::kVulkan_BackendType);
#endif
#if defined(SK_METAL)
                ImGui::SameLine();
                ImGui::RadioButton("Metal", &newBackend, sk_app::Window::kMetal_BackendType);
#if defined(SK_GRAPHITE_ENABLED)
                ImGui::SameLine();
                ImGui::RadioButton("Metal (Graphite)", &newBackend,
                                   sk_app::Window::kGraphiteMetal_BackendType);
#endif
#endif
#if defined(SK_DIRECT3D)
                ImGui::SameLine();
                ImGui::RadioButton("Direct3D", &newBackend, sk_app::Window::kDirect3D_BackendType);
#endif
                if (newBackend != fBackendType) {
                    fDeferredActions.push_back([=]() {
                        this->setBackend(static_cast<sk_app::Window::BackendType>(newBackend));
                    });
                }

                bool* wire = &params.fGrContextOptions.fWireframeMode;
                if (ctx && ImGui::Checkbox("Wireframe Mode", wire)) {
                    displayParamsChanged = true;
                }

                bool* reducedShaders = &params.fGrContextOptions.fReducedShaderVariations;
                if (ctx && ImGui::Checkbox("Reduced shaders", reducedShaders)) {
                    displayParamsChanged = true;
                }

                if (ctx) {
                    // Determine the context's max sample count for MSAA radio buttons.
                    int sampleCount = fWindow->sampleCount();
                    int maxMSAA = (fBackendType != sk_app::Window::kRaster_BackendType) ?
                            ctx->maxSurfaceSampleCountForColorType(kRGBA_8888_SkColorType) :
                            1;

                    // Only display the MSAA radio buttons when there are options above 1x MSAA.
                    if (maxMSAA >= 4) {
                        ImGui::Text("MSAA: ");

                        for (int curMSAA = 1; curMSAA <= maxMSAA; curMSAA *= 2) {
                            // 2x MSAA works, but doesn't offer much of a visual improvement, so we
                            // don't show it in the list.
                            if (curMSAA == 2) {
                                continue;
                            }
                            ImGui::SameLine();
                            ImGui::RadioButton(SkStringPrintf("%d", curMSAA).c_str(),
                                               &sampleCount, curMSAA);
                        }
                    }

                    if (sampleCount != params.fMSAASampleCount) {
                        params.fMSAASampleCount = sampleCount;
                        displayParamsChanged = true;
                    }
                }

                int pixelGeometryIdx = 0;
                if (fDisplayOverrides.fSurfaceProps.fPixelGeometry) {
                    pixelGeometryIdx = params.fSurfaceProps.pixelGeometry() + 1;
                }
                if (ImGui::Combo("Pixel Geometry", &pixelGeometryIdx,
                                 "Default\0Flat\0RGB\0BGR\0RGBV\0BGRV\0\0"))
                {
                    uint32_t flags = params.fSurfaceProps.flags();
                    if (pixelGeometryIdx == 0) {
                        fDisplayOverrides.fSurfaceProps.fPixelGeometry = false;
                        SkPixelGeometry pixelGeometry = fDisplay.fSurfaceProps.pixelGeometry();
                        params.fSurfaceProps = SkSurfaceProps(flags, pixelGeometry);
                    } else {
                        fDisplayOverrides.fSurfaceProps.fPixelGeometry = true;
                        SkPixelGeometry pixelGeometry = SkTo<SkPixelGeometry>(pixelGeometryIdx - 1);
                        params.fSurfaceProps = SkSurfaceProps(flags, pixelGeometry);
                    }
                    displayParamsChanged = true;
                }

                bool useDFT = params.fSurfaceProps.isUseDeviceIndependentFonts();
                if (ImGui::Checkbox("DFT", &useDFT)) {
                    uint32_t flags = params.fSurfaceProps.flags();
                    if (useDFT) {
                        flags |= SkSurfaceProps::kUseDeviceIndependentFonts_Flag;
                    } else {
                        flags &= ~SkSurfaceProps::kUseDeviceIndependentFonts_Flag;
                    }
                    SkPixelGeometry pixelGeometry = params.fSurfaceProps.pixelGeometry();
                    params.fSurfaceProps = SkSurfaceProps(flags, pixelGeometry);
                    displayParamsChanged = true;
                }

                if (ImGui::TreeNode("Path Renderers")) {
                    GpuPathRenderers prevPr = params.fGrContextOptions.fGpuPathRenderers;
                    auto prButton = [&](GpuPathRenderers x) {
                        if (ImGui::RadioButton(gPathRendererNames[x].c_str(), prevPr == x)) {
                            if (x != params.fGrContextOptions.fGpuPathRenderers) {
                                params.fGrContextOptions.fGpuPathRenderers = x;
                                displayParamsChanged = true;
                            }
                        }
                    };

                    if (!ctx) {
                        ImGui::RadioButton("Software", true);
                    } else {
                        prButton(GpuPathRenderers::kDefault);
#if SK_GPU_V1
                        if (fWindow->sampleCount() > 1 || FLAGS_dmsaa) {
                            const auto* caps = ctx->priv().caps();
                            if (skgpu::v1::AtlasPathRenderer::IsSupported(ctx)) {
                                prButton(GpuPathRenderers::kAtlas);
                            }
                            if (skgpu::v1::TessellationPathRenderer::IsSupported(*caps)) {
                                prButton(GpuPathRenderers::kTessellation);
                            }
                        }
#endif
                        if (1 == fWindow->sampleCount()) {
                            prButton(GpuPathRenderers::kSmall);
                        }
                        prButton(GpuPathRenderers::kTriangulating);
                        prButton(GpuPathRenderers::kNone);
                    }
                    ImGui::TreePop();
                }
            }

            if (ImGui::CollapsingHeader("Tiling")) {
                ImGui::Checkbox("Enable", &fTiled);
                ImGui::Checkbox("Draw Boundaries", &fDrawTileBoundaries);
                ImGui::SliderFloat("Horizontal", &fTileScale.fWidth, 0.1f, 1.0f);
                ImGui::SliderFloat("Vertical", &fTileScale.fHeight, 0.1f, 1.0f);
            }

            if (ImGui::CollapsingHeader("Transform")) {
                if (ImGui::Checkbox("Apply Backing Scale", &fApplyBackingScale)) {
                    this->preTouchMatrixChanged();
                    this->onResize(fWindow->width(), fWindow->height());
                    // This changes how we manipulate the canvas transform, it's not changing the
                    // window's actual parameters.
                    uiParamsChanged = true;
                }

                float zoom = fZoomLevel;
                if (ImGui::SliderFloat("Zoom", &zoom, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL)) {
                    fZoomLevel = zoom;
                    this->preTouchMatrixChanged();
                    uiParamsChanged = true;
                }
                float deg = fRotation;
                if (ImGui::SliderFloat("Rotate", &deg, -30, 360, "%.3f deg")) {
                    fRotation = deg;
                    this->preTouchMatrixChanged();
                    uiParamsChanged = true;
                }
                if (ImGui::CollapsingHeader("Subpixel offset", ImGuiTreeNodeFlags_NoTreePushOnOpen)) {
                    if (ImGui_DragLocation(&fOffset)) {
                        this->preTouchMatrixChanged();
                        uiParamsChanged = true;
                    }
                } else if (fOffset != SkVector{0.5f, 0.5f}) {
                    this->preTouchMatrixChanged();
                    uiParamsChanged = true;
                    fOffset = {0.5f, 0.5f};
                }
                int perspectiveMode = static_cast<int>(fPerspectiveMode);
                if (ImGui::Combo("Perspective", &perspectiveMode, "Off\0Real\0Fake\0\0")) {
                    fPerspectiveMode = static_cast<PerspectiveMode>(perspectiveMode);
                    this->preTouchMatrixChanged();
                    uiParamsChanged = true;
                }
                if (perspectiveMode != kPerspective_Off && ImGui_DragQuad(fPerspectivePoints)) {
                    this->preTouchMatrixChanged();
                    uiParamsChanged = true;
                }
            }

            if (ImGui::CollapsingHeader("Paint")) {
                int aliasIdx = 0;
                if (fPaintOverrides.fAntiAlias) {
                    aliasIdx = SkTo<int>(fPaintOverrides.fAntiAliasState) + 1;
                }
                if (ImGui::Combo("Anti-Alias", &aliasIdx,
                                 "Default\0Alias\0Normal\0AnalyticAAEnabled\0AnalyticAAForced\0\0"))
                {
                    gSkUseAnalyticAA = fPaintOverrides.fOriginalSkUseAnalyticAA;
                    gSkForceAnalyticAA = fPaintOverrides.fOriginalSkForceAnalyticAA;
                    if (aliasIdx == 0) {
                        fPaintOverrides.fAntiAliasState = SkPaintFields::AntiAliasState::Alias;
                        fPaintOverrides.fAntiAlias = false;
                    } else {
                        fPaintOverrides.fAntiAlias = true;
                        fPaintOverrides.fAntiAliasState = SkTo<SkPaintFields::AntiAliasState>(aliasIdx-1);
                        fPaint.setAntiAlias(aliasIdx > 1);
                        switch (fPaintOverrides.fAntiAliasState) {
                            case SkPaintFields::AntiAliasState::Alias:
                                break;
                            case SkPaintFields::AntiAliasState::Normal:
                                break;
                            case SkPaintFields::AntiAliasState::AnalyticAAEnabled:
                                gSkUseAnalyticAA = true;
                                gSkForceAnalyticAA = false;
                                break;
                            case SkPaintFields::AntiAliasState::AnalyticAAForced:
                                gSkUseAnalyticAA = gSkForceAnalyticAA = true;
                                break;
                        }
                    }
                    uiParamsChanged = true;
                }

                auto paintFlag = [this, &uiParamsChanged](const char* label, const char* items,
                                                          bool SkPaintFields::* flag,
                                                          bool (SkPaint::* isFlag)() const,
                                                          void (SkPaint::* setFlag)(bool) )
                {
                    int itemIndex = 0;
                    if (fPaintOverrides.*flag) {
                        itemIndex = (fPaint.*isFlag)() ? 2 : 1;
                    }
                    if (ImGui::Combo(label, &itemIndex, items)) {
                        if (itemIndex == 0) {
                            fPaintOverrides.*flag = false;
                        } else {
                            fPaintOverrides.*flag = true;
                            (fPaint.*setFlag)(itemIndex == 2);
                        }
                        uiParamsChanged = true;
                    }
                };

                paintFlag("Dither",
                          "Default\0No Dither\0Dither\0\0",
                          &SkPaintFields::fDither,
                          &SkPaint::isDither, &SkPaint::setDither);

                int styleIdx = 0;
                if (fPaintOverrides.fStyle) {
                    styleIdx = SkTo<int>(fPaint.getStyle()) + 1;
                }
                if (ImGui::Combo("Style", &styleIdx,
                                 "Default\0Fill\0Stroke\0Stroke and Fill\0\0"))
                {
                    if (styleIdx == 0) {
                        fPaintOverrides.fStyle = false;
                        fPaint.setStyle(SkPaint::kFill_Style);
                    } else {
                        fPaint.setStyle(SkTo<SkPaint::Style>(styleIdx - 1));
                        fPaintOverrides.fStyle = true;
                    }
                    uiParamsChanged = true;
                }

                ImGui::Checkbox("Force Runtime Blends", &fPaintOverrides.fForceRuntimeBlend);

                ImGui::Checkbox("Override Stroke Width", &fPaintOverrides.fStrokeWidth);
                if (fPaintOverrides.fStrokeWidth) {
                    float width = fPaint.getStrokeWidth();
                    if (ImGui::SliderFloat("Stroke Width", &width, 0, 20)) {
                        fPaint.setStrokeWidth(width);
                        uiParamsChanged = true;
                    }
                }

                ImGui::Checkbox("Override Miter Limit", &fPaintOverrides.fMiterLimit);
                if (fPaintOverrides.fMiterLimit) {
                    float miterLimit = fPaint.getStrokeMiter();
                    if (ImGui::SliderFloat("Miter Limit", &miterLimit, 0, 20)) {
                        fPaint.setStrokeMiter(miterLimit);
                        uiParamsChanged = true;
                    }
                }

                int capIdx = 0;
                if (fPaintOverrides.fCapType) {
                    capIdx = SkTo<int>(fPaint.getStrokeCap()) + 1;
                }
                if (ImGui::Combo("Cap Type", &capIdx,
                                 "Default\0Butt\0Round\0Square\0\0"))
                {
                    if (capIdx == 0) {
                        fPaintOverrides.fCapType = false;
                        fPaint.setStrokeCap(SkPaint::kDefault_Cap);
                    } else {
                        fPaint.setStrokeCap(SkTo<SkPaint::Cap>(capIdx - 1));
                        fPaintOverrides.fCapType = true;
                    }
                    uiParamsChanged = true;
                }

                int joinIdx = 0;
                if (fPaintOverrides.fJoinType) {
                    joinIdx = SkTo<int>(fPaint.getStrokeJoin()) + 1;
                }
                if (ImGui::Combo("Join Type", &joinIdx,
                                 "Default\0Miter\0Round\0Bevel\0\0"))
                {
                    if (joinIdx == 0) {
                        fPaintOverrides.fJoinType = false;
                        fPaint.setStrokeJoin(SkPaint::kDefault_Join);
                    } else {
                        fPaint.setStrokeJoin(SkTo<SkPaint::Join>(joinIdx - 1));
                        fPaintOverrides.fJoinType = true;
                    }
                    uiParamsChanged = true;
                }
            }

            if (ImGui::CollapsingHeader("Font")) {
                int hintingIdx = 0;
                if (fFontOverrides.fHinting) {
                    hintingIdx = SkTo<int>(fFont.getHinting()) + 1;
                }
                if (ImGui::Combo("Hinting", &hintingIdx,
                                 "Default\0None\0Slight\0Normal\0Full\0\0"))
                {
                    if (hintingIdx == 0) {
                        fFontOverrides.fHinting = false;
                        fFont.setHinting(SkFontHinting::kNone);
                    } else {
                        fFont.setHinting(SkTo<SkFontHinting>(hintingIdx - 1));
                        fFontOverrides.fHinting = true;
                    }
                    uiParamsChanged = true;
                }

                auto fontFlag = [this, &uiParamsChanged](const char* label, const char* items,
                                                        bool SkFontFields::* flag,
                                                        bool (SkFont::* isFlag)() const,
                                                        void (SkFont::* setFlag)(bool) )
                {
                    int itemIndex = 0;
                    if (fFontOverrides.*flag) {
                        itemIndex = (fFont.*isFlag)() ? 2 : 1;
                    }
                    if (ImGui::Combo(label, &itemIndex, items)) {
                        if (itemIndex == 0) {
                            fFontOverrides.*flag = false;
                        } else {
                            fFontOverrides.*flag = true;
                            (fFont.*setFlag)(itemIndex == 2);
                        }
                        uiParamsChanged = true;
                    }
                };

                fontFlag("Fake Bold Glyphs",
                         "Default\0No Fake Bold\0Fake Bold\0\0",
                         &SkFontFields::fEmbolden,
                         &SkFont::isEmbolden, &SkFont::setEmbolden);

                fontFlag("Baseline Snapping",
                         "Default\0No Baseline Snapping\0Baseline Snapping\0\0",
                         &SkFontFields::fBaselineSnap,
                         &SkFont::isBaselineSnap, &SkFont::setBaselineSnap);

                fontFlag("Linear Text",
                         "Default\0No Linear Text\0Linear Text\0\0",
                         &SkFontFields::fLinearMetrics,
                         &SkFont::isLinearMetrics, &SkFont::setLinearMetrics);

                fontFlag("Subpixel Position Glyphs",
                         "Default\0Pixel Text\0Subpixel Text\0\0",
                         &SkFontFields::fSubpixel,
                         &SkFont::isSubpixel, &SkFont::setSubpixel);

                fontFlag("Embedded Bitmap Text",
                         "Default\0No Embedded Bitmaps\0Embedded Bitmaps\0\0",
                         &SkFontFields::fEmbeddedBitmaps,
                         &SkFont::isEmbeddedBitmaps, &SkFont::setEmbeddedBitmaps);

                fontFlag("Force Auto-Hinting",
                         "Default\0No Force Auto-Hinting\0Force Auto-Hinting\0\0",
                         &SkFontFields::fForceAutoHinting,
                         &SkFont::isForceAutoHinting, &SkFont::setForceAutoHinting);

                int edgingIdx = 0;
                if (fFontOverrides.fEdging) {
                    edgingIdx = SkTo<int>(fFont.getEdging()) + 1;
                }
                if (ImGui::Combo("Edging", &edgingIdx,
                                 "Default\0Alias\0Antialias\0Subpixel Antialias\0\0"))
                {
                    if (edgingIdx == 0) {
                        fFontOverrides.fEdging = false;
                        fFont.setEdging(SkFont::Edging::kAlias);
                    } else {
                        fFont.setEdging(SkTo<SkFont::Edging>(edgingIdx-1));
                        fFontOverrides.fEdging = true;
                    }
                    uiParamsChanged = true;
                }

                ImGui::Checkbox("Override Size", &fFontOverrides.fSize);
                if (fFontOverrides.fSize) {
                    ImGui::DragFloat2("TextRange", fFontOverrides.fSizeRange,
                                      0.001f, -10.0f, 300.0f, "%.6f", ImGuiSliderFlags_Logarithmic);
                    float textSize = fFont.getSize();
                    if (ImGui::DragFloat("TextSize", &textSize, 0.001f,
                                         fFontOverrides.fSizeRange[0],
                                         fFontOverrides.fSizeRange[1],
                                         "%.6f", ImGuiSliderFlags_Logarithmic))
                    {
                        fFont.setSize(textSize);
                        uiParamsChanged = true;
                    }
                }

                ImGui::Checkbox("Override ScaleX", &fFontOverrides.fScaleX);
                if (fFontOverrides.fScaleX) {
                    float scaleX = fFont.getScaleX();
                    if (ImGui::SliderFloat("ScaleX", &scaleX, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL)) {
                        fFont.setScaleX(scaleX);
                        uiParamsChanged = true;
                    }
                }

                ImGui::Checkbox("Override SkewX", &fFontOverrides.fSkewX);
                if (fFontOverrides.fSkewX) {
                    float skewX = fFont.getSkewX();
                    if (ImGui::SliderFloat("SkewX", &skewX, MIN_ZOOM_LEVEL, MAX_ZOOM_LEVEL)) {
                        fFont.setSkewX(skewX);
                        uiParamsChanged = true;
                    }
                }
            }

            {
                SkMetaData controls;
                if (fSlides[fCurrentSlide]->onGetControls(&controls)) {
                    if (ImGui::CollapsingHeader("Current Slide")) {
                        SkMetaData::Iter iter(controls);
                        const char* name;
                        SkMetaData::Type type;
                        int count;
                        while ((name = iter.next(&type, &count)) != nullptr) {
                            if (type == SkMetaData::kScalar_Type) {
                                float val[3];
                                SkASSERT(count == 3);
                                controls.findScalars(name, &count, val);
                                if (ImGui::SliderFloat(name, &val[0], val[1], val[2])) {
                                    controls.setScalars(name, 3, val);
                                }
                            } else if (type == SkMetaData::kBool_Type) {
                                bool val;
                                SkASSERT(count == 1);
                                controls.findBool(name, &val);
                                if (ImGui::Checkbox(name, &val)) {
                                    controls.setBool(name, val);
                                }
                            }
                        }
                        fSlides[fCurrentSlide]->onSetControls(controls);
                    }
                }
            }

            if (fShowSlidePicker) {
                ImGui::SetNextTreeNodeOpen(true);
            }
            if (ImGui::CollapsingHeader("Slide")) {
                static ImGuiTextFilter filter;
                static ImVector<const char*> filteredSlideNames;
                static ImVector<int> filteredSlideIndices;

                if (fShowSlidePicker) {
                    ImGui::SetKeyboardFocusHere();
                    fShowSlidePicker = false;
                }

                filter.Draw();
                filteredSlideNames.clear();
                filteredSlideIndices.clear();
                int filteredIndex = 0;
                for (int i = 0; i < fSlides.count(); ++i) {
                    const char* slideName = fSlides[i]->getName().c_str();
                    if (filter.PassFilter(slideName) || i == fCurrentSlide) {
                        if (i == fCurrentSlide) {
                            filteredIndex = filteredSlideIndices.size();
                        }
                        filteredSlideNames.push_back(slideName);
                        filteredSlideIndices.push_back(i);
                    }
                }

                if (ImGui::ListBox("", &filteredIndex, filteredSlideNames.begin(),
                                   filteredSlideNames.size(), 20)) {
                    this->setCurrentSlide(filteredSlideIndices[filteredIndex]);
                }
            }

            if (ImGui::CollapsingHeader("Color Mode")) {
                ColorMode newMode = fColorMode;
                auto cmButton = [&](ColorMode mode, const char* label) {
                    if (ImGui::RadioButton(label, mode == fColorMode)) {
                        newMode = mode;
                    }
                };

                cmButton(ColorMode::kLegacy, "Legacy 8888");
                cmButton(ColorMode::kColorManaged8888, "Color Managed 8888");
                cmButton(ColorMode::kColorManagedF16, "Color Managed F16");
                cmButton(ColorMode::kColorManagedF16Norm, "Color Managed F16 Norm");

                if (newMode != fColorMode) {
                    this->setColorMode(newMode);
                }

                // Pick from common gamuts:
                int primariesIdx = 4; // Default: Custom
                for (size_t i = 0; i < SK_ARRAY_COUNT(gNamedPrimaries); ++i) {
                    if (primaries_equal(*gNamedPrimaries[i].fPrimaries, fColorSpacePrimaries)) {
                        primariesIdx = i;
                        break;
                    }
                }

                // Let user adjust the gamma
                ImGui::SliderFloat("Gamma", &fColorSpaceTransferFn.g, 0.5f, 3.5f);

                if (ImGui::Combo("Primaries", &primariesIdx,
                                 "sRGB\0AdobeRGB\0P3\0Rec. 2020\0Custom\0\0")) {
                    if (primariesIdx >= 0 && primariesIdx <= 3) {
                        fColorSpacePrimaries = *gNamedPrimaries[primariesIdx].fPrimaries;
                    }
                }

                if (ImGui::Button("Spin")) {
                    float rx = fColorSpacePrimaries.fRX,
                          ry = fColorSpacePrimaries.fRY;
                    fColorSpacePrimaries.fRX = fColorSpacePrimaries.fGX;
                    fColorSpacePrimaries.fRY = fColorSpacePrimaries.fGY;
                    fColorSpacePrimaries.fGX = fColorSpacePrimaries.fBX;
                    fColorSpacePrimaries.fGY = fColorSpacePrimaries.fBY;
                    fColorSpacePrimaries.fBX = rx;
                    fColorSpacePrimaries.fBY = ry;
                }

                // Allow direct editing of gamut
                ImGui_Primaries(&fColorSpacePrimaries, &fImGuiGamutPaint);
            }

            if (ImGui::CollapsingHeader("Animation")) {
                bool isPaused = AnimTimer::kPaused_State == fAnimTimer.state();
                if (ImGui::Checkbox("Pause", &isPaused)) {
                    fAnimTimer.togglePauseResume();
                }

                float speed = fAnimTimer.getSpeed();
                if (ImGui::DragFloat("Speed", &speed, 0.1f)) {
                    fAnimTimer.setSpeed(speed);
                }
            }

            if (ImGui::CollapsingHeader("Shaders")) {
                bool sksl = params.fGrContextOptions.fShaderCacheStrategy ==
                            GrContextOptions::ShaderCacheStrategy::kSkSL;

#if defined(SK_VULKAN)
                const bool isVulkan = fBackendType == sk_app::Window::kVulkan_BackendType;
#else
                const bool isVulkan = false;
#endif

                // To re-load shaders from the currently active programs, we flush all
                // caches on one frame, then set a flag to poll the cache on the next frame.
                static bool gLoadPending = false;
                if (gLoadPending) {
                    auto collectShaders = [this](sk_sp<const SkData> key, sk_sp<SkData> data,
                                                 const SkString& description, int hitCount) {
                        CachedShader& entry(fCachedShaders.push_back());
                        entry.fKey = key;
                        SkMD5 hash;
                        hash.write(key->bytes(), key->size());
                        SkMD5::Digest digest = hash.finish();
                        for (int i = 0; i < 16; ++i) {
                            entry.fKeyString.appendf("%02x", digest.data[i]);
                        }
                        entry.fKeyDescription = description;

                        SkReadBuffer reader(data->data(), data->size());
                        entry.fShaderType = GrPersistentCacheUtils::GetType(&reader);
                        GrPersistentCacheUtils::UnpackCachedShaders(&reader, entry.fShader,
                                                                    entry.fInputs,
                                                                    kGrShaderTypeCount);
                    };
                    fCachedShaders.reset();
                    fPersistentCache.foreach(collectShaders);
                    gLoadPending = false;

#if defined(SK_VULKAN)
                    if (isVulkan && !sksl) {
                        spvtools::SpirvTools tools(SPV_ENV_VULKAN_1_0);
                        for (auto& entry : fCachedShaders) {
                            for (int i = 0; i < kGrShaderTypeCount; ++i) {
                                const std::string& spirv(entry.fShader[i]);
                                std::string disasm;
                                tools.Disassemble((const uint32_t*)spirv.c_str(), spirv.size() / 4,
                                                  &disasm);
                                entry.fShader[i].assign(disasm);
                            }
                        }
                    }
#endif
                }

                // Defer actually doing the View/Apply logic so that we can trigger an Apply when we
                // start or finish hovering on a tree node in the list below:
                bool doView      = ImGui::Button("View"); ImGui::SameLine();
                bool doApply     = ImGui::Button("Apply Changes"); ImGui::SameLine();
                bool doDump      = ImGui::Button("Dump SkSL to resources/sksl/");

                int newOptLevel = fOptLevel;
                ImGui::RadioButton("SkSL", &newOptLevel, kShaderOptLevel_Source);
                ImGui::SameLine();
                ImGui::RadioButton("Compile", &newOptLevel, kShaderOptLevel_Compile);
                ImGui::SameLine();
                ImGui::RadioButton("Optimize", &newOptLevel, kShaderOptLevel_Optimize);
                ImGui::SameLine();
                ImGui::RadioButton("Inline", &newOptLevel, kShaderOptLevel_Inline);

                // If we are changing the compile mode, we want to reset the cache and redo
                // everything.
                static bool sDoDeferredView = false;
                if (doView || doDump || newOptLevel != fOptLevel) {
                    sksl = doDump || (newOptLevel == kShaderOptLevel_Source);
                    fOptLevel = (ShaderOptLevel)newOptLevel;
                    switch (fOptLevel) {
                        case kShaderOptLevel_Source:
                            Compiler::EnableOptimizer(OverrideFlag::kOff);
                            Compiler::EnableInliner(OverrideFlag::kOff);
                            break;
                        case kShaderOptLevel_Compile:
                            Compiler::EnableOptimizer(OverrideFlag::kOff);
                            Compiler::EnableInliner(OverrideFlag::kOff);
                            break;
                        case kShaderOptLevel_Optimize:
                            Compiler::EnableOptimizer(OverrideFlag::kOn);
                            Compiler::EnableInliner(OverrideFlag::kOff);
                            break;
                        case kShaderOptLevel_Inline:
                            Compiler::EnableOptimizer(OverrideFlag::kOn);
                            Compiler::EnableInliner(OverrideFlag::kOn);
                            break;
                    }

                    params.fGrContextOptions.fShaderCacheStrategy =
                            sksl ? GrContextOptions::ShaderCacheStrategy::kSkSL
                                 : GrContextOptions::ShaderCacheStrategy::kBackendSource;
                    displayParamsChanged = true;

                    fDeferredActions.push_back([=]() {
                        // Reset the cache.
                        fPersistentCache.reset();
                        sDoDeferredView = true;

                        // Dump the cache once we have drawn a frame with it.
                        if (doDump) {
                            fDeferredActions.push_back([this]() {
                                this->dumpShadersToResources();
                            });
                        }
                    });
                }

                ImGui::BeginChild("##ScrollingRegion");
                for (auto& entry : fCachedShaders) {
                    bool inTreeNode = ImGui::TreeNode(entry.fKeyString.c_str());
                    bool hovered = ImGui::IsItemHovered();
                    if (hovered != entry.fHovered) {
                        // Force an Apply to patch the highlight shader in/out
                        entry.fHovered = hovered;
                        doApply = true;
                    }
                    if (inTreeNode) {
                        auto stringBox = [](const char* label, std::string* str) {
                            // Full width, and not too much space for each shader
                            int lines = std::count(str->begin(), str->end(), '\n') + 2;
                            ImVec2 boxSize(-1.0f, ImGui::GetTextLineHeight() * std::min(lines, 30));
                            ImGui::InputTextMultiline(label, str, boxSize);
                        };
                        if (ImGui::TreeNode("Key")) {
                            ImGui::TextWrapped("%s", entry.fKeyDescription.c_str());
                            ImGui::TreePop();
                        }
                        stringBox("##VP", &entry.fShader[kVertex_GrShaderType]);
                        stringBox("##FP", &entry.fShader[kFragment_GrShaderType]);
                        ImGui::TreePop();
                    }
                }
                ImGui::EndChild();

                if (doView || sDoDeferredView) {
                    fPersistentCache.reset();
                    ctx->priv().getGpu()->resetShaderCacheForTesting();
                    gLoadPending = true;
                    sDoDeferredView = false;
                }

                // We don't support updating SPIRV shaders. We could re-assemble them (with edits),
                // but I'm not sure anyone wants to do that.
                if (isVulkan && !sksl) {
                    doApply = false;
                }
                if (doApply) {
                    fPersistentCache.reset();
                    ctx->priv().getGpu()->resetShaderCacheForTesting();
                    for (auto& entry : fCachedShaders) {
                        std::string backup = entry.fShader[kFragment_GrShaderType];
                        if (entry.fHovered) {
                            // The hovered item (if any) gets a special shader to make it
                            // identifiable.
                            std::string& fragShader = entry.fShader[kFragment_GrShaderType];
                            switch (entry.fShaderType) {
                                case SkSetFourByteTag('S', 'K', 'S', 'L'): {
                                    fragShader = build_sksl_highlight_shader();
                                    break;
                                }
                                case SkSetFourByteTag('G', 'L', 'S', 'L'): {
                                    fragShader = build_glsl_highlight_shader(
                                        *ctx->priv().caps()->shaderCaps());
                                    break;
                                }
                                case SkSetFourByteTag('M', 'S', 'L', ' '): {
                                    fragShader = build_metal_highlight_shader(fragShader);
                                    break;
                                }
                            }
                        }

                        auto data = GrPersistentCacheUtils::PackCachedShaders(entry.fShaderType,
                                                                              entry.fShader,
                                                                              entry.fInputs,
                                                                              kGrShaderTypeCount);
                        fPersistentCache.store(*entry.fKey, *data, entry.fKeyDescription);

                        entry.fShader[kFragment_GrShaderType] = backup;
                    }
                }
            }

            if (ImGui::CollapsingHeader("SkVM")) {
                auto* cache = SkVMBlitter::TryAcquireProgramCache();
                SkASSERT(cache);

                if (ImGui::Button("Clear")) {
                    cache->reset();
                    fDisassemblyCache.reset();
                }

                // First, go through the cache and restore the original program if we were hovering
                if (!fHoveredProgram.empty()) {
                    auto restoreHoveredProgram = [this](const SkVMBlitter::Key* key,
                                                        skvm::Program* program) {
                        if (*key == fHoveredKey) {
                            *program = std::move(fHoveredProgram);
                            fHoveredProgram = {};
                        }
                    };
                    cache->foreach(restoreHoveredProgram);
                }

                // Now iterate again, and dump any expanded program. If any program is hovered,
                // patch it, and remember the original (so it can be restored next frame).
                auto showVMEntry = [this](const SkVMBlitter::Key* key, skvm::Program* program) {
                    SkString keyString = SkVMBlitter::DebugName(*key);
                    bool inTreeNode = ImGui::TreeNode(keyString.c_str());
                    bool hovered = ImGui::IsItemHovered();

                    if (inTreeNode) {
                        auto stringBox = [](const char* label, std::string* str) {
                            int lines = std::count(str->begin(), str->end(), '\n') + 2;
                            ImVec2 boxSize(-1.0f, ImGui::GetTextLineHeight() * std::min(lines, 30));
                            ImGui::InputTextMultiline(label, str, boxSize);
                        };

                        SkDynamicMemoryWStream stream;
                        program->dump(&stream);
                        auto dumpData = stream.detachAsData();
                        std::string dumpString((const char*)dumpData->data(), dumpData->size());
                        stringBox("##VM", &dumpString);

#if defined(SKVM_JIT)
                        std::string* asmString = fDisassemblyCache.find(*key);
                        if (!asmString) {
                            program->disassemble(&stream);
                            auto asmData = stream.detachAsData();
                            asmString = fDisassemblyCache.set(
                                    *key,
                                    std::string((const char*)asmData->data(), asmData->size()));
                        }
                        stringBox("##ASM", asmString);
#endif

                        ImGui::TreePop();
                    }
                    if (hovered) {
                        // Generate a new blitter that just draws magenta
                        skvm::Program highlightProgram = build_skvm_highlight_program(
                                static_cast<SkColorType>(key->colorType), program->nargs());

                        fHoveredKey = *key;
                        fHoveredProgram = std::move(*program);
                        *program = std::move(highlightProgram);
                    }
                };
                cache->foreach(showVMEntry);

                SkVMBlitter::ReleaseProgramCache();
            }
        }
        if (displayParamsChanged || uiParamsChanged) {
            fDeferredActions.push_back([=]() {
                if (displayParamsChanged) {
                    fWindow->setRequestedDisplayParams(params);
                }
                fWindow->inval();
                this->updateTitle();
            });
        }
        ImGui::End();
    }

    if (gShaderErrorHandler.fErrors.count()) {
        ImGui::SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver);
        ImGui::Begin("Shader Errors", nullptr, ImGuiWindowFlags_NoFocusOnAppearing);
        for (int i = 0; i < gShaderErrorHandler.fErrors.count(); ++i) {
            ImGui::TextWrapped("%s", gShaderErrorHandler.fErrors[i].c_str());
            std::string sksl(gShaderErrorHandler.fShaders[i].c_str());
            SkShaderUtils::VisitLineByLine(sksl, [](int lineNumber, const char* lineText) {
                ImGui::TextWrapped("%4i\t%s\n", lineNumber, lineText);
            });
        }
        ImGui::End();
        gShaderErrorHandler.reset();
    }

    if (fShowZoomWindow && fLastImage) {
        ImGui::SetNextWindowSize(ImVec2(200, 200), ImGuiCond_FirstUseEver);
        if (ImGui::Begin("Zoom", &fShowZoomWindow)) {
            static int zoomFactor = 8;
            if (ImGui::Button("<<")) {
                zoomFactor = std::max(zoomFactor / 2, 4);
            }
            ImGui::SameLine(); ImGui::Text("%2d", zoomFactor); ImGui::SameLine();
            if (ImGui::Button(">>")) {
                zoomFactor = std::min(zoomFactor * 2, 32);
            }

            if (!fZoomWindowFixed) {
                ImVec2 mousePos = ImGui::GetMousePos();
                fZoomWindowLocation = SkPoint::Make(mousePos.x, mousePos.y);
            }
            SkScalar x = fZoomWindowLocation.x();
            SkScalar y = fZoomWindowLocation.y();
            int xInt = SkScalarRoundToInt(x);
            int yInt = SkScalarRoundToInt(y);
            ImVec2 avail = ImGui::GetContentRegionAvail();

            uint32_t pixel = 0;
            SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1);
            auto dContext = fWindow->directContext();
            if (fLastImage->readPixels(dContext, info, &pixel, info.minRowBytes(), xInt, yInt)) {
                ImGui::SameLine();
                ImGui::Text("(X, Y): %d, %d RGBA: %X %X %X %X",
                            xInt, yInt,
                            SkGetPackedR32(pixel), SkGetPackedG32(pixel),
                            SkGetPackedB32(pixel), SkGetPackedA32(pixel));
            }

            fImGuiLayer.skiaWidget(avail, [=, lastImage = fLastImage](SkCanvas* c) {
                // Translate so the region of the image that's under the mouse cursor is centered
                // in the zoom canvas:
                c->scale(zoomFactor, zoomFactor);
                c->translate(avail.x * 0.5f / zoomFactor - x - 0.5f,
                             avail.y * 0.5f / zoomFactor - y - 0.5f);
                c->drawImage(lastImage, 0, 0);

                SkPaint outline;
                outline.setStyle(SkPaint::kStroke_Style);
                c->drawRect(SkRect::MakeXYWH(x, y, 1, 1), outline);
            });
        }

        ImGui::End();
    }

    if (fShowHistogramWindow && fLastImage) {
        ImGui::SetNextWindowSize(ImVec2(450, 500));
        ImGui::SetNextWindowBgAlpha(0.5f);
        if (ImGui::Begin("Color Histogram (R,G,B)", &fShowHistogramWindow)) {
            const auto info = SkImageInfo::MakeN32Premul(fWindow->width(), fWindow->height());
            SkAutoPixmapStorage pixmap;
            pixmap.alloc(info);

            if (fLastImage->readPixels(fWindow->directContext(), info, pixmap.writable_addr(),
                                       info.minRowBytes(), 0, 0)) {
                std::vector<float> r(256), g(256), b(256);
                for (int y = 0; y < info.height(); ++y) {
                    for (int x = 0; x < info.width(); ++x) {
                        const auto pmc = *pixmap.addr32(x, y);
                        r[SkGetPackedR32(pmc)]++;
                        g[SkGetPackedG32(pmc)]++;
                        b[SkGetPackedB32(pmc)]++;
                    }
                }

                ImGui::PushItemWidth(-1);
                ImGui::PlotHistogram("R", r.data(), r.size(), 0, nullptr,
                                     FLT_MAX, FLT_MAX, ImVec2(0, 150));
                ImGui::PlotHistogram("G", g.data(), g.size(), 0, nullptr,
                                     FLT_MAX, FLT_MAX, ImVec2(0, 150));
                ImGui::PlotHistogram("B", b.data(), b.size(), 0, nullptr,
                                     FLT_MAX, FLT_MAX, ImVec2(0, 150));
                ImGui::PopItemWidth();
            }
        }

        ImGui::End();
    }
}

void Viewer::dumpShadersToResources() {
    // Sort the list of cached shaders so we can maintain some minimal level of consistency.
    // It doesn't really matter, but it will keep files from switching places unpredictably.
    std::vector<const CachedShader*> shaders;
    shaders.reserve(fCachedShaders.size());
    for (const CachedShader& shader : fCachedShaders) {
        shaders.push_back(&shader);
    }

    std::sort(shaders.begin(), shaders.end(), [](const CachedShader* a, const CachedShader* b) {
        return std::tie(a->fShader[kFragment_GrShaderType], a->fShader[kVertex_GrShaderType]) <
               std::tie(b->fShader[kFragment_GrShaderType], b->fShader[kVertex_GrShaderType]);
    });

    // Make the resources/sksl/SlideName/ directory.
    SkString directory = SkStringPrintf("%ssksl/%s",
                                        GetResourcePath().c_str(),
                                        fSlides[fCurrentSlide]->getName().c_str());
    if (!sk_mkdir(directory.c_str())) {
        SkDEBUGFAILF("Unable to create directory '%s'", directory.c_str());
        return;
    }

    int index = 0;
    for (const auto& entry : shaders) {
        SkString vertPath = SkStringPrintf("%s/Vertex_%02d.vert", directory.c_str(), index);
        FILE* vertFile = sk_fopen(vertPath.c_str(), kWrite_SkFILE_Flag);
        if (vertFile) {
            const std::string& vertText = entry->fShader[kVertex_GrShaderType];
            SkAssertResult(sk_fwrite(vertText.c_str(), vertText.size(), vertFile));
            sk_fclose(vertFile);
        } else {
            SkDEBUGFAILF("Unable to write shader to path '%s'", vertPath.c_str());
        }

        SkString fragPath = SkStringPrintf("%s/Fragment_%02d.frag", directory.c_str(), index);
        FILE* fragFile = sk_fopen(fragPath.c_str(), kWrite_SkFILE_Flag);
        if (fragFile) {
            const std::string& fragText = entry->fShader[kFragment_GrShaderType];
            SkAssertResult(sk_fwrite(fragText.c_str(), fragText.size(), fragFile));
            sk_fclose(fragFile);
        } else {
            SkDEBUGFAILF("Unable to write shader to path '%s'", fragPath.c_str());
        }

        ++index;
    }
}

void Viewer::onIdle() {
    SkTArray<std::function<void()>> actionsToRun;
    actionsToRun.swap(fDeferredActions);

    for (const auto& fn : actionsToRun) {
        fn();
    }

    fStatsLayer.beginTiming(fAnimateTimer);
    fAnimTimer.updateTime();
    bool animateWantsInval = fSlides[fCurrentSlide]->animate(fAnimTimer.nanos());
    fStatsLayer.endTiming(fAnimateTimer);

    ImGuiIO& io = ImGui::GetIO();
    // ImGui always has at least one "active" window, which is the default "Debug" window. It may
    // not be visible, though. So we need to redraw if there is at least one visible window, or
    // more than one active window. Newly created windows are active but not visible for one frame
    // while they determine their layout and sizing.
    if (animateWantsInval || fStatsLayer.getActive() || fRefresh ||
        io.MetricsActiveWindows > 1 || io.MetricsRenderWindows > 0) {
        fWindow->inval();
    }
}

template <typename OptionsFunc>
static void WriteStateObject(SkJSONWriter& writer, const char* name, const char* value,
                             OptionsFunc&& optionsFunc) {
    writer.beginObject();
    {
        writer.appendString(kName , name);
        writer.appendString(kValue, value);

        writer.beginArray(kOptions);
        {
            optionsFunc(writer);
        }
        writer.endArray();
    }
    writer.endObject();
}


void Viewer::updateUIState() {
    if (!fWindow) {
        return;
    }
    if (fWindow->sampleCount() < 1) {
        return; // Surface hasn't been created yet.
    }

    SkDynamicMemoryWStream memStream;
    SkJSONWriter writer(&memStream);
    writer.beginArray();

    // Slide state
    WriteStateObject(writer, kSlideStateName, fSlides[fCurrentSlide]->getName().c_str(),
        [this](SkJSONWriter& writer) {
            for(const auto& slide : fSlides) {
                writer.appendString(slide->getName().c_str());
            }
        });

    // Backend state
    WriteStateObject(writer, kBackendStateName, kBackendTypeStrings[fBackendType],
        [](SkJSONWriter& writer) {
            for (const auto& str : kBackendTypeStrings) {
                writer.appendString(str);
            }
        });

    // MSAA state
    const auto countString = SkStringPrintf("%d", fWindow->sampleCount());
    WriteStateObject(writer, kMSAAStateName, countString.c_str(),
        [this](SkJSONWriter& writer) {
            writer.appendS32(0);

            if (sk_app::Window::kRaster_BackendType == fBackendType) {
                return;
            }

            for (int msaa : {4, 8, 16}) {
                writer.appendS32(msaa);
            }
        });

    // Path renderer state
    GpuPathRenderers pr = fWindow->getRequestedDisplayParams().fGrContextOptions.fGpuPathRenderers;
    WriteStateObject(writer, kPathRendererStateName, gPathRendererNames[pr].c_str(),
        [this](SkJSONWriter& writer) {
            auto ctx = fWindow->directContext();
            if (!ctx) {
                writer.appendString("Software");
            } else {
                writer.appendString(gPathRendererNames[GpuPathRenderers::kDefault].c_str());
#if SK_GPU_V1
                if (fWindow->sampleCount() > 1 || FLAGS_dmsaa) {
                    const auto* caps = ctx->priv().caps();
                    if (skgpu::v1::AtlasPathRenderer::IsSupported(ctx)) {
                        writer.appendString(
                                gPathRendererNames[GpuPathRenderers::kAtlas].c_str());
                    }
                    if (skgpu::v1::TessellationPathRenderer::IsSupported(*caps)) {
                        writer.appendString(
                                gPathRendererNames[GpuPathRenderers::kTessellation].c_str());
                    }
                }
#endif
                if (1 == fWindow->sampleCount()) {
                    writer.appendString(gPathRendererNames[GpuPathRenderers::kSmall].c_str());
                }
                writer.appendString(gPathRendererNames[GpuPathRenderers::kTriangulating].c_str());
                writer.appendString(gPathRendererNames[GpuPathRenderers::kNone].c_str());
            }
        });

    // Softkey state
    WriteStateObject(writer, kSoftkeyStateName, kSoftkeyHint,
        [this](SkJSONWriter& writer) {
            writer.appendString(kSoftkeyHint);
            for (const auto& softkey : fCommands.getCommandsAsSoftkeys()) {
                writer.appendString(softkey.c_str());
            }
        });

    writer.endArray();
    writer.flush();

    auto data = memStream.detachAsData();

    // TODO: would be cool to avoid this copy
    const SkString cstring(static_cast<const char*>(data->data()), data->size());

    fWindow->setUIState(cstring.c_str());
}

void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateValue) {
    // For those who will add more features to handle the state change in this function:
    // After the change, please call updateUIState no notify the frontend (e.g., Android app).
    // For example, after slide change, updateUIState is called inside setupCurrentSlide;
    // after backend change, updateUIState is called in this function.
    if (stateName.equals(kSlideStateName)) {
        for (int i = 0; i < fSlides.count(); ++i) {
            if (fSlides[i]->getName().equals(stateValue)) {
                this->setCurrentSlide(i);
                return;
            }
        }

        SkDebugf("Slide not found: %s", stateValue.c_str());
    } else if (stateName.equals(kBackendStateName)) {
        for (int i = 0; i < sk_app::Window::kBackendTypeCount; i++) {
            if (stateValue.equals(kBackendTypeStrings[i])) {
                if (fBackendType != i) {
                    fBackendType = (sk_app::Window::BackendType)i;
                    for(auto& slide : fSlides) {
                        slide->gpuTeardown();
                    }
                    fWindow->detach();
                    fWindow->attach(backend_type_for_window(fBackendType));
                }
                break;
            }
        }
    } else if (stateName.equals(kMSAAStateName)) {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        int sampleCount = atoi(stateValue.c_str());
        if (sampleCount != params.fMSAASampleCount) {
            params.fMSAASampleCount = sampleCount;
            fWindow->setRequestedDisplayParams(params);
            fWindow->inval();
            this->updateTitle();
            this->updateUIState();
        }
    } else if (stateName.equals(kPathRendererStateName)) {
        DisplayParams params = fWindow->getRequestedDisplayParams();
        for (const auto& pair : gPathRendererNames) {
            if (pair.second == stateValue.c_str()) {
                if (params.fGrContextOptions.fGpuPathRenderers != pair.first) {
                    params.fGrContextOptions.fGpuPathRenderers = pair.first;
                    fWindow->setRequestedDisplayParams(params);
                    fWindow->inval();
                    this->updateTitle();
                    this->updateUIState();
                }
                break;
            }
        }
    } else if (stateName.equals(kSoftkeyStateName)) {
        if (!stateValue.equals(kSoftkeyHint)) {
            fCommands.onSoftkey(stateValue);
            this->updateUIState(); // This is still needed to reset the value to kSoftkeyHint
        }
    } else if (stateName.equals(kRefreshStateName)) {
        // This state is actually NOT in the UI state.
        // We use this to allow Android to quickly set bool fRefresh.
        fRefresh = stateValue.equals(kON);
    } else {
        SkDebugf("Unknown stateName: %s", stateName.c_str());
    }
}

bool Viewer::onKey(skui::Key key, skui::InputState state, skui::ModifierKey modifiers) {
    return fCommands.onKey(key, state, modifiers);
}

bool Viewer::onChar(SkUnichar c, skui::ModifierKey modifiers) {
    if (fSlides[fCurrentSlide]->onChar(c)) {
        fWindow->inval();
        return true;
    } else {
        return fCommands.onChar(c, modifiers);
    }
}
