Add legacy++ to viewer (sRGB w/nonlinear blending)
authorBrian Osman <brianosman@google.com>
Mon, 6 Mar 2017 16:47:26 +0000 (11:47 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Mon, 6 Mar 2017 17:21:08 +0000 (17:21 +0000)
BUG=skia:6242

Change-Id: I696de8eac61aebaf5cb07d8874bde3c7bd470277
Reviewed-on: https://skia-review.googlesource.com/9299
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
tools/viewer/Viewer.cpp
tools/viewer/Viewer.h

index f3cc4c9..881c6d9 100644 (file)
@@ -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<SkSurface> 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<SkColorSpace> 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<SkColorSpace> cs = (kRGBA_F16_SkColorType == fColorType)
+        sk_sp<SkColorSpace> 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);
                     });
                 }
 
index fc094fc..c50f750 100644 (file)
@@ -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