Simplify viewer's handling of backbuffer surface and color space

WindowContext still supports color spaces, but not other color
types. Any off-screen rendering is the app's responsibility.

This change also adds (working) F16 support to viewer. Note that
the previous 10-bit and FP16 support in WindowContext was broken.
There was no code to push the off-screen canvas to the window.
If you ever made it to the unreachable off-screen code path in
createSurface, it would have simply stopped drawing.

The decision to limit the window's gamut to sRGB is mostly driven
by my desire to add real-time editing of gamut. This design lets
us do that, without tearing down and rebuilding the window for
every change. An application could still supply a different gamut
via setDisplayParams and render directly to the back buffer with
proper color correction.

BUG=skia:

Change-Id: I94df35c7a42faee396009acc83683e40bb3c284d
Reviewed-on: https://skia-review.googlesource.com/8153
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index c19b3bd..e389cd2 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1360,7 +1360,6 @@
         "tools/viewer/sk_app/CommandSet.cpp",
         "tools/viewer/sk_app/GLWindowContext.cpp",
         "tools/viewer/sk_app/Window.cpp",
-        "tools/viewer/sk_app/WindowContext.cpp",
       ]
       libs = []
 
diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp
index 0383897..f8236bf 100644
--- a/tools/sk_tool_utils.cpp
+++ b/tools/sk_tool_utils.cpp
@@ -201,6 +201,7 @@
         case kRGB_565_SkColorType:      return "RGB_565";
         case kRGBA_8888_SkColorType:    return "RGBA_8888";
         case kBGRA_8888_SkColorType:    return "BGRA_8888";
+        case kRGBA_F16_SkColorType:     return "RGBA_F16";
         default:
             SkASSERT(false);
             return "unexpected colortype";
diff --git a/tools/viewer/ImageSlide.cpp b/tools/viewer/ImageSlide.cpp
index 0b52a81..dd7adba 100644
--- a/tools/viewer/ImageSlide.cpp
+++ b/tools/viewer/ImageSlide.cpp
@@ -7,14 +7,9 @@
 
 #include "ImageSlide.h"
 
-#include "SkBitmap.h"
-#include "SkCodec.h"
-#include "SkColorSpaceXform.h"
-#include "SkColorSpace_Base.h"
 #include "SkCanvas.h"
 #include "SkData.h"
 #include "SkImage.h"
-#include "SkMetaData.h"
 
 ImageSlide::ImageSlide(const SkString& name, const SkString& path) : fPath(path) {
     fName = name;
@@ -25,30 +20,12 @@
 }
 
 void ImageSlide::draw(SkCanvas* canvas) {
-    if (canvas->getMetaData().hasBool(kImageColorXformMetaData, true)) {
-        canvas->drawBitmap(fXformedBitmap, 0, 0);
-    } else {
-        // skbug.com/5428
-        // drawImage() and drawBitmap() behave differently in sRGB mode.
-        // canvas->drawImage(fImage.get(), 0, 0);
-        canvas->drawBitmap(fOriginalBitmap, 0, 0);
-    }
+    canvas->drawImage(fImage, 0, 0);
 }
 
 void ImageSlide::load(SkScalar, SkScalar) {
     sk_sp<SkData> encoded = SkData::MakeFromFileName(fPath.c_str());
-    std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(encoded));
-    if (!codec) {
-        return;
-    }
-
-    fOriginalBitmap.allocPixels(codec->getInfo());
-    codec->getPixels(codec->getInfo(), fOriginalBitmap.getPixels(), fOriginalBitmap.rowBytes());
-
-    SkImageInfo xformedInfo = codec->getInfo().makeColorSpace(
-            SkColorSpace_Base::MakeNamed(SkColorSpace_Base::kAdobeRGB_Named));
-    fXformedBitmap.allocPixels(xformedInfo);
-    codec->getPixels(xformedInfo, fXformedBitmap.getPixels(), fXformedBitmap.rowBytes());
+    fImage = SkImage::MakeFromEncoded(encoded);
 }
 
 void ImageSlide::unload() {
diff --git a/tools/viewer/ImageSlide.h b/tools/viewer/ImageSlide.h
index 0dd816e..d9e3f2d 100644
--- a/tools/viewer/ImageSlide.h
+++ b/tools/viewer/ImageSlide.h
@@ -12,8 +12,6 @@
 #include "SkPicture.h"
 #include "SkImage.h"
 
-static const char* kImageColorXformMetaData = "ImageColorSpaceXform";
-
 class ImageSlide : public Slide {
 public:
     ImageSlide(const SkString& name, const SkString& path);
@@ -25,10 +23,8 @@
     void unload() override;
 
 private:
-    SkString               fPath;
-    sk_sp<const SkImage>   fImage;
-    SkBitmap               fOriginalBitmap;
-    SkBitmap               fXformedBitmap;
+    SkString         fPath;
+    sk_sp<SkImage>   fImage;
 };
 
 #endif
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 0b93afc..40486e7 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -18,6 +18,7 @@
 #include "SkCommandLineFlags.h"
 #include "SkDashPathEffect.h"
 #include "SkGraphics.h"
+#include "SkImagePriv.h"
 #include "SkMetaData.h"
 #include "SkOSFile.h"
 #include "SkOSPath.h"
@@ -113,7 +114,6 @@
 const char* kSoftkeyStateName = "Softkey";
 const char* kSoftkeyHint = "Please select a softkey";
 const char* kFpsStateName = "FPS";
-const char* kSplitScreenStateName = "Split screen";
 const char* kON = "ON";
 const char* kOFF = "OFF";
 const char* kRefreshStateName = "Refresh";
@@ -122,8 +122,9 @@
     : fCurrentMeasurement(0)
     , fDisplayStats(false)
     , fRefresh(false)
-    , fSplitScreen(false)
     , fBackendType(sk_app::Window::kNativeGL_BackendType)
+    , fColorType(kN32_SkColorType)
+    , fColorSpace(nullptr)
     , fZoomCenterX(0.0f)
     , fZoomCenterY(0.0f)
     , fZoomLevel(0.0f)
@@ -162,13 +163,17 @@
         this->fDisplayStats = !this->fDisplayStats;
         fWindow->inval();
     });
-    fCommands.addCommand('c', "Modes", "Toggle sRGB color mode", [this]() {
-        DisplayParams params = fWindow->getDisplayParams();
-        params.fColorSpace = (nullptr == params.fColorSpace)
-            ? SkColorSpace::MakeSRGB() : nullptr;
-        fWindow->setDisplayParams(params);
-        this->updateTitle();
-        fWindow->inval();
+    fCommands.addCommand('c', "Modes", "Cycle color mode", [this]() {
+        if (!fColorSpace) {
+            // Legacy -> sRGB
+            this->setColorMode(kN32_SkColorType, SkColorSpace::MakeSRGB());
+        } else if (kN32_SkColorType == fColorType) {
+            // sRGB -> F16 sRGB
+            this->setColorMode(kRGBA_F16_SkColorType, SkColorSpace::MakeSRGBLinear());
+        } else {
+            // F16 sRGB -> Legacy
+            this->setColorMode(kN32_SkColorType, nullptr);
+        }
     });
     fCommands.addCommand(Window::Key::kRight, "Right", "Navigation", "Next slide", [this]() {
         int previousSlide = fCurrentSlide;
@@ -337,10 +342,13 @@
     SkString title("Viewer: ");
     title.append(fSlides[fCurrentSlide]->getName());
 
-    // TODO: For now, any color-space on the window means sRGB
-    if (fWindow->getDisplayParams().fColorSpace) {
-        title.append(" sRGB");
+    title.appendf(" %s", sk_tool_utils::colortype_name(fColorType));
+
+    // TODO: Find a short string to describe the gamut of the color space?
+    if (fColorSpace) {
+        title.append(" ColorManaged");
     }
+
     title.append(kBackendTypeStrings[fBackendType]);
     fWindow->setTitle(title.c_str());
 }
@@ -422,56 +430,67 @@
     return m;
 }
 
-void Viewer::drawSlide(SkCanvas* canvas, bool inSplitScreen) {
-    SkASSERT(!inSplitScreen || fWindow->supportsContentRect());
+void Viewer::setColorMode(SkColorType colorType, sk_sp<SkColorSpace> colorSpace) {
+    fColorType = colorType;
+    fColorSpace = std::move(colorSpace);
 
+    // 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->getDisplayParams();
+    if (SkToBool(fColorSpace) != SkToBool(params.fColorSpace)) {
+        params.fColorSpace = fColorSpace ? SkColorSpace::MakeSRGB() : nullptr;
+        fWindow->setDisplayParams(params);
+    }
+
+    this->updateTitle();
+    fWindow->inval();
+}
+
+void Viewer::drawSlide(SkCanvas* canvas) {
     int count = canvas->save();
-
     if (fWindow->supportsContentRect()) {
         SkRect contentRect = fWindow->getContentRect();
-        // If inSplitScreen, translate the image half screen to the right.
-        // Thus we have two copies of the image on each half of the screen.
-        contentRect.fLeft +=
-                inSplitScreen ? (contentRect.fRight - contentRect.fLeft) * 0.5f : 0.0f;
         canvas->clipRect(contentRect);
         canvas->translate(contentRect.fLeft, contentRect.fTop);
     }
 
-    canvas->clear(SK_ColorWHITE);
-    canvas->concat(fDefaultMatrix);
-    canvas->concat(computeMatrix());
+    // By default, we render directly into the window's surface/canvas
+    SkCanvas* slideCanvas = canvas;
 
-    if (inSplitScreen) {
-        sk_sp<SkSurface> offscreenSurface = fWindow->getOffscreenSurface(true);
-        offscreenSurface->getCanvas()->getMetaData().setBool(kImageColorXformMetaData, true);
-        fSlides[fCurrentSlide]->draw(offscreenSurface->getCanvas());
-        sk_sp<SkImage> snapshot = offscreenSurface->makeImageSnapshot();
-        canvas->drawImage(snapshot, 0, 0);
-    } else {
-        fSlides[fCurrentSlide]->draw(canvas);
+    // ... but if we're in F16, or the gamut isn't sRGB, we need to render offscreen
+    sk_sp<SkSurface> offscreenSurface = nullptr;
+    if (kRGBA_F16_SkColorType == fColorType || fColorSpace != SkColorSpace::MakeSRGB()) {
+        SkImageInfo info = SkImageInfo::Make(fWindow->width(), fWindow->height(), fColorType,
+                                             kPremul_SkAlphaType, fColorSpace);
+        offscreenSurface = canvas->makeSurface(info);
+        slideCanvas = offscreenSurface->getCanvas();
+    }
+
+    slideCanvas->clear(SK_ColorWHITE);
+    slideCanvas->concat(fDefaultMatrix);
+    slideCanvas->concat(computeMatrix());
+
+    fSlides[fCurrentSlide]->draw(slideCanvas);
+
+    // If we rendered offscreen, snap an image and push the results to the window's canvas
+    if (offscreenSurface) {
+        auto slideImage = offscreenSurface->makeImageSnapshot();
+
+        // Tag the image with the sRGB gamut, so no further color space conversion happens
+        sk_sp<SkColorSpace> cs = (kRGBA_F16_SkColorType == fColorType)
+            ? SkColorSpace::MakeSRGBLinear() : SkColorSpace::MakeSRGB();
+        auto retaggedImage = SkImageMakeRasterCopyAndAssignColorSpace(slideImage.get(), cs.get());
+        canvas->drawImage(retaggedImage, 0, 0);
     }
 
     canvas->restoreToCount(count);
-
-    if (inSplitScreen) {
-        // Draw split line
-        SkPaint paint;
-        SkScalar intervals[] = {10.0f, 5.0f};
-        paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f));
-        SkRect contentRect = fWindow->getContentRect();
-        SkScalar middleX = (contentRect.fLeft + contentRect.fRight) * 0.5f;
-        canvas->drawLine(middleX, contentRect.fTop, middleX, contentRect.fBottom, paint);
-    }
 }
 
 void Viewer::onPaint(SkCanvas* canvas) {
     // Record measurements
     double startTime = SkTime::GetMSecs();
 
-    drawSlide(canvas, false);
-    if (fSplitScreen && fWindow->supportsContentRect()) {
-        drawSlide(canvas, true);
-    }
+    drawSlide(canvas);
 
     if (fDisplayStats) {
         drawStats(canvas);
@@ -600,20 +619,11 @@
     fpsState[kValue] = SkStringPrintf("%8.3lf ms", measurement).c_str();
     fpsState[kOptions] = Json::Value(Json::arrayValue);
 
-    // Split screen state
-    Json::Value splitScreenState(Json::objectValue);
-    splitScreenState[kName] = kSplitScreenStateName;
-    splitScreenState[kValue] = fSplitScreen ? kON : kOFF;
-    splitScreenState[kOptions] = Json::Value(Json::arrayValue);
-    splitScreenState[kOptions].append(kON);
-    splitScreenState[kOptions].append(kOFF);
-
     Json::Value state(Json::arrayValue);
     state.append(slideState);
     state.append(backendState);
     state.append(softkeyState);
     state.append(fpsState);
-    state.append(splitScreenState);
 
     fWindow->setUIState(state);
 }
@@ -656,13 +666,6 @@
             fCommands.onSoftkey(stateValue);
             updateUIState(); // This is still needed to reset the value to kSoftkeyHint
         }
-    } else if (stateName.equals(kSplitScreenStateName)) {
-        bool newSplitScreen = stateValue.equals(kON);
-        if (newSplitScreen != fSplitScreen) {
-            fSplitScreen = newSplitScreen;
-            fWindow->inval();
-            updateUIState();
-        }
     } 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.
diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h
index 1ed135d..1608fa9 100644
--- a/tools/viewer/Viewer.h
+++ b/tools/viewer/Viewer.h
@@ -31,11 +31,12 @@
 private:
     void initSlides();
     void updateTitle();
+    void setColorMode(SkColorType, sk_sp<SkColorSpace>);
     void setupCurrentSlide(int previousSlide);
 
     void updateUIState();
 
-    void drawSlide(SkCanvas* canvs, bool inSplitScreen);
+    void drawSlide(SkCanvas* canvs);
     void drawStats(SkCanvas* canvas);
 
     void changeZoomLevel(float delta);
@@ -54,11 +55,12 @@
     bool                   fDisplayStats;
     bool                   fRefresh; // whether to continuously refresh for measuring render time
 
-    // whether to split the screen and draw two copies of the slide, one with sRGB and one without
-    bool                   fSplitScreen;
-
     sk_app::Window::BackendType fBackendType;
 
+    // Color properties for slide rendering
+    SkColorType            fColorType;
+    sk_sp<SkColorSpace>    fColorSpace;
+
     // transform data
     SkScalar               fZoomCenterX;
     SkScalar               fZoomCenterY;
diff --git a/tools/viewer/sk_app/DisplayParams.h b/tools/viewer/sk_app/DisplayParams.h
index b9a23f3..0c649c0 100644
--- a/tools/viewer/sk_app/DisplayParams.h
+++ b/tools/viewer/sk_app/DisplayParams.h
@@ -15,13 +15,11 @@
     DisplayParams()
         : fColorType(kN32_SkColorType)
         , fColorSpace(nullptr)
-        , fMSAASampleCount(0)
-        , fDeepColor(false) {}
+        , fMSAASampleCount(0) {}
 
     SkColorType         fColorType;
     sk_sp<SkColorSpace> fColorSpace;
     int                 fMSAASampleCount;
-    bool                fDeepColor;
 };
 
 }   // namespace sk_app
diff --git a/tools/viewer/sk_app/GLWindowContext.cpp b/tools/viewer/sk_app/GLWindowContext.cpp
index dd51b7e..501f272 100644
--- a/tools/viewer/sk_app/GLWindowContext.cpp
+++ b/tools/viewer/sk_app/GLWindowContext.cpp
@@ -39,11 +39,8 @@
 
     // We may not have real sRGB support (ANGLE, in particular), so check for
     // that, and fall back to L32:
-    //
-    // ... and, if we're using a 10-bit/channel FB0, it doesn't do sRGB conversion on write,
-    // so pretend that it's non-sRGB 8888:
-    fPixelConfig = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace &&
-                   (fColorBits != 30) ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
+    fPixelConfig = fContext->caps()->srgbSupport() && fDisplayParams.fColorSpace
+                   ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
 }
 
 void GLWindowContext::destroyContext() {
@@ -63,8 +60,6 @@
 
 sk_sp<SkSurface> GLWindowContext::getBackbufferSurface() {
     if (nullptr == fSurface) {
-        fActualColorBits = SkTMax(fColorBits, 24);
-
         if (fContext) {
             GrBackendRenderTargetDesc desc;
             desc.fWidth = this->fWidth;
@@ -77,7 +72,9 @@
             GR_GL_CALL(fBackendContext.get(), GetIntegerv(GR_GL_FRAMEBUFFER_BINDING, &buffer));
             desc.fRenderTargetHandle = buffer;
 
-            fSurface = this->createRenderSurface(desc, fActualColorBits);
+            fSurface = SkSurface::MakeFromBackendRenderTarget(fContext, desc,
+                                                              fDisplayParams.fColorSpace,
+                                                              &fSurfaceProps);
         }
     }
 
diff --git a/tools/viewer/sk_app/GLWindowContext.h b/tools/viewer/sk_app/GLWindowContext.h
index 7a3256eb..a7d1c98 100644
--- a/tools/viewer/sk_app/GLWindowContext.h
+++ b/tools/viewer/sk_app/GLWindowContext.h
@@ -55,11 +55,9 @@
 
     // parameters obtained from the native window
     // Note that the platform .cpp file is responsible for
-    // initializing fSampleCount, fStencilBits, and fColorBits!
+    // initializing fSampleCount and fStencilBits!
     int                        fSampleCount;
     int                        fStencilBits;
-    int                        fColorBits;
-    int                        fActualColorBits;
 };
 
 }   // namespace sk_app
diff --git a/tools/viewer/sk_app/VulkanWindowContext.cpp b/tools/viewer/sk_app/VulkanWindowContext.cpp
index 898710f..b4e6676 100644
--- a/tools/viewer/sk_app/VulkanWindowContext.cpp
+++ b/tools/viewer/sk_app/VulkanWindowContext.cpp
@@ -276,7 +276,9 @@
         desc.fStencilBits = 0;
         desc.fRenderTargetHandle = (GrBackendObject) &info;
 
-        fSurfaces[i] = this->createRenderSurface(desc, 24);
+        fSurfaces[i] = SkSurface::MakeFromBackendRenderTarget(fContext, desc,
+                                                              fDisplayParams.fColorSpace,
+                                                              &fSurfaceProps);
     }
 
     // create the command pool for the command buffers
diff --git a/tools/viewer/sk_app/Window.cpp b/tools/viewer/sk_app/Window.cpp
index 4a04363..dec1584 100644
--- a/tools/viewer/sk_app/Window.cpp
+++ b/tools/viewer/sk_app/Window.cpp
@@ -113,8 +113,4 @@
     fIsContentInvalidated = false;
 }
 
-sk_sp<SkSurface> Window::getOffscreenSurface(bool forceSRGB) {
-    return fWindowContext->createOffscreenSurface(forceSRGB);
-}
-
 }   // namespace sk_app
diff --git a/tools/viewer/sk_app/Window.h b/tools/viewer/sk_app/Window.h
index 36d5414..ea6f6c1 100644
--- a/tools/viewer/sk_app/Window.h
+++ b/tools/viewer/sk_app/Window.h
@@ -164,9 +164,6 @@
     virtual const DisplayParams& getDisplayParams();
     void setDisplayParams(const DisplayParams& params);
 
-    // This is just for the sRGB split screen
-    sk_sp<SkSurface> getOffscreenSurface(bool forceSRGB);
-
 protected:
     Window();
 
diff --git a/tools/viewer/sk_app/WindowContext.cpp b/tools/viewer/sk_app/WindowContext.cpp
deleted file mode 100644
index 8efe9bd..0000000
--- a/tools/viewer/sk_app/WindowContext.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-
-/*
- * Copyright 2015 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrContext.h"
-#include "SkSurface.h"
-#include "WindowContext.h"
-
-#include "gl/GrGLDefines.h"
-
-#include "gl/GrGLUtil.h"
-#include "GrRenderTarget.h"
-#include "GrContext.h"
-
-#include "SkCanvas.h"
-#include "SkImage_Base.h"
-
-namespace sk_app {
-
-sk_sp<SkSurface> WindowContext::createOffscreenSurface(bool forceSRGB) {
-    return createSurface(nullptr, 0, true, forceSRGB);
-}
-
-sk_sp<SkSurface> WindowContext::createRenderSurface(const GrBackendRenderTargetDesc& desc,
-                                                    int colorBits) {
-    return createSurface(&desc, colorBits, false, false);
-}
-
-sk_sp<SkSurface> WindowContext::createSurface(
-        const GrBackendRenderTargetDesc* rtDesc, int colorBits, bool offscreen, bool forceSRGB) {
-    if (!this->isGpuContext() || colorBits > 24 || offscreen ||
-        kRGBA_F16_SkColorType == fDisplayParams.fColorType) {
-        // If we're rendering to F16, we need an off-screen surface - the current render
-        // target is most likely the wrong format.
-        //
-        // If we're rendering raster data or using a deep (10-bit or higher) surface, we probably
-        // need an off-screen surface. 10-bit, in particular, has strange gamma behavior.
-        SkImageInfo info = SkImageInfo::Make(
-            fWidth, fHeight,
-            fDisplayParams.fColorType,
-            kPremul_SkAlphaType,
-            forceSRGB ? SkColorSpace::MakeSRGB()
-                      : fDisplayParams.fColorSpace
-        );
-        if (this->isGpuContext()) {
-            return SkSurface::MakeRenderTarget(fContext, SkBudgeted::kNo, info,
-                                               fDisplayParams.fMSAASampleCount, &fSurfaceProps);
-        } else {
-            return SkSurface::MakeRaster(info, &fSurfaceProps);
-        }
-    } else {
-        sk_sp<SkColorSpace> colorSpace = GrPixelConfigIsSRGB(rtDesc->fConfig)
-            ? SkColorSpace::MakeSRGB() : nullptr;
-        return SkSurface::MakeFromBackendRenderTarget(fContext, *rtDesc, colorSpace,
-                                                      &fSurfaceProps);
-    }
-}
-
-}   //namespace sk_app
diff --git a/tools/viewer/sk_app/WindowContext.h b/tools/viewer/sk_app/WindowContext.h
index 438d3c0..75edf2d 100644
--- a/tools/viewer/sk_app/WindowContext.h
+++ b/tools/viewer/sk_app/WindowContext.h
@@ -44,13 +44,9 @@
     virtual GrBackendContext getBackendContext() = 0;
     GrContext* getGrContext() const { return fContext; }
 
-    sk_sp<SkSurface> createOffscreenSurface(bool sRGB);
-
 protected:
     virtual bool isGpuContext() { return true;  }
 
-    sk_sp<SkSurface> createRenderSurface(const GrBackendRenderTargetDesc&, int colorBits);
-
     GrContext*        fContext;
 
     int               fWidth;
@@ -58,10 +54,6 @@
     DisplayParams     fDisplayParams;
     GrPixelConfig     fPixelConfig;
     SkSurfaceProps    fSurfaceProps;
-
-private:
-    sk_sp<SkSurface> createSurface(
-            const GrBackendRenderTargetDesc*, int colorBits, bool offscreen, bool forceSRGB);
 };
 
 }   // namespace sk_app
diff --git a/tools/viewer/sk_app/android/GLWindowContext_android.cpp b/tools/viewer/sk_app/android/GLWindowContext_android.cpp
index 20a7631..7dd813d 100644
--- a/tools/viewer/sk_app/android/GLWindowContext_android.cpp
+++ b/tools/viewer/sk_app/android/GLWindowContext_android.cpp
@@ -123,11 +123,6 @@
     glStencilMask(0xffffffff);
     glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 
-    int redBits, greenBits, blueBits;
-    eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_RED_SIZE, &redBits);
-    eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_GREEN_SIZE, &greenBits);
-    eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_BLUE_SIZE, &blueBits);
-    fColorBits = redBits + greenBits + blueBits;
     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_STENCIL_SIZE, &fStencilBits);
     eglGetConfigAttrib(fDisplay, surfaceConfig, EGL_SAMPLES, &fSampleCount);
 }
diff --git a/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp b/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp
index bc86df3..5bdba64 100644
--- a/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp
+++ b/tools/viewer/sk_app/mac/GLWindowContext_mac.cpp
@@ -66,12 +66,6 @@
         glStencilMask(0xffffffff);
         glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 
-        int redBits, greenBits, blueBits;
-        SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);
-        SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);
-        SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits);
-        fColorBits = redBits + greenBits + blueBits;
-
         SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &fStencilBits);
         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fSampleCount);
 
diff --git a/tools/viewer/sk_app/mac/RasterWindowContext_mac.cpp b/tools/viewer/sk_app/mac/RasterWindowContext_mac.cpp
index 4749bc7..a88ed13 100644
--- a/tools/viewer/sk_app/mac/RasterWindowContext_mac.cpp
+++ b/tools/viewer/sk_app/mac/RasterWindowContext_mac.cpp
@@ -78,12 +78,6 @@
         glStencilMask(0xffffffff);
         glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 
-        int redBits, greenBits, blueBits;
-        SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);
-        SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);
-        SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &blueBits);
-        fColorBits = redBits + greenBits + blueBits;
-
         SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &fStencilBits);
         SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fSampleCount);
 
@@ -115,21 +109,9 @@
         // We made/have an off-screen surface. Get the contents as an SkImage:
         sk_sp<SkImage> snapshot = fBackbufferSurface->makeImageSnapshot();
         
-        // With ten-bit output, we need to manually apply the gamma of the output device
-        // (unless we're in non-gamma correct mode, in which case our data is already
-        // fake-sRGB, like we're expected to put in the 10-bit buffer):
-        bool doGamma = (fActualColorBits == 30) &&
-                       (fDisplayParams.fColorSpace != nullptr ||
-                        kRGBA_F16_SkColorType == fDisplayParams.fColorType);
-        SkPaint gammaPaint;
-        gammaPaint.setBlendMode(SkBlendMode::kSrc);
-        if (doGamma) {
-            gammaPaint.setColorFilter(sk_tool_utils::MakeLinearToSRGBColorFilter());
-        }
-
         sk_sp<SkSurface> gpuSurface = INHERITED::getBackbufferSurface();
         SkCanvas* gpuCanvas = gpuSurface->getCanvas();
-        gpuCanvas->drawImage(snapshot, 0, 0, &gammaPaint);
+        gpuCanvas->drawImage(snapshot, 0, 0);
         gpuCanvas->flush();
 
         SDL_GL_SwapWindow(fWindow);
diff --git a/tools/viewer/sk_app/unix/GLWindowContext_unix.cpp b/tools/viewer/sk_app/unix/GLWindowContext_unix.cpp
index 6df1a52..ead7037 100644
--- a/tools/viewer/sk_app/unix/GLWindowContext_unix.cpp
+++ b/tools/viewer/sk_app/unix/GLWindowContext_unix.cpp
@@ -61,11 +61,6 @@
         glStencilMask(0xffffffff);
         glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
 
-        int redBits, greenBits, blueBits;
-        glXGetConfig(fDisplay, fVisualInfo, GLX_RED_SIZE, &redBits);
-        glXGetConfig(fDisplay, fVisualInfo, GLX_GREEN_SIZE, &greenBits);
-        glXGetConfig(fDisplay, fVisualInfo, GLX_BLUE_SIZE, &blueBits);
-        fColorBits = redBits + greenBits + blueBits;
         glXGetConfig(fDisplay, fVisualInfo, GLX_STENCIL_SIZE, &fStencilBits);
         glXGetConfig(fDisplay, fVisualInfo, GLX_SAMPLES_ARB, &fSampleCount);
 
diff --git a/tools/viewer/sk_app/win/GLWindowContext_win.cpp b/tools/viewer/sk_app/win/GLWindowContext_win.cpp
index bf1ddb9..055abf3 100644
--- a/tools/viewer/sk_app/win/GLWindowContext_win.cpp
+++ b/tools/viewer/sk_app/win/GLWindowContext_win.cpp
@@ -52,7 +52,7 @@
 void GLWindowContext_win::onInitializeContext() {
     HDC dc = GetDC(fHWND);
 
-    fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, fDisplayParams.fDeepColor,
+    fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
                                 kGLPreferCompatibilityProfile_SkWGLContextRequest);
     if (NULL == fHGLRC) {
         return;
@@ -69,8 +69,6 @@
         PIXELFORMATDESCRIPTOR pfd;
         DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
         fStencilBits = pfd.cStencilBits;
-        // pfd.cColorBits includes alpha, so it will be 32 in 8/8/8/8 and 10/10/10/2
-        fColorBits = pfd.cRedBits + pfd.cGreenBits + pfd.cBlueBits;
 
         // Get sample count if the MSAA WGL extension is present
         SkWGLExtensions extensions;