From 92004807f2dffea2d4a694e49434ce4c0bcfb28d Mon Sep 17 00:00:00 2001 From: Brian Osman Date: Mon, 6 Mar 2017 11:47:26 -0500 Subject: [PATCH] Add legacy++ to viewer (sRGB w/nonlinear blending) BUG=skia:6242 Change-Id: I696de8eac61aebaf5cb07d8874bde3c7bd470277 Reviewed-on: https://skia-review.googlesource.com/9299 Commit-Queue: Brian Osman Reviewed-by: Mike Klein --- tools/viewer/Viewer.cpp | 102 +++++++++++++++++++++++++++++++----------------- tools/viewer/Viewer.h | 12 ++++-- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index f3cc4c9..881c6d9 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -238,8 +238,7 @@ Viewer::Viewer(int argc, char** argv, void* platformData) , fShowZoomWindow(false) , fLastImage(nullptr) , fBackendType(sk_app::Window::kNativeGL_BackendType) - , fColorType(kN32_SkColorType) - , fColorManaged(false) + , fColorMode(ColorMode::kLegacy) , fColorSpacePrimaries(gSrgbPrimaries) , fZoomCenterX(0.0f) , fZoomCenterY(0.0f) @@ -316,15 +315,19 @@ Viewer::Viewer(int argc, char** argv, void* platformData) fWindow->inval(); }); fCommands.addCommand('c', "Modes", "Cycle color mode", [this]() { - if (!fColorManaged) { - // Legacy -> Color correct 8888 - this->setColorMode(kN32_SkColorType, true); - } else if (kN32_SkColorType == fColorType) { - // Color correct 8888 -> Color correct F16 - this->setColorMode(kRGBA_F16_SkColorType, true); - } else { - // Color correct F16 -> Legacy - this->setColorMode(kN32_SkColorType, false); + switch (fColorMode) { + case ColorMode::kLegacy: + this->setColorMode(ColorMode::kColorManagedSRGB8888_NonLinearBlending); + break; + case ColorMode::kColorManagedSRGB8888_NonLinearBlending: + this->setColorMode(ColorMode::kColorManagedSRGB8888); + break; + case ColorMode::kColorManagedSRGB8888: + this->setColorMode(ColorMode::kColorManagedLinearF16); + break; + case ColorMode::kColorManagedLinearF16: + this->setColorMode(ColorMode::kLegacy); + break; } }); fCommands.addCommand(Window::Key::kRight, "Right", "Navigation", "Next slide", [this]() { @@ -532,11 +535,22 @@ void Viewer::updateTitle() { SkString title("Viewer: "); title.append(fSlides[fCurrentSlide]->getName()); - title.appendf(" %s", sk_tool_utils::colortype_name(fColorType)); - - if (fColorManaged) { - title.append(" ColorManaged"); + switch (fColorMode) { + case ColorMode::kLegacy: + title.append(" Legacy 8888"); + break; + case ColorMode::kColorManagedSRGB8888_NonLinearBlending: + title.append(" ColorManaged 8888 (Nonlinear blending)"); + break; + case ColorMode::kColorManagedSRGB8888: + title.append(" ColorManaged 8888"); + break; + case ColorMode::kColorManagedLinearF16: + title.append(" ColorManaged F16"); + 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)) { @@ -692,15 +706,16 @@ void Viewer::setBackend(sk_app::Window::BackendType backendType) { fWindow->attach(fBackendType); } -void Viewer::setColorMode(SkColorType colorType, bool colorManaged) { - fColorType = colorType; - fColorManaged = colorManaged; +void Viewer::setColorMode(ColorMode colorMode) { + fColorMode = colorMode; // When we're in color managed mode, we tag our window surface as sRGB. If we've switched into // or out of legacy mode, we need to update our window configuration. DisplayParams params = fWindow->getRequestedDisplayParams(); - if (fColorManaged != SkToBool(params.fColorSpace)) { - params.fColorSpace = fColorManaged ? SkColorSpace::MakeSRGB() : nullptr; + bool wasInLegacy = !SkToBool(params.fColorSpace); + bool wantLegacy = (ColorMode::kLegacy == fColorMode); + if (wasInLegacy != wantLegacy) { + params.fColorSpace = wantLegacy ? nullptr : SkColorSpace::MakeSRGB(); fWindow->setRequestedDisplayParams(params); } @@ -721,19 +736,27 @@ void Viewer::drawSlide(SkCanvas* canvas) { SkCanvas* slideCanvas = canvas; fLastImage.reset(); - // If we're in F16, or the gamut isn't sRGB, or we're zooming, we need to render offscreen + // If we're in F16 or nonlinear blending mode, or the gamut isn't sRGB, or we're zooming, + // we need to render offscreen + bool colorManaged = (ColorMode::kLegacy != fColorMode); sk_sp offscreenSurface = nullptr; - if (kRGBA_F16_SkColorType == fColorType || fShowZoomWindow || - (fColorManaged && !primaries_equal(fColorSpacePrimaries, gSrgbPrimaries))) { + if (ColorMode::kColorManagedLinearF16 == fColorMode || + ColorMode::kColorManagedSRGB8888_NonLinearBlending == fColorMode || + fShowZoomWindow || + (colorManaged && !primaries_equal(fColorSpacePrimaries, gSrgbPrimaries))) { sk_sp cs = nullptr; - if (fColorManaged) { - SkColorSpace::RenderTargetGamma transferFn = (kRGBA_F16_SkColorType == fColorType) + if (colorManaged) { + auto transferFn = (ColorMode::kColorManagedLinearF16 == fColorMode) ? SkColorSpace::kLinear_RenderTargetGamma : SkColorSpace::kSRGB_RenderTargetGamma; SkMatrix44 toXYZ; SkAssertResult(fColorSpacePrimaries.toXYZD50(&toXYZ)); - cs = SkColorSpace::MakeRGB(transferFn, toXYZ); + uint32_t flags = (ColorMode::kColorManagedSRGB8888_NonLinearBlending == fColorMode) + ? SkColorSpace::kNonLinearBlending_ColorSpaceFlag : 0; + cs = SkColorSpace::MakeRGB(transferFn, toXYZ, flags); } - SkImageInfo info = SkImageInfo::Make(fWindow->width(), fWindow->height(), fColorType, + SkColorType colorType = (ColorMode::kColorManagedLinearF16 == fColorMode) + ? kRGBA_F16_SkColorType : kN32_SkColorType; + SkImageInfo info = SkImageInfo::Make(fWindow->width(), fWindow->height(), colorType, kPremul_SkAlphaType, std::move(cs)); offscreenSurface = canvas->makeSurface(info); slideCanvas = offscreenSurface->getCanvas(); @@ -759,7 +782,7 @@ void Viewer::drawSlide(SkCanvas* canvas) { fLastImage = offscreenSurface->makeImageSnapshot(); // Tag the image with the sRGB gamut, so no further color space conversion happens - sk_sp cs = (kRGBA_F16_SkColorType == fColorType) + sk_sp cs = (ColorMode::kColorManagedLinearF16 == fColorMode) ? SkColorSpace::MakeSRGBLinear() : SkColorSpace::MakeSRGB(); auto retaggedImage = SkImageMakeRasterCopyAndAssignColorSpace(fLastImage.get(), cs.get()); SkPaint paint; @@ -1042,17 +1065,24 @@ void Viewer::drawImGui(SkCanvas* canvas) { } if (ImGui::CollapsingHeader("Color Mode")) { - int oldMode = fColorManaged ? (kRGBA_F16_SkColorType == fColorType) ? 2 : 1 : 0; - int newMode = oldMode; - ImGui::RadioButton("Legacy", &newMode, 0); - ImGui::RadioButton("Color Managed 8888", &newMode, 1); - ImGui::RadioButton("Color Managed F16", &newMode, 2); - if (newMode != oldMode) { + 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::kColorManagedSRGB8888_NonLinearBlending, + "Color Managed 8888 (Nonlinear blending)"); + cmButton(ColorMode::kColorManagedSRGB8888, "Color Managed 8888"); + cmButton(ColorMode::kColorManagedLinearF16, "Color Managed F16"); + + if (newMode != fColorMode) { // It isn't safe to switch color mode now (in the middle of painting). We might // tear down the back-end, etc... Defer this change until the next onIdle. fDeferredActions.push_back([=]() { - this->setColorMode(2 == newMode ? kRGBA_F16_SkColorType : kN32_SkColorType, - 0 != newMode); + this->setColorMode(newMode); }); } diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index fc094fc..c50f750 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -32,10 +32,17 @@ public: bool onChar(SkUnichar c, uint32_t modifiers); private: + enum class ColorMode { + kLegacy, // N32, no color management + kColorManagedSRGB8888_NonLinearBlending, // N32, sRGB transfer function, nonlinear blending + kColorManagedSRGB8888, // N32, sRGB transfer function, linear blending + kColorManagedLinearF16, // F16, linear transfer function, linear blending + }; + void initSlides(); void updateTitle(); void setBackend(sk_app::Window::BackendType); - void setColorMode(SkColorType, bool colorManaged); + void setColorMode(ColorMode); void setStartupSlide(); void setupCurrentSlide(int previousSlide); void listNames(); @@ -75,8 +82,7 @@ private: sk_app::Window::BackendType fBackendType; // Color properties for slide rendering - SkColorType fColorType; - bool fColorManaged; + ColorMode fColorMode; SkColorSpacePrimaries fColorSpacePrimaries; // transform data -- 2.7.4