From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Birunthan Mohanathas <birunthan@mohanathas.com>
Date: Fri, 30 Nov 2018 12:44:12 +0200
Subject: disable_color_correct_rendering.patch

This adds a --disable-color-correct-rendering switch. In Electron 2.0,
`--disable-features=ColorCorrectRendering` could be
used to make the app use the display color space (e.g. P3 on Macs)
instead of color correcting to sRGB. Because color correct rendering is
always enabled on Chromium 62 and later and because
`--force-color-profile` has no effect on macOS, apps that need e.g. P3
colors are currently stuck on Electron 2.0.

This restores the functionality removed in
https://chromium-review.googlesource.com/698347 in the form of the
`--disable-color-correct-rendering` switch.

This can be removed once web content (including WebGL) learn how
to deal with color spaces. That is being tracked at
https://crbug.com/634542 and https://crbug.com/711107.

diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index ed8edf6ba74d22997ef51a2114cf7c9b7b08fdd5..c918fcc6fc450aa7438b96fa5f1d16093a8facef 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -1770,6 +1770,10 @@ void LayerTreeHostImpl::SetIsLikelyToRequireADraw(
 
 gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
     gfx::ContentColorUsage content_color_usage) const {
+  if (!settings_.enable_color_correct_rendering) {
+    return {};
+  }
+
   constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
 
   // If we are likely to software composite the resource, we use sRGB because
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h
index 63f087b74b93efe884df3833865e9aa7af912508..eb41d143ed1dd622a362b0f008a725034d6e1a97 100644
--- a/cc/trees/layer_tree_settings.h
+++ b/cc/trees/layer_tree_settings.h
@@ -97,6 +97,8 @@ class CC_EXPORT LayerTreeSettings {
   bool use_rgba_4444 = false;
   bool unpremultiply_and_dither_low_bit_depth_tiles = false;
 
+  bool enable_color_correct_rendering = true;
+
   // If set to true, the compositor may selectively defer image decodes to the
   // Image Decode Service and raster tiles without images until the decode is
   // ready.
diff --git a/components/viz/common/display/renderer_settings.h b/components/viz/common/display/renderer_settings.h
index 2e32385af86c6156c4197393248d70c470cdd4b5..350f56238e1c01cc6073555933f57df8cafca050 100644
--- a/components/viz/common/display/renderer_settings.h
+++ b/components/viz/common/display/renderer_settings.h
@@ -23,6 +23,7 @@ class VIZ_COMMON_EXPORT RendererSettings {
   RendererSettings(const RendererSettings& other);
   ~RendererSettings();
 
+  bool enable_color_correct_rendering = true;
   bool allow_antialiasing = true;
   bool force_antialiasing = false;
   bool force_blending_with_shaders = false;
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc
index 88045687f03cbefa8c2adaee65f6ada75d3f3e52..53cb6859dd951dd79f9d463c2bb2177268f1a251 100644
--- a/components/viz/host/renderer_settings_creation.cc
+++ b/components/viz/host/renderer_settings_creation.cc
@@ -17,6 +17,7 @@
 #include "components/viz/common/features.h"
 #include "components/viz/common/switches.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/gfx/switches.h"
 
 #if defined(OS_APPLE)
 #include "ui/base/cocoa/remote_layer_api.h"
@@ -54,6 +55,8 @@ bool GetSwitchValueAsInt(const base::CommandLine* command_line,
 RendererSettings CreateRendererSettings() {
   RendererSettings renderer_settings;
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+  renderer_settings.enable_color_correct_rendering =
+      !command_line->HasSwitch(switches::kDisableColorCorrectRendering);
   renderer_settings.partial_swap_enabled =
       !command_line->HasSwitch(switches::kUIDisablePartialSwap);
 #if defined(OS_APPLE)
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc
index 9f60a5f7b0062775b8451a82658b1c719775b332..7053104b6575991f2edbeff89028bd1b6c788a02 100644
--- a/components/viz/service/display/gl_renderer.cc
+++ b/components/viz/service/display/gl_renderer.cc
@@ -88,6 +88,9 @@
 
 using gpu::gles2::GLES2Interface;
 
+#define PATCH_CS(color_space) \
+  (settings_->enable_color_correct_rendering ? color_space : gfx::ColorSpace())
+
 namespace viz {
 namespace {
 
@@ -677,8 +680,9 @@ void GLRenderer::DoDrawQuad(const DrawQuad* quad,
 void GLRenderer::DrawDebugBorderQuad(const DebugBorderDrawQuad* quad) {
   SetBlendEnabled(quad->ShouldDrawWithBlending());
 
-  SetUseProgram(ProgramKey::DebugBorder(), gfx::ColorSpace::CreateSRGB(),
-                CurrentRenderPassColorSpace());
+  SetUseProgram(ProgramKey::DebugBorder(),
+                PATCH_CS(gfx::ColorSpace::CreateSRGB()),
+                PATCH_CS(CurrentRenderPassColorSpace()));
 
   // Use the full quad_rect for debug quads to not move the edges based on
   // partial swaps.
@@ -1662,7 +1666,8 @@ void GLRenderer::ChooseRPDQProgram(DrawRenderPassDrawQuadParams* params,
           params->use_color_matrix, tint_gl_composited_content_,
           params->apply_shader_based_rounded_corner &&
               ShouldApplyRoundedCorner(params->quad)),
-      params->contents_and_bypass_color_space, target_color_space);
+          PATCH_CS(params->contents_and_bypass_color_space),
+          PATCH_CS(target_color_space));
 }
 
 void GLRenderer::UpdateRPDQUniforms(DrawRenderPassDrawQuadParams* params) {
@@ -2136,15 +2141,16 @@ void GLRenderer::DrawSolidColorQuad(const SolidColorDrawQuad* quad,
   SetUseProgram(ProgramKey::SolidColor(use_aa ? USE_AA : NO_AA,
                                        tint_gl_composited_content_,
                                        ShouldApplyRoundedCorner(quad)),
-                CurrentRenderPassColorSpace(), CurrentRenderPassColorSpace());
+                PATCH_CS(CurrentRenderPassColorSpace()),
+                PATCH_CS(CurrentRenderPassColorSpace()));
 
   gfx::ColorSpace quad_color_space = gfx::ColorSpace::CreateSRGB();
   SkColor4f color_f = SkColor4f::FromColor(color);
 
   // Apply color transform if the color space or source and target do not match.
-  if (quad_color_space != CurrentRenderPassColorSpace()) {
+  if (PATCH_CS(quad_color_space) != PATCH_CS(CurrentRenderPassColorSpace())) {
     const gfx::ColorTransform* color_transform =
-        GetColorTransform(quad_color_space, CurrentRenderPassColorSpace());
+        GetColorTransform(PATCH_CS(quad_color_space), PATCH_CS(CurrentRenderPassColorSpace()));
     gfx::ColorTransform::TriStim col(color_f.fR, color_f.fG, color_f.fB);
     color_transform->Transform(&col, 1);
     color_f.fR = col.x();
@@ -2366,7 +2372,8 @@ void GLRenderer::DrawContentQuadAA(const ContentDrawQuadBase* quad,
                                               : NON_PREMULTIPLIED_ALPHA,
                        false, false, tint_gl_composited_content_,
                        ShouldApplyRoundedCorner(quad)),
-      quad_resource_lock.color_space(), CurrentRenderPassColorSpace());
+      PATCH_CS(quad_resource_lock.color_space()),
+      PATCH_CS(CurrentRenderPassColorSpace()));
 
   if (current_program_->tint_color_matrix_location() != -1) {
     auto matrix = cc::DebugColors::TintCompositedContentColorTransformMatrix();
@@ -2465,7 +2472,8 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
                        !quad->ShouldDrawWithBlending(), has_tex_clamp_rect,
                        tint_gl_composited_content_,
                        ShouldApplyRoundedCorner(quad)),
-      quad_resource_lock.color_space(), CurrentRenderPassColorSpace());
+      PATCH_CS(quad_resource_lock.color_space()),
+      PATCH_CS(CurrentRenderPassColorSpace()));
 
   if (current_program_->tint_color_matrix_location() != -1) {
     auto matrix = cc::DebugColors::TintCompositedContentColorTransformMatrix();
@@ -2575,7 +2583,8 @@ void GLRenderer::DrawYUVVideoQuad(const YUVVideoDrawQuad* quad,
   // The source color space should never be RGB.
   DCHECK_NE(src_color_space, src_color_space.GetAsFullRangeRGB());
 
-  gfx::ColorSpace dst_color_space = CurrentRenderPassColorSpace();
+  gfx::ColorSpace dst_color_space =
+      PATCH_CS(CurrentRenderPassColorSpace());
 
 #if defined(OS_WIN)
   // Force sRGB output on Windows for overlay candidate video quads to match
@@ -2755,7 +2764,8 @@ void GLRenderer::DrawStreamVideoQuad(const StreamVideoDrawQuad* quad,
 
   SetUseProgram(ProgramKey::VideoStream(tex_coord_precision,
                                         ShouldApplyRoundedCorner(quad)),
-                lock.color_space(), CurrentRenderPassColorSpace());
+                PATCH_CS(lock.color_space()),
+                PATCH_CS(CurrentRenderPassColorSpace()));
 
   DCHECK_EQ(GL_TEXTURE0, GetActiveTextureUnit(gl_));
   gl_->BindTexture(GL_TEXTURE_EXTERNAL_OES, lock.texture_id());
@@ -2826,8 +2836,8 @@ void GLRenderer::FlushTextureQuadCache(BoundGeometry flush_binding) {
       draw_cache_.nearest_neighbor ? GL_NEAREST : GL_LINEAR);
 
   // Bind the program to the GL state.
-  SetUseProgram(draw_cache_.program_key, locked_quad.color_space(),
-                CurrentRenderPassColorSpace(),
+  SetUseProgram(draw_cache_.program_key, PATCH_CS(locked_quad.color_space()),
+                PATCH_CS(CurrentRenderPassColorSpace()),
                 /*adjust_src_white_level=*/draw_cache_.is_video_frame);
 
   if (current_program_->rounded_corner_rect_location() != -1) {
@@ -3654,7 +3664,9 @@ void GLRenderer::SetUseProgram(const ProgramKey& program_key_no_color,
                                const gfx::ColorSpace& src_color_space,
                                const gfx::ColorSpace& dst_color_space,
                                bool adjust_src_white_level) {
-  DCHECK(dst_color_space.IsValid());
+  if (settings_->enable_color_correct_rendering) {
+    DCHECK(dst_color_space.IsValid());
+  }
   gfx::ColorSpace adjusted_src_color_space = src_color_space;
   if (adjust_src_white_level) {
     // If the input color space is HDR, and it did not specify a white level,
@@ -4034,9 +4046,9 @@ void GLRenderer::CopyRenderPassDrawQuadToOverlayResource(
         cc::MathUtil::CheckedRoundUp(iosurface_height, iosurface_multiple);
   }
 
-  *overlay_texture =
-      FindOrCreateOverlayTexture(params.quad->render_pass_id, iosurface_width,
-                                 iosurface_height, RootRenderPassColorSpace());
+  *overlay_texture = FindOrCreateOverlayTexture(
+      params.quad->render_pass_id, iosurface_width, iosurface_height,
+      PATCH_CS(RootRenderPassColorSpace()));
   *new_bounds = gfx::RectF(updated_dst_rect.origin(),
                            gfx::SizeF((*overlay_texture)->texture.size()));
 
@@ -4256,8 +4268,8 @@ void GLRenderer::FlushOverdrawFeedback(const gfx::Rect& output_rect) {
 
   PrepareGeometry(SHARED_BINDING);
 
-  SetUseProgram(ProgramKey::DebugBorder(), gfx::ColorSpace::CreateSRGB(),
-                CurrentRenderPassColorSpace());
+  SetUseProgram(ProgramKey::DebugBorder(), PATCH_CS(gfx::ColorSpace::CreateSRGB()),
+                PATCH_CS(CurrentRenderPassColorSpace()));
 
   gfx::Transform render_matrix;
   render_matrix.Translate(0.5 * output_rect.width() + output_rect.x(),
@@ -4447,3 +4459,5 @@ GLRenderer::OverlayTexture::OverlayTexture() = default;
 GLRenderer::OverlayTexture::~OverlayTexture() = default;
 
 }  // namespace viz
+
+#undef PATCH_CS
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index d5d68aa5a40b577d7d7b545cdc67f60e18acdf86..8ab5b75d7eee5f3e17b997abcd84f504ec6283ea 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -223,6 +223,7 @@ GpuTerminationStatus ConvertToGpuTerminationStatus(
 
 // Command-line switches to propagate to the GPU process.
 static const char* const kSwitchNames[] = {
+    switches::kDisableColorCorrectRendering,
     sandbox::policy::switches::kDisableSeccompFilterSandbox,
     sandbox::policy::switches::kGpuSandboxAllowSysVShm,
     sandbox::policy::switches::kGpuSandboxFailuresFatal,
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 894e527847ee338e4377740d59dfeb308f286fc5..34a066bf4ec85ec4ec5606861320b0e1a1f9793b 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -218,6 +218,7 @@
 #include "ui/accessibility/accessibility_switches.h"
 #include "ui/base/ui_base_switches.h"
 #include "ui/display/display_switches.h"
+#include "ui/gfx/switches.h"
 #include "ui/gl/gl_switches.h"
 #include "ui/native_theme/native_theme_features.h"
 #include "url/origin.h"
@@ -3175,6 +3176,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
   // Propagate the following switches to the renderer command line (along
   // with any associated values) if present in the browser command line.
   static const char* const kSwitchNames[] = {
+    switches::kDisableColorCorrectRendering,
     network::switches::kExplicitlyAllowedPorts,
     switches::kDisableInProcessStackTraces,
     sandbox::policy::switches::kDisableSeccompFilterSandbox,
diff --git a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
index 9bd9885624666a8d65b0b1bb710c79077321c451..ff5842db80d81adc8f17d2eef36e82d37dbdbe47 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_color_params.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
 
+#include "base/command_line.h"
 #include "cc/paint/skia_paint_canvas.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_params.h"
@@ -14,6 +15,7 @@
 #include "third_party/khronos/GLES3/gl3.h"
 #include "third_party/skia/include/core/SkSurfaceProps.h"
 #include "ui/gfx/color_space.h"
+#include "ui/gfx/switches.h"
 
 namespace blink {
 
@@ -144,6 +146,11 @@ uint8_t CanvasColorParams::BytesPerPixel() const {
 }
 
 gfx::ColorSpace CanvasColorParams::GetStorageGfxColorSpace() const {
+  auto* cmd_line = base::CommandLine::ForCurrentProcess();
+  if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+    return gfx::ColorSpace();
+  }
+
   return CanvasColorSpaceToGfxColorSpace(color_space_);
 }
 
diff --git a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
index 2c8e7445e9226f4860a0d36284e0cf770dbaa233..6cabd21b8dd996578d9aa02a553d4e3bca5fde04 100644
--- a/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
+++ b/third_party/blink/renderer/platform/widget/compositing/layer_tree_settings.cc
@@ -24,6 +24,7 @@
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/base/ui_base_switches.h"
+#include "ui/gfx/switches.h"
 #include "ui/native_theme/native_theme_features.h"
 #include "ui/native_theme/overlay_scrollbar_constants_aura.h"
 
@@ -177,6 +178,9 @@ cc::LayerTreeSettings GenerateLayerTreeSettings(
   settings.main_frame_before_activation_enabled =
       cmd.HasSwitch(cc::switches::kEnableMainFrameBeforeActivation);
 
+  settings.enable_color_correct_rendering =
+      !cmd.HasSwitch(::switches::kDisableColorCorrectRendering);
+
   // Checkerimaging is not supported for synchronous single-threaded mode, which
   // is what the renderer uses if its not threaded.
   settings.enable_checker_imaging =
diff --git a/ui/gfx/mac/io_surface.cc b/ui/gfx/mac/io_surface.cc
index e5fd0a36f83e14f13ad37525266076d791829900..f75d17d9506e7f9aad9f95a9a2026db4dda2706e 100644
--- a/ui/gfx/mac/io_surface.cc
+++ b/ui/gfx/mac/io_surface.cc
@@ -20,6 +20,7 @@
 #include "ui/gfx/buffer_format_util.h"
 #include "ui/gfx/color_space.h"
 #include "ui/gfx/icc_profile.h"
+#include "ui/gfx/switches.h"
 
 namespace gfx {
 
@@ -131,6 +132,14 @@ void IOSurfaceMachPortTraits::Release(mach_port_t port) {
 // Common method used by IOSurfaceSetColorSpace and IOSurfaceCanSetColorSpace.
 bool IOSurfaceSetColorSpace(IOSurfaceRef io_surface,
                             const ColorSpace& color_space) {
+  auto* cmd_line = base::CommandLine::ForCurrentProcess();
+  if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+    base::ScopedCFTypeRef<CFDataRef> system_icc(
+        CGColorSpaceCopyICCProfile(base::mac::GetSystemColorSpace()));
+    IOSurfaceSetValue(io_surface, CFSTR("IOSurfaceColorSpace"), system_icc);
+    return true;
+  }
+
   // Allow but ignore invalid color spaces.
   if (!color_space.IsValid())
     return true;
@@ -297,6 +306,15 @@ IOSurfaceRef CreateIOSurface(const gfx::Size& size,
     DCHECK_EQ(kIOReturnSuccess, r);
   }
 
+  auto* cmd_line = base::CommandLine::ForCurrentProcess();
+  if (cmd_line->HasSwitch(switches::kDisableColorCorrectRendering)) {
+    CGColorSpaceRef color_space = base::mac::GetSystemColorSpace();
+    base::ScopedCFTypeRef<CFDataRef> color_space_icc(
+        CGColorSpaceCopyICCProfile(color_space));
+    IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), color_space_icc);
+    return surface;
+  }
+
   // Ensure that all IOSurfaces start as sRGB.
   if (__builtin_available(macos 10.12, *)) {
     IOSurfaceSetValue(surface, CFSTR("IOSurfaceColorSpace"), kCGColorSpaceSRGB);
diff --git a/ui/gfx/switches.cc b/ui/gfx/switches.cc
index 16eeda0d910c555aae074fe1ed8ba04c4be76d9e..095b704442f55e978c7f60e9c97c2abe20b131a7 100644
--- a/ui/gfx/switches.cc
+++ b/ui/gfx/switches.cc
@@ -10,6 +10,7 @@ namespace switches {
 // Scale factor to apply to every animation duration. Must be >= 0.0. This will
 // only apply to LinearAnimation and its subclasses.
 const char kAnimationDurationScale[] = "animation-duration-scale";
+const char kDisableColorCorrectRendering[] = "disable-color-correct-rendering";
 
 // Force disables font subpixel positioning. This affects the character glyph
 // sharpness, kerning, hinting and layout.
diff --git a/ui/gfx/switches.h b/ui/gfx/switches.h
index fa86fc52621f4cf12bad58f8c1dd7ca6b29a307c..6b98b75c05643036ecd0fb71a8682ee1088ac52e 100644
--- a/ui/gfx/switches.h
+++ b/ui/gfx/switches.h
@@ -11,6 +11,8 @@
 namespace switches {
 
 GFX_SWITCHES_EXPORT extern const char kAnimationDurationScale[];
+GFX_SWITCHES_EXPORT extern const char kDisableColorCorrectRendering[];
+
 GFX_SWITCHES_EXPORT extern const char kDisableFontSubpixelPositioning[];
 GFX_SWITCHES_EXPORT extern const char kDisableYuv420Biplanar[];
 GFX_SWITCHES_EXPORT extern const char kEnableNativeGpuMemoryBuffers[];
