Commit bbf8442c authored by Christopher Cameron's avatar Christopher Cameron Committed by Commit Bot

Add gfx::DisplayColorSpaces and use in display::Display

The concept of "the color space of the display" falls apart on several
platforms, because display (or OS) can be configured to handle multiple
color spaces. Rather than sending a single color space, send a set of
color spaces to use in various situations (sRGB-only content, SDR WCG
content, and HDR content).

Use this gfx::DisplayColorSpaces structure in display::Display, instead
of using gfx::ColorSpace and sdr_white_point. Also communicate this
via mojo, which had not been done in the past.

For now, only use the "HDR transparent" color space. The next patch
use this structure in ui::Compositor, viz::Display, and
viz::SurfaceAggregator. This structure is added to gfx because it is
imported from these several locations.

Bug: 1037954, 1038770, 1038494, 958166
Change-Id: I677e3f5c4d01deeb95f76b6463541eec2163b48b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2006068Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Commit-Queue: ccameron <ccameron@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732874}
parent 57971004
...@@ -323,16 +323,25 @@ void Display::SetSize(const gfx::Size& size_in_pixel) { ...@@ -323,16 +323,25 @@ void Display::SetSize(const gfx::Size& size_in_pixel) {
SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel)); SetScaleAndBounds(device_scale_factor_, gfx::Rect(origin, size_in_pixel));
} }
gfx::ColorSpace Display::color_space() const {
return color_spaces_.hdr_transparent;
}
void Display::set_color_space(const gfx::ColorSpace& color_space) {
color_spaces_ = gfx::DisplayColorSpaces(color_space);
}
float Display::sdr_white_level() const {
return color_spaces_.sdr_white_level;
}
void Display::SetColorSpaceAndDepth(const gfx::ColorSpace& color_space, void Display::SetColorSpaceAndDepth(const gfx::ColorSpace& color_space,
float sdr_white_level) { float sdr_white_level) {
color_space_ = color_space; color_spaces_ = gfx::DisplayColorSpaces(color_space);
sdr_white_level_ = sdr_white_level; color_spaces_.sdr_white_level = sdr_white_level;
if (color_space_ == gfx::ColorSpace::CreateHDR10()) { if (color_spaces_.SupportsHDR()) {
color_depth_ = kHDR10BitsPerPixel; color_depth_ = kHDR10BitsPerPixel;
depth_per_component_ = kHDR10BitsPerComponent; depth_per_component_ = kHDR10BitsPerComponent;
} else if (color_space == gfx::ColorSpace::CreateSCRGBLinear()) {
color_depth_ = kSCRGBLinearBitsPerPixel;
depth_per_component_ = kSCRGBLinearBitsPerComponent;
} else { } else {
color_depth_ = kDefaultBitsPerPixel; color_depth_ = kDefaultBitsPerPixel;
depth_per_component_ = kDefaultBitsPerComponent; depth_per_component_ = kDefaultBitsPerComponent;
...@@ -394,7 +403,8 @@ bool Display::operator==(const Display& rhs) const { ...@@ -394,7 +403,8 @@ bool Display::operator==(const Display& rhs) const {
rotation_ == rhs.rotation_ && touch_support_ == rhs.touch_support_ && rotation_ == rhs.rotation_ && touch_support_ == rhs.touch_support_ &&
accelerometer_support_ == rhs.accelerometer_support_ && accelerometer_support_ == rhs.accelerometer_support_ &&
maximum_cursor_size_ == rhs.maximum_cursor_size_ && maximum_cursor_size_ == rhs.maximum_cursor_size_ &&
color_space_ == rhs.color_space_ && color_depth_ == rhs.color_depth_ && color_spaces_ == rhs.color_spaces_ &&
color_depth_ == rhs.color_depth_ &&
depth_per_component_ == rhs.depth_per_component_ && depth_per_component_ == rhs.depth_per_component_ &&
is_monochrome_ == rhs.is_monochrome_ && is_monochrome_ == rhs.is_monochrome_ &&
display_frequency_ == rhs.display_frequency_; display_frequency_ == rhs.display_frequency_;
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "mojo/public/cpp/bindings/struct_traits.h" #include "mojo/public/cpp/bindings/struct_traits.h"
#include "ui/display/display_export.h" #include "ui/display/display_export.h"
#include "ui/display/types/display_constants.h" #include "ui/display/types/display_constants.h"
#include "ui/gfx/color_space.h" #include "ui/gfx/display_color_spaces.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
namespace display { namespace display {
...@@ -226,13 +226,17 @@ class DISPLAY_EXPORT Display final { ...@@ -226,13 +226,17 @@ class DISPLAY_EXPORT Display final {
} }
// The color space of the display. // The color space of the display.
gfx::ColorSpace color_space() const { return color_space_; } // TODO: This is to be removed and replaced by gfx::DisplayColorSpaces.
void set_color_space(const gfx::ColorSpace& color_space) { gfx::ColorSpace color_space() const;
color_space_ = color_space; void set_color_space(const gfx::ColorSpace& color_space);
const gfx::DisplayColorSpaces& color_spaces() const { return color_spaces_; }
void set_color_spaces(const gfx::DisplayColorSpaces& color_spaces) {
color_spaces_ = color_spaces;
} }
// SDR white level used to scale HDR color spaces. // SDR white level used to scale HDR color spaces.
float sdr_white_level() const { return sdr_white_level_; } // TODO: This is to be removed in favor of GetColorSpaces.
float sdr_white_level() const;
// Set the color space and SDR white level of the display, and reset the color // Set the color space and SDR white level of the display, and reset the color
// depth and depth per component based on whether the color space is HDR. // depth and depth per component based on whether the color space is HDR.
...@@ -279,9 +283,6 @@ class DISPLAY_EXPORT Display final { ...@@ -279,9 +283,6 @@ class DISPLAY_EXPORT Display final {
private: private:
friend struct mojo::StructTraits<mojom::DisplayDataView, Display>; friend struct mojo::StructTraits<mojom::DisplayDataView, Display>;
static constexpr int kSCRGBLinearBitsPerPixel = 48;
static constexpr int kSCRGBLinearBitsPerComponent = 16;
int64_t id_ = kInvalidDisplayId; int64_t id_ = kInvalidDisplayId;
gfx::Rect bounds_; gfx::Rect bounds_;
// If non-empty, then should be same size as |bounds_|. Used to avoid rounding // If non-empty, then should be same size as |bounds_|. Used to avoid rounding
...@@ -294,10 +295,7 @@ class DISPLAY_EXPORT Display final { ...@@ -294,10 +295,7 @@ class DISPLAY_EXPORT Display final {
TouchSupport touch_support_ = TouchSupport::UNKNOWN; TouchSupport touch_support_ = TouchSupport::UNKNOWN;
AccelerometerSupport accelerometer_support_ = AccelerometerSupport::UNKNOWN; AccelerometerSupport accelerometer_support_ = AccelerometerSupport::UNKNOWN;
gfx::Size maximum_cursor_size_; gfx::Size maximum_cursor_size_;
// NOTE: this is not currently written to the mojom as it is not used in gfx::DisplayColorSpaces color_spaces_;
// aura.
gfx::ColorSpace color_space_;
float sdr_white_level_;
int color_depth_; int color_depth_;
int depth_per_component_; int depth_per_component_;
bool is_monochrome_ = false; bool is_monochrome_ = false;
......
...@@ -81,8 +81,8 @@ TEST(DisplayTest, DisplayHDRValues) { ...@@ -81,8 +81,8 @@ TEST(DisplayTest, DisplayHDRValues) {
EXPECT_EQ(10, display.depth_per_component()); EXPECT_EQ(10, display.depth_per_component());
display.SetColorSpaceAndDepth(gfx::ColorSpace::CreateSCRGBLinear()); display.SetColorSpaceAndDepth(gfx::ColorSpace::CreateSCRGBLinear());
EXPECT_EQ(48, display.color_depth()); EXPECT_EQ(30, display.color_depth());
EXPECT_EQ(16, display.depth_per_component()); EXPECT_EQ(10, display.depth_per_component());
display.SetColorSpaceAndDepth(gfx::ColorSpace::CreateSRGB()); display.SetColorSpaceAndDepth(gfx::ColorSpace::CreateSRGB());
EXPECT_EQ(24, display.color_depth()); EXPECT_EQ(24, display.color_depth());
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
module display.mojom; module display.mojom;
import "ui/gfx/geometry/mojom/geometry.mojom"; import "ui/gfx/geometry/mojom/geometry.mojom";
import "ui/gfx/mojom/display_color_spaces.mojom";
// Corresponds to display::Display::Rotation. // Corresponds to display::Display::Rotation.
enum Rotation { enum Rotation {
...@@ -39,6 +40,7 @@ struct Display { ...@@ -39,6 +40,7 @@ struct Display {
TouchSupport touch_support; TouchSupport touch_support;
AccelerometerSupport accelerometer_support; AccelerometerSupport accelerometer_support;
gfx.mojom.Size maximum_cursor_size; gfx.mojom.Size maximum_cursor_size;
gfx.mojom.DisplayColorSpaces color_spaces;
int32 color_depth; int32 color_depth;
int32 depth_per_component; int32 depth_per_component;
bool is_monochrome; bool is_monochrome;
......
...@@ -140,6 +140,9 @@ bool StructTraits<display::mojom::DisplayDataView, display::Display>::Read( ...@@ -140,6 +140,9 @@ bool StructTraits<display::mojom::DisplayDataView, display::Display>::Read(
if (!data.ReadMaximumCursorSize(&out->maximum_cursor_size_)) if (!data.ReadMaximumCursorSize(&out->maximum_cursor_size_))
return false; return false;
if (!data.ReadColorSpaces(&out->color_spaces_))
return false;
out->set_color_depth(data.color_depth()); out->set_color_depth(data.color_depth());
out->set_depth_per_component(data.depth_per_component()); out->set_depth_per_component(data.depth_per_component());
out->set_is_monochrome(data.is_monochrome()); out->set_is_monochrome(data.is_monochrome());
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/display/mojom/display.mojom.h" #include "ui/display/mojom/display.mojom.h"
#include "ui/gfx/geometry/mojom/geometry_mojom_traits.h" #include "ui/gfx/geometry/mojom/geometry_mojom_traits.h"
#include "ui/gfx/mojom/display_color_spaces_mojom_traits.h"
namespace mojo { namespace mojo {
...@@ -74,6 +75,10 @@ struct StructTraits<display::mojom::DisplayDataView, display::Display> { ...@@ -74,6 +75,10 @@ struct StructTraits<display::mojom::DisplayDataView, display::Display> {
return display.maximum_cursor_size(); return display.maximum_cursor_size();
} }
static gfx::DisplayColorSpaces color_spaces(const display::Display& display) {
return display.color_spaces();
}
static int32_t color_depth(const display::Display& display) { static int32_t color_depth(const display::Display& display) {
return display.color_depth(); return display.color_depth();
} }
......
...@@ -419,6 +419,8 @@ jumbo_component("color_space") { ...@@ -419,6 +419,8 @@ jumbo_component("color_space") {
"color_space.cc", "color_space.cc",
"color_space.h", "color_space.h",
"color_space_export.h", "color_space_export.h",
"display_color_spaces.cc",
"display_color_spaces.h",
"icc_profile.cc", "icc_profile.cc",
"icc_profile.h", "icc_profile.h",
"skia_color_space_util.cc", "skia_color_space_util.cc",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/display_color_spaces.h"
namespace gfx {
DisplayColorSpaces::DisplayColorSpaces() = default;
DisplayColorSpaces::DisplayColorSpaces(const gfx::ColorSpace& c)
: srgb(c),
wcg_opaque(c),
wcg_transparent(c),
hdr_opaque(c),
hdr_transparent(c) {}
gfx::ColorSpace DisplayColorSpaces::GetRasterColorSpace() const {
return hdr_transparent.GetRasterColorSpace();
}
gfx::ColorSpace DisplayColorSpaces::GetCompositingColorSpace() const {
if (SupportsHDR())
return gfx::ColorSpace::CreateExtendedSRGB();
return hdr_transparent;
}
gfx::ColorSpace DisplayColorSpaces::GetOutputColorSpace(
bool needs_alpha) const {
if (needs_alpha)
return hdr_transparent;
else
return hdr_opaque;
}
bool DisplayColorSpaces::IsSuitableForOutput(
const gfx::ColorSpace& color_space) const {
return color_space == hdr_opaque || color_space == hdr_transparent;
}
bool DisplayColorSpaces::SupportsHDR() const {
return hdr_opaque.IsHDR() && hdr_transparent.IsHDR();
}
bool DisplayColorSpaces::operator==(const DisplayColorSpaces& other) const {
return srgb == other.srgb && wcg_opaque == other.wcg_opaque &&
wcg_transparent == other.wcg_transparent &&
hdr_opaque == other.hdr_opaque &&
hdr_transparent == other.hdr_transparent &&
sdr_white_level == other.sdr_white_level;
}
bool DisplayColorSpaces::operator!=(const DisplayColorSpaces& other) const {
return !(*this == other);
}
} // namespace gfx
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GFX_DISPLAY_COLOR_SPACES_H_
#define UI_GFX_DISPLAY_COLOR_SPACES_H_
#include "ui/gfx/color_space.h"
#include "ui/gfx/color_space_export.h"
namespace gfx {
// This structure is used by a display::Display to specify the color space that
// should be used to display content of various types. This lives in here, as
// opposed to in ui/display because it is used directly by components/viz.
struct COLOR_SPACE_EXPORT DisplayColorSpaces {
// Initialize as sRGB-only.
DisplayColorSpaces();
// Initialize as |color_space| for all settings.
explicit DisplayColorSpaces(const ColorSpace& color_space);
// Return the color space that should be used for rasterization.
gfx::ColorSpace GetRasterColorSpace() const;
// Return the color space in which compositing (and, in particular, blending,
// should be performed). This space may not (on Windows) be suitable for
// output.
// TODO: This will take arguments regarding the presence of WCG and HDR
// content, and whether or not an alpha channel will be needed.
gfx::ColorSpace GetCompositingColorSpace() const;
// Return the color space to use for output.
gfx::ColorSpace GetOutputColorSpace(bool needs_alpha) const;
// Return true if |color_space| is a valid output color space. If it is not,
// and is the color space for the root RenderPass, then an additional pass
// will be added to a color space from GetOutputColorSpace.
bool IsSuitableForOutput(const gfx::ColorSpace& color_space) const;
// Return true if the HDR color spaces are, indeed, HDR.
bool SupportsHDR() const;
bool operator==(const DisplayColorSpaces& other) const;
bool operator!=(const DisplayColorSpaces& other) const;
// The color space to use for SDR content that is limited to the sRGB gamut.
ColorSpace srgb = ColorSpace::CreateSRGB();
// For opaque and transparent SDR content that is larger than the sRGB gamut.
ColorSpace wcg_opaque = ColorSpace::CreateSRGB();
ColorSpace wcg_transparent = ColorSpace::CreateSRGB();
// For opaque and transparent HDR content.
ColorSpace hdr_opaque = ColorSpace::CreateSRGB();
ColorSpace hdr_transparent = ColorSpace::CreateSRGB();
// The SDR white level in nits. This varies only on Windows.
float sdr_white_level = ColorSpace::kDefaultSDRWhiteLevel;
};
} // namespace gfx
#endif // UI_GFX_DISPLAY_COLOR_SPACES_H_
...@@ -11,6 +11,7 @@ mojom("mojom") { ...@@ -11,6 +11,7 @@ mojom("mojom") {
"buffer_types.mojom", "buffer_types.mojom",
"ca_layer_params.mojom", "ca_layer_params.mojom",
"color_space.mojom", "color_space.mojom",
"display_color_spaces.mojom",
"font_render_params.mojom", "font_render_params.mojom",
"gpu_fence_handle.mojom", "gpu_fence_handle.mojom",
"overlay_transform.mojom", "overlay_transform.mojom",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module gfx.mojom;
import "ui/gfx/mojom/color_space.mojom";
struct DisplayColorSpaces {
ColorSpace srgb;
ColorSpace wcg_opaque;
ColorSpace wcg_transparent;
ColorSpace hdr_opaque;
ColorSpace hdr_transparent;
float sdr_white_level;
};
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
mojom = "//ui/gfx/mojom/display_color_spaces.mojom"
public_headers = [ "//ui/gfx/display_color_spaces.h" ]
traits_headers = [ "//ui/gfx/mojom/display_color_spaces_mojom_traits.h" ]
sources = [ "//ui/gfx/mojom/display_color_spaces_mojom_traits.cc" ]
public_deps = [ "//ui/gfx" ]
type_mappings = [ "gfx.mojom.DisplayColorSpaces=::gfx::DisplayColorSpaces" ]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/gfx/mojom/display_color_spaces_mojom_traits.h"
namespace mojo {
// static
bool StructTraits<
gfx::mojom::DisplayColorSpacesDataView,
gfx::DisplayColorSpaces>::Read(gfx::mojom::DisplayColorSpacesDataView input,
gfx::DisplayColorSpaces* out) {
if (!input.ReadSrgb(&out->srgb))
return false;
if (!input.ReadWcgOpaque(&out->wcg_opaque))
return false;
if (!input.ReadWcgTransparent(&out->wcg_transparent))
return false;
if (!input.ReadHdrOpaque(&out->hdr_opaque))
return false;
if (!input.ReadHdrTransparent(&out->hdr_transparent))
return false;
out->sdr_white_level = input.sdr_white_level();
return true;
}
} // namespace mojo
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_GFX_MOJOM_DISPLAY_COLOR_SPACES_MOJOM_TRAITS_H_
#define UI_GFX_MOJOM_DISPLAY_COLOR_SPACES_MOJOM_TRAITS_H_
#include "base/containers/span.h"
#include "ui/gfx/display_color_spaces.h"
#include "ui/gfx/mojom/color_space_mojom_traits.h"
#include "ui/gfx/mojom/display_color_spaces.mojom.h"
namespace mojo {
template <>
struct StructTraits<gfx::mojom::DisplayColorSpacesDataView,
gfx::DisplayColorSpaces> {
static gfx::ColorSpace srgb(const gfx::DisplayColorSpaces& input) {
return input.srgb;
}
static gfx::ColorSpace wcg_opaque(const gfx::DisplayColorSpaces& input) {
return input.wcg_opaque;
}
static gfx::ColorSpace wcg_transparent(const gfx::DisplayColorSpaces& input) {
return input.wcg_transparent;
}
static gfx::ColorSpace hdr_opaque(const gfx::DisplayColorSpaces& input) {
return input.hdr_opaque;
}
static gfx::ColorSpace hdr_transparent(const gfx::DisplayColorSpaces& input) {
return input.hdr_transparent;
}
static float sdr_white_level(const gfx::DisplayColorSpaces& input) {
return input.sdr_white_level;
}
static bool Read(gfx::mojom::DisplayColorSpacesDataView data,
gfx::DisplayColorSpaces* out);
};
} // namespace mojo
#endif // UI_GFX_MOJOM_DISPLAY_COLOR_SPACES_MOJOM_TRAITS_H_
...@@ -9,6 +9,7 @@ typemaps = [ ...@@ -9,6 +9,7 @@ typemaps = [
"//ui/gfx/mojom/buffer_types.typemap", "//ui/gfx/mojom/buffer_types.typemap",
"//ui/gfx/mojom/ca_layer_params.typemap", "//ui/gfx/mojom/ca_layer_params.typemap",
"//ui/gfx/mojom/color_space.typemap", "//ui/gfx/mojom/color_space.typemap",
"//ui/gfx/mojom/display_color_spaces.typemap",
"//ui/gfx/mojom/font_render_params.typemap", "//ui/gfx/mojom/font_render_params.typemap",
"//ui/gfx/mojom/gpu_fence_handle.typemap", "//ui/gfx/mojom/gpu_fence_handle.typemap",
"//ui/gfx/mojom/overlay_transform.typemap", "//ui/gfx/mojom/overlay_transform.typemap",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment