diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 9f274e36ea..8789c99a56 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -13,6 +13,7 @@ #include "SampleSlide.h" #include "SKPSlide.h" +#include "GrContext.h" #include "SkATrace.h" #include "SkCanvas.h" #include "SkColorSpace_Base.h" @@ -22,6 +23,7 @@ #include "SkGraphics.h" #include "SkImagePriv.h" #include "SkMetaData.h" +#include "SkOnce.h" #include "SkOSFile.h" #include "SkOSPath.h" #include "SkRandom.h" @@ -34,9 +36,13 @@ #include "imgui.h" #include +#include using namespace sk_app; +using GpuPathRenderers = GrContextOptions::GpuPathRenderers; +static std::map gPathRendererNames; + Application* Application::Create(int argc, char** argv, void* platformData) { return new Viewer(argc, argv, platformData); } @@ -215,6 +221,7 @@ const char* kOptions = "options"; const char* kSlideStateName = "Slide"; const char* kBackendStateName = "Backend"; const char* kMSAAStateName = "MSAA"; +const char* kPathRendererStateName = "Path renderer"; const char* kSoftkeyStateName = "Softkey"; const char* kSoftkeyHint = "Please select a softkey"; const char* kFpsStateName = "FPS"; @@ -241,6 +248,19 @@ Viewer::Viewer(int argc, char** argv, void* platformData) { static SkTaskGroup::Enabler kTaskGroupEnabler; SkGraphics::Init(); + + static SkOnce initPathRendererNames; + initPathRendererNames([]() { + gPathRendererNames[GpuPathRenderers::kAll] = "Default Ganesh Behavior (best path renderer)"; + gPathRendererNames[GpuPathRenderers::kStencilAndCover] = "NV_path_rendering"; + gPathRendererNames[GpuPathRenderers::kMSAA] = "Sample shading"; + gPathRendererNames[GpuPathRenderers::kPLS] = "Pixel local storage"; + gPathRendererNames[GpuPathRenderers::kDistanceField] = "Distance field (small paths only)"; + gPathRendererNames[GpuPathRenderers::kTesselating] = "Tessellating"; + gPathRendererNames[GpuPathRenderers::kDefault] = "Original Ganesh path renderer"; + gPathRendererNames[GpuPathRenderers::kNone] = "Software masks"; + }); + memset(fPaintTimes, 0, sizeof(fPaintTimes)); memset(fFlushTimes, 0, sizeof(fFlushTimes)); memset(fAnimateTimes, 0, sizeof(fAnimateTimes)); @@ -265,6 +285,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData) DisplayParams displayParams; displayParams.fMSAASampleCount = FLAGS_msaa; + displayParams.fGrContextOptions.fGpuPathRenderers = CollectGpuPathRenderersFromFlags(); fWindow->setRequestedDisplayParams(displayParams); // register callbacks @@ -551,6 +572,12 @@ void Viewer::updateTitle() { title.appendf(" MSAA: %i", msaa); } title.append("]"); + + GpuPathRenderers pr = fWindow->getRequestedDisplayParams().fGrContextOptions.fGpuPathRenderers; + if (GpuPathRenderers::kAll != pr) { + title.appendf(" [Path renderer: %s]", gPathRendererNames[pr].c_str()); + } + fWindow->setTitle(title.c_str()); } @@ -1120,6 +1147,36 @@ void Viewer::updateUIState() { } } + // Path renderer state + GpuPathRenderers pr = fWindow->getRequestedDisplayParams().fGrContextOptions.fGpuPathRenderers; + Json::Value prState(Json::objectValue); + prState[kName] = kPathRendererStateName; + prState[kValue] = gPathRendererNames[pr]; + prState[kOptions] = Json::Value(Json::arrayValue); + const GrContext* ctx = fWindow->getGrContext(); + if (!ctx) { + prState[kOptions].append("Software"); + } else if (fWindow->sampleCount()) { + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kAll]); + if (ctx->caps()->shaderCaps()->pathRenderingSupport()) { + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kStencilAndCover]); + } + if (ctx->caps()->sampleShadingSupport()) { + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kMSAA]); + } + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kTesselating]); + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kDefault]); + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kNone]); + } else { + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kAll]); + if (ctx->caps()->shaderCaps()->plsPathRenderingSupport()) { + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kPLS]); + } + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kDistanceField]); + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kTesselating]); + prState[kOptions].append(gPathRendererNames[GpuPathRenderers::kNone]); + } + // Softkey state Json::Value softkeyState(Json::objectValue); softkeyState[kName] = kSoftkeyStateName; @@ -1145,6 +1202,7 @@ void Viewer::updateUIState() { state.append(slideState); state.append(backendState); state.append(msaaState); + state.append(prState); state.append(softkeyState); state.append(fpsState); @@ -1189,6 +1247,21 @@ void Viewer::onUIStateChanged(const SkString& stateName, const SkString& stateVa fWindow->setRequestedDisplayParams(params); fWindow->inval(); updateTitle(); + 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(); + updateTitle(); + updateUIState(); + } + break; + } } } else if (stateName.equals(kSoftkeyStateName)) { if (!stateValue.equals(kSoftkeyHint)) { diff --git a/tools/viewer/sk_app/DisplayParams.h b/tools/viewer/sk_app/DisplayParams.h index 0c649c01bd..959735e8ff 100644 --- a/tools/viewer/sk_app/DisplayParams.h +++ b/tools/viewer/sk_app/DisplayParams.h @@ -7,6 +7,7 @@ #ifndef DisplayParams_DEFINED #define DisplayParams_DEFINED +#include "GrContextOptions.h" #include "SkImageInfo.h" namespace sk_app { @@ -20,6 +21,7 @@ struct DisplayParams { SkColorType fColorType; sk_sp fColorSpace; int fMSAASampleCount; + GrContextOptions fGrContextOptions; }; } // namespace sk_app diff --git a/tools/viewer/sk_app/GLWindowContext.cpp b/tools/viewer/sk_app/GLWindowContext.cpp index 89cd858bc1..ff56ce8668 100644 --- a/tools/viewer/sk_app/GLWindowContext.cpp +++ b/tools/viewer/sk_app/GLWindowContext.cpp @@ -7,7 +7,6 @@ */ #include "GrContext.h" -#include "SkCommonFlagsPathRenderer.h" #include "SkSurface.h" #include "GLWindowContext.h" @@ -37,11 +36,9 @@ void GLWindowContext::initializeContext() { this->onInitializeContext(); SkASSERT(nullptr == fContext); - GrContextOptions ctxOptions; - ctxOptions.fGpuPathRenderers = CollectGpuPathRenderersFromFlags(); fBackendContext.reset(GrGLCreateNativeInterface()); fContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext)fBackendContext.get(), - ctxOptions); + fDisplayParams.fGrContextOptions); if (!fContext && fDisplayParams.fMSAASampleCount) { fDisplayParams.fMSAASampleCount /= 2; this->initializeContext(); diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp index b8071d3bc3..8e8c059492 100644 --- a/tools/viewer/sk_app/VulkanWindowContext.cpp +++ b/tools/viewer/sk_app/VulkanWindowContext.cpp @@ -8,7 +8,6 @@ #include "GrContext.h" #include "GrRenderTarget.h" -#include "SkCommonFlagsPathRenderer.h" #include "SkAutoMalloc.h" #include "SkSurface.h" #include "VulkanWindowContext.h" @@ -62,10 +61,8 @@ VulkanWindowContext::VulkanWindowContext(const DisplayParams& params, GET_DEV_PROC(AcquireNextImageKHR); GET_DEV_PROC(QueuePresentKHR); - GrContextOptions ctxOptions; - ctxOptions.fGpuPathRenderers = CollectGpuPathRenderersFromFlags(); fContext = GrContext::Create(kVulkan_GrBackend, (GrBackendContext) fBackendContext.get(), - ctxOptions); + params.fGrContextOptions); fSurface = createVkSurface(instance); if (VK_NULL_HANDLE == fSurface) { diff --git a/tools/viewer/sk_app/Window.cpp b/tools/viewer/sk_app/Window.cpp index d57daf98a7..a63e1e3760 100644 --- a/tools/viewer/sk_app/Window.cpp +++ b/tools/viewer/sk_app/Window.cpp @@ -146,6 +146,13 @@ int Window::stencilBits() const { return fWindowContext->stencilBits(); } +const GrContext* Window::getGrContext() const { + if (!fWindowContext) { + return nullptr; + } + return fWindowContext->getGrContext(); +} + void Window::inval() { if (!fWindowContext) { return; diff --git a/tools/viewer/sk_app/Window.h b/tools/viewer/sk_app/Window.h index 4ae23b1b47..85cf3ac8a4 100644 --- a/tools/viewer/sk_app/Window.h +++ b/tools/viewer/sk_app/Window.h @@ -14,6 +14,7 @@ #include "SkTypes.h" #include "SkJSONCPP.h" +class GrContext; class SkCanvas; class SkSurface; @@ -198,6 +199,9 @@ public: int sampleCount() const; int stencilBits() const; + // Returns null if there is not a GPU backend or if the backend is not yet created. + const GrContext* getGrContext() const; + protected: Window();