Commit 8cc46420 authored by Prashant Nevase's avatar Prashant Nevase Committed by Commit Bot

Make DarkModeImageClassifier apis to work with SkPixmap.

For RSDM (wip patch crrev.com/c/2295379), the ImageDecodeCache expects
DarkModeFilter work on SkPixmap. This patch makes
DarkModeImageClassifier use SkPixmap instead of PaintImage. Also as
RSDM requires the purging of the cache to be implemented in decoded
image cache, this patch moves dark mode image cache outside dark mode
module. Now blink implements caching in Image class and dark mode
filter helper is added to handle cache modifications.

To check the correctness of the dark mode classifier logic to work on
full image than portion of the image, few more tests related to image
sprite and block samples are added.

Bug: 1094005
Change-Id: I39dbd7638691da459b898045d4721069dc5dd21c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2382990Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarPhilip Rogers <pdr@chromium.org>
Commit-Queue: Prashant Nevase <prashant.n@samsung.com>
Cr-Commit-Position: refs/heads/master@{#809969}
parent c5e234cc
...@@ -879,10 +879,14 @@ component("platform") { ...@@ -879,10 +879,14 @@ component("platform") {
"graphics/dark_mode_color_filter.h", "graphics/dark_mode_color_filter.h",
"graphics/dark_mode_filter.cc", "graphics/dark_mode_filter.cc",
"graphics/dark_mode_filter.h", "graphics/dark_mode_filter.h",
"graphics/dark_mode_filter_helper.cc",
"graphics/dark_mode_filter_helper.h",
"graphics/dark_mode_image_cache.h",
"graphics/dark_mode_image_classifier.cc", "graphics/dark_mode_image_classifier.cc",
"graphics/dark_mode_image_classifier.h", "graphics/dark_mode_image_classifier.h",
"graphics/dark_mode_lab_color_space.h", "graphics/dark_mode_lab_color_space.h",
"graphics/dark_mode_settings.h", "graphics/dark_mode_settings.h",
"graphics/dark_mode_types.h",
"graphics/darkmode/darkmode_classifier.cc", "graphics/darkmode/darkmode_classifier.cc",
"graphics/darkmode/darkmode_classifier.h", "graphics/darkmode/darkmode_classifier.h",
"graphics/dash_array.h", "graphics/dash_array.h",
...@@ -1949,6 +1953,7 @@ source_set("blink_platform_unittests_sources") { ...@@ -1949,6 +1953,7 @@ source_set("blink_platform_unittests_sources") {
"graphics/contiguous_container_test.cc", "graphics/contiguous_container_test.cc",
"graphics/dark_mode_color_classifier_test.cc", "graphics/dark_mode_color_classifier_test.cc",
"graphics/dark_mode_filter_test.cc", "graphics/dark_mode_filter_test.cc",
"graphics/dark_mode_image_cache_test.cc",
"graphics/dark_mode_image_classifier_test.cc", "graphics/dark_mode_image_classifier_test.cc",
"graphics/dark_mode_lab_color_space_test.cc", "graphics/dark_mode_lab_color_space_test.cc",
"graphics/decoding_image_generator_test.cc", "graphics/decoding_image_generator_test.cc",
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_color_classifier.h"
#include "base/check_op.h" #include "base/check_op.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
namespace blink { namespace blink {
namespace { namespace {
...@@ -14,36 +13,34 @@ class SimpleColorClassifier : public DarkModeColorClassifier { ...@@ -14,36 +13,34 @@ class SimpleColorClassifier : public DarkModeColorClassifier {
public: public:
static std::unique_ptr<SimpleColorClassifier> NeverInvert() { static std::unique_ptr<SimpleColorClassifier> NeverInvert() {
return std::unique_ptr<SimpleColorClassifier>( return std::unique_ptr<SimpleColorClassifier>(
new SimpleColorClassifier(DarkModeClassification::kDoNotApplyFilter)); new SimpleColorClassifier(DarkModeResult::kDoNotApplyFilter));
} }
static std::unique_ptr<SimpleColorClassifier> AlwaysInvert() { static std::unique_ptr<SimpleColorClassifier> AlwaysInvert() {
return std::unique_ptr<SimpleColorClassifier>( return std::unique_ptr<SimpleColorClassifier>(
new SimpleColorClassifier(DarkModeClassification::kApplyFilter)); new SimpleColorClassifier(DarkModeResult::kApplyFilter));
} }
DarkModeClassification ShouldInvertColor(SkColor color) override { DarkModeResult ShouldInvertColor(SkColor color) override { return value_; }
return value_;
}
private: private:
SimpleColorClassifier(DarkModeClassification value) : value_(value) {} explicit SimpleColorClassifier(DarkModeResult value) : value_(value) {}
DarkModeClassification value_; DarkModeResult value_;
}; };
class InvertLowBrightnessColorsClassifier : public DarkModeColorClassifier { class InvertLowBrightnessColorsClassifier : public DarkModeColorClassifier {
public: public:
InvertLowBrightnessColorsClassifier(int brightness_threshold) explicit InvertLowBrightnessColorsClassifier(int brightness_threshold)
: brightness_threshold_(brightness_threshold) { : brightness_threshold_(brightness_threshold) {
DCHECK_GT(brightness_threshold_, 0); DCHECK_GT(brightness_threshold_, 0);
DCHECK_LT(brightness_threshold_, 256); DCHECK_LT(brightness_threshold_, 256);
} }
DarkModeClassification ShouldInvertColor(SkColor color) override { DarkModeResult ShouldInvertColor(SkColor color) override {
if (CalculateColorBrightness(color) < brightness_threshold_) if (CalculateColorBrightness(color) < brightness_threshold_)
return DarkModeClassification::kApplyFilter; return DarkModeResult::kApplyFilter;
return DarkModeClassification::kDoNotApplyFilter; return DarkModeResult::kDoNotApplyFilter;
} }
private: private:
...@@ -52,16 +49,16 @@ class InvertLowBrightnessColorsClassifier : public DarkModeColorClassifier { ...@@ -52,16 +49,16 @@ class InvertLowBrightnessColorsClassifier : public DarkModeColorClassifier {
class InvertHighBrightnessColorsClassifier : public DarkModeColorClassifier { class InvertHighBrightnessColorsClassifier : public DarkModeColorClassifier {
public: public:
InvertHighBrightnessColorsClassifier(int brightness_threshold) explicit InvertHighBrightnessColorsClassifier(int brightness_threshold)
: brightness_threshold_(brightness_threshold) { : brightness_threshold_(brightness_threshold) {
DCHECK_GT(brightness_threshold_, 0); DCHECK_GT(brightness_threshold_, 0);
DCHECK_LT(brightness_threshold_, 256); DCHECK_LT(brightness_threshold_, 256);
} }
DarkModeClassification ShouldInvertColor(SkColor color) override { DarkModeResult ShouldInvertColor(SkColor color) override {
if (CalculateColorBrightness(color) > brightness_threshold_) if (CalculateColorBrightness(color) > brightness_threshold_)
return DarkModeClassification::kApplyFilter; return DarkModeResult::kApplyFilter;
return DarkModeClassification::kDoNotApplyFilter; return DarkModeResult::kDoNotApplyFilter;
} }
private: private:
......
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
#include <memory> #include <memory>
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_types.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkColor.h"
namespace blink { namespace blink {
...@@ -29,7 +30,7 @@ class PLATFORM_EXPORT DarkModeColorClassifier { ...@@ -29,7 +30,7 @@ class PLATFORM_EXPORT DarkModeColorClassifier {
// whether to invert a color. The background is likely to be dark, so a lower // whether to invert a color. The background is likely to be dark, so a lower
// opacity will usually decrease the effective brightness of both the original // opacity will usually decrease the effective brightness of both the original
// and the inverted colors. // and the inverted colors.
virtual DarkModeClassification ShouldInvertColor(SkColor color) = 0; virtual DarkModeResult ShouldInvertColor(SkColor color) = 0;
}; };
} // namespace blink } // namespace blink
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "base/check_op.h" #include "base/check_op.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
namespace blink { namespace blink {
...@@ -33,18 +32,18 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToDarkTextOnly) { ...@@ -33,18 +32,18 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToDarkTextOnly) {
// * white text // * white text
// * text brighter than the text brightness threshold // * text brighter than the text brightness threshold
// * text at the brightness threshold // * text at the brightness threshold
EXPECT_EQ(DarkModeClassification::kApplyFilter, EXPECT_EQ(DarkModeResult::kApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness( classifier->ShouldInvertColor(GetColorWithBrightness(
settings.text_brightness_threshold - 5))); settings.text_brightness_threshold - 5)));
EXPECT_EQ(DarkModeClassification::kApplyFilter, EXPECT_EQ(DarkModeResult::kApplyFilter,
classifier->ShouldInvertColor(SK_ColorBLACK)); classifier->ShouldInvertColor(SK_ColorBLACK));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor(SK_ColorWHITE)); classifier->ShouldInvertColor(SK_ColorWHITE));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness( classifier->ShouldInvertColor(GetColorWithBrightness(
settings.text_brightness_threshold + 5))); settings.text_brightness_threshold + 5)));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor( classifier->ShouldInvertColor(
GetColorWithBrightness(settings.text_brightness_threshold))); GetColorWithBrightness(settings.text_brightness_threshold)));
} }
...@@ -56,18 +55,18 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToLightBackgroundElementsOnly) { ...@@ -56,18 +55,18 @@ TEST(DarkModeColorClassifierTest, ApplyFilterToLightBackgroundElementsOnly) {
auto classifier = auto classifier =
DarkModeColorClassifier::MakeBackgroundColorClassifier(settings); DarkModeColorClassifier::MakeBackgroundColorClassifier(settings);
EXPECT_EQ(DarkModeClassification::kApplyFilter, EXPECT_EQ(DarkModeResult::kApplyFilter,
classifier->ShouldInvertColor(SK_ColorWHITE)); classifier->ShouldInvertColor(SK_ColorWHITE));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor(SK_ColorBLACK)); classifier->ShouldInvertColor(SK_ColorBLACK));
EXPECT_EQ(DarkModeClassification::kApplyFilter, EXPECT_EQ(DarkModeResult::kApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness( classifier->ShouldInvertColor(GetColorWithBrightness(
settings.background_brightness_threshold + 5))); settings.background_brightness_threshold + 5)));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness( classifier->ShouldInvertColor(GetColorWithBrightness(
settings.background_brightness_threshold))); settings.background_brightness_threshold)));
EXPECT_EQ(DarkModeClassification::kDoNotApplyFilter, EXPECT_EQ(DarkModeResult::kDoNotApplyFilter,
classifier->ShouldInvertColor(GetColorWithBrightness( classifier->ShouldInvertColor(GetColorWithBrightness(
settings.background_brightness_threshold - 5))); settings.background_brightness_threshold - 5)));
} }
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include "third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_color_filter.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h" #include "third_party/blink/renderer/platform/wtf/hash_functions.h"
#include "third_party/blink/renderer/platform/wtf/lru_cache.h" #include "third_party/blink/renderer/platform/wtf/lru_cache.h"
#include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorFilter.h"
...@@ -148,42 +147,47 @@ SkColor DarkModeFilter::InvertColorIfNeeded(SkColor color, ElementRole role) { ...@@ -148,42 +147,47 @@ SkColor DarkModeFilter::InvertColorIfNeeded(SkColor color, ElementRole role) {
return color; return color;
} }
bool DarkModeFilter::AnalyzeShouldApplyToImage(const SkRect& src, DarkModeResult DarkModeFilter::AnalyzeShouldApplyToImage(
const SkRect& dst) { const SkRect& src,
const SkRect& dst) const {
if (settings().image_policy == DarkModeImagePolicy::kFilterNone) if (settings().image_policy == DarkModeImagePolicy::kFilterNone)
return false; return DarkModeResult::kDoNotApplyFilter;
if (settings().image_policy == DarkModeImagePolicy::kFilterAll) if (settings().image_policy == DarkModeImagePolicy::kFilterAll)
return true; return DarkModeResult::kApplyFilter;
// Images being drawn from very smaller |src| rect, i.e. one of the dimensions // Images being drawn from very smaller |src| rect, i.e. one of the dimensions
// is very small, can be used for the border around the content or showing // is very small, can be used for the border around the content or showing
// separator. Consider these images irrespective of size of the rect being // separator. Consider these images irrespective of size of the rect being
// drawn to. Classifying them will not be too costly. // drawn to. Classifying them will not be too costly.
if (src.width() <= kMinImageLength || src.height() <= kMinImageLength) if (src.width() <= kMinImageLength || src.height() <= kMinImageLength)
return true; return DarkModeResult::kNotClassified;
// Do not consider images being drawn into bigger rect as these images are not // Do not consider images being drawn into bigger rect as these images are not
// meant for icons or representing smaller widgets. These images are // meant for icons or representing smaller widgets. These images are
// considered as photos which should be untouched. // considered as photos which should be untouched.
return (dst.width() <= kMaxImageLength && dst.height() <= kMaxImageLength); return (dst.width() <= kMaxImageLength && dst.height() <= kMaxImageLength)
? DarkModeResult::kNotClassified
: DarkModeResult::kDoNotApplyFilter;
} }
void DarkModeFilter::ApplyToImageFlagsIfNeeded(const SkRect& src, sk_sp<SkColorFilter> DarkModeFilter::ApplyToImage(const SkPixmap& pixmap,
const SkRect& dst, const SkRect& src,
const PaintImage& paint_image, const SkRect& dst) {
cc::PaintFlags* flags) { DCHECK(AnalyzeShouldApplyToImage(src, dst) == DarkModeResult::kNotClassified);
// The construction of |paint_image| is expensive, so ensure DCHECK(settings().image_policy == DarkModeImagePolicy::kFilterSmart);
// IsDarkModeActive() is checked prior to calling this function. DCHECK(image_filter_);
// See: https://crbug.com/1094781.
DCHECK(IsDarkModeActive()); return (image_classifier_->Classify(pixmap, src) ==
DarkModeResult::kApplyFilter)
if (!image_filter_ || !AnalyzeShouldApplyToImage(src, dst)) ? image_filter_
return; : nullptr;
}
if (ClassifyImage(settings(), src, dst, paint_image) == sk_sp<SkColorFilter> DarkModeFilter::GetImageFilter() {
DarkModeClassification::kApplyFilter) DCHECK(settings().image_policy == DarkModeImagePolicy::kFilterAll);
flags->setColorFilter(image_filter_); DCHECK(image_filter_);
return image_filter_;
} }
base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded( base::Optional<cc::PaintFlags> DarkModeFilter::ApplyToFlagsIfNeeded(
...@@ -219,18 +223,18 @@ bool DarkModeFilter::ShouldApplyToColor(SkColor color, ElementRole role) { ...@@ -219,18 +223,18 @@ bool DarkModeFilter::ShouldApplyToColor(SkColor color, ElementRole role) {
case ElementRole::kText: case ElementRole::kText:
DCHECK(text_classifier_); DCHECK(text_classifier_);
return text_classifier_->ShouldInvertColor(color) == return text_classifier_->ShouldInvertColor(color) ==
DarkModeClassification::kApplyFilter; DarkModeResult::kApplyFilter;
case ElementRole::kListSymbol: case ElementRole::kListSymbol:
// TODO(prashant.n): Rename text_classifier_ to foreground_classifier_, // TODO(prashant.n): Rename text_classifier_ to foreground_classifier_,
// so that same classifier can be used for all roles which are supposed // so that same classifier can be used for all roles which are supposed
// to be at foreground. // to be at foreground.
DCHECK(text_classifier_); DCHECK(text_classifier_);
return text_classifier_->ShouldInvertColor(color) == return text_classifier_->ShouldInvertColor(color) ==
DarkModeClassification::kApplyFilter; DarkModeResult::kApplyFilter;
case ElementRole::kBackground: case ElementRole::kBackground:
DCHECK(background_classifier_); DCHECK(background_classifier_);
return background_classifier_->ShouldInvertColor(color) == return background_classifier_->ShouldInvertColor(color) ==
DarkModeClassification::kApplyFilter; DarkModeResult::kApplyFilter;
case ElementRole::kSVG: case ElementRole::kSVG:
// 1) Inline SVG images are considered as individual shapes and do not // 1) Inline SVG images are considered as individual shapes and do not
// have an Image object associated with them. So they do not go through // have an Image object associated with them. So they do not go through
...@@ -251,23 +255,6 @@ size_t DarkModeFilter::GetInvertedColorCacheSizeForTesting() { ...@@ -251,23 +255,6 @@ size_t DarkModeFilter::GetInvertedColorCacheSizeForTesting() {
return inverted_color_cache_->size(); return inverted_color_cache_->size();
} }
DarkModeClassification DarkModeFilter::ClassifyImage(
const DarkModeSettings& settings,
const SkRect& src,
const SkRect& dst,
const PaintImage& paint_image) {
switch (settings.image_policy) {
case DarkModeImagePolicy::kFilterSmart:
return image_classifier_->Classify(paint_image, src, dst);
case DarkModeImagePolicy::kFilterNone:
return DarkModeClassification::kDoNotApplyFilter;
case DarkModeImagePolicy::kFilterAll:
return DarkModeClassification::kApplyFilter;
}
NOTREACHED();
}
ScopedDarkModeElementRoleOverride::ScopedDarkModeElementRoleOverride( ScopedDarkModeElementRoleOverride::ScopedDarkModeElementRoleOverride(
GraphicsContext* graphics_context, GraphicsContext* graphics_context,
DarkModeFilter::ElementRole role) DarkModeFilter::ElementRole role)
......
...@@ -8,12 +8,9 @@ ...@@ -8,12 +8,9 @@
#include <memory> #include <memory>
#include "cc/paint/paint_flags.h" #include "cc/paint/paint_flags.h"
#include "third_party/blink/renderer/platform/graphics/color.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_settings.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_types.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkRefCnt.h"
class SkColorFilter; class SkColorFilter;
...@@ -48,19 +45,31 @@ class PLATFORM_EXPORT DarkModeFilter { ...@@ -48,19 +45,31 @@ class PLATFORM_EXPORT DarkModeFilter {
const cc::PaintFlags& flags, const cc::PaintFlags& flags,
ElementRole element_role); ElementRole element_role);
// Decides whether to apply dark mode or not based on |src| and |dst|. True // Decides whether to apply dark mode or not based on |src| and |dst|.
// means dark mode should be applied. For applying the dark mode color filter // DarkModeResult::kDoNotApplyFilter - Dark mode filter should not be applied.
// to the image call ApplyToImageFlagsIfNeeded(). // DarkModeResult::kApplyFilter - Dark mode filter should be applied and to
bool AnalyzeShouldApplyToImage(const SkRect& src, const SkRect& dst); // get the color filter GetImageFilter() should be called.
// DarkModeResult::kNotClassified - Dark mode filter should be applied and to
// get the color filter ApplyToImage() should be called.
DarkModeResult AnalyzeShouldApplyToImage(const SkRect& src,
const SkRect& dst) const;
// Returns dark mode color filter based on the classification done on
// |pixmap|. The image cannot be classified if pixmap is empty or |src| is
// empty or |src| is larger than pixmap bounds. Before calling this function
// AnalyzeShouldApplyToImage() must be called for early out or deciding
// appropriate function call. This function should be called only if image
// policy is set to DarkModeImagePolicy::kFilterSmart.
sk_sp<SkColorFilter> ApplyToImage(const SkPixmap& pixmap,
const SkRect& src,
const SkRect& dst);
// Sets dark mode color filter on the flags based on the classification done // Returns dark mode color filter for images. Before calling this function
// on |paint_image|. |flags| must not be null. // AnalyzeShouldApplyToImage() must be called for early out or deciding
void ApplyToImageFlagsIfNeeded(const SkRect& src, // appropriate function call. This function should be called only if image
const SkRect& dst, // policy is set to DarkModeImagePolicy::kFilterAll.
const PaintImage& paint_image, sk_sp<SkColorFilter> GetImageFilter();
cc::PaintFlags* flags);
SkColorFilter* GetImageFilterForTesting() { return image_filter_.get(); }
size_t GetInvertedColorCacheSizeForTesting(); size_t GetInvertedColorCacheSizeForTesting();
private: private:
...@@ -69,10 +78,6 @@ class PLATFORM_EXPORT DarkModeFilter { ...@@ -69,10 +78,6 @@ class PLATFORM_EXPORT DarkModeFilter {
DarkModeSettings settings_; DarkModeSettings settings_;
bool ShouldApplyToColor(SkColor color, ElementRole role); bool ShouldApplyToColor(SkColor color, ElementRole role);
DarkModeClassification ClassifyImage(const DarkModeSettings& settings,
const SkRect& src,
const SkRect& dst,
const PaintImage& paint_image);
std::unique_ptr<DarkModeColorClassifier> text_classifier_; std::unique_ptr<DarkModeColorClassifier> text_classifier_;
std::unique_ptr<DarkModeColorClassifier> background_classifier_; std::unique_ptr<DarkModeColorClassifier> background_classifier_;
......
// 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 "third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h"
#include "base/hash/hash.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_filter.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_image_cache.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
namespace blink {
// static
void DarkModeFilterHelper::ApplyToImageIfNeeded(
DarkModeFilter* dark_mode_filter,
Image* image,
cc::PaintFlags* flags,
const SkRect& src,
const SkRect& dst) {
DCHECK(dark_mode_filter);
DCHECK(image);
DCHECK(flags);
// The Image::AsSkBitmapForCurrentFrame() is expensive due creation of paint
// image and bitmap, so ensure IsDarkModeActive() is checked prior to calling
// this function. See: https://crbug.com/1094781.
DCHECK(dark_mode_filter->IsDarkModeActive());
sk_sp<SkColorFilter> filter;
DarkModeResult result = dark_mode_filter->AnalyzeShouldApplyToImage(src, dst);
if (result == DarkModeResult::kApplyFilter) {
filter = dark_mode_filter->GetImageFilter();
} else if (result == DarkModeResult::kNotClassified) {
DarkModeImageCache* cache = image->GetDarkModeImageCache();
DCHECK(cache);
if (cache->Exists(src)) {
filter = cache->Get(src);
} else {
// Performance warning: Calling this function will synchronously decode
// image.
SkBitmap bitmap =
image->AsSkBitmapForCurrentFrame(kDoNotRespectImageOrientation);
SkPixmap pixmap;
bitmap.peekPixels(&pixmap);
filter = dark_mode_filter->ApplyToImage(pixmap, src, dst);
cache->Add(src, filter);
}
}
if (filter)
flags->setColorFilter(filter);
}
} // namespace blink
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_HELPER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_HELPER_H_
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkRect.h"
namespace blink {
class DarkModeFilter;
class Image;
class PLATFORM_EXPORT DarkModeFilterHelper {
public:
static void ApplyToImageIfNeeded(DarkModeFilter* dark_mode_filter,
Image* image,
cc::PaintFlags* flags,
const SkRect& src,
const SkRect& dst);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_FILTER_HELPER_H_
...@@ -30,8 +30,6 @@ TEST(DarkModeFilterTest, DoNotApplyFilterWhenDarkModeIsOff) { ...@@ -30,8 +30,6 @@ TEST(DarkModeFilterTest, DoNotApplyFilterWhenDarkModeIsOff) {
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt,
filter.ApplyToFlagsIfNeeded( filter.ApplyToFlagsIfNeeded(
cc::PaintFlags(), DarkModeFilter::ElementRole::kBackground)); cc::PaintFlags(), DarkModeFilter::ElementRole::kBackground));
EXPECT_EQ(nullptr, filter.GetImageFilterForTesting());
} }
TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) { TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
...@@ -61,8 +59,6 @@ TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) { ...@@ -61,8 +59,6 @@ TEST(DarkModeFilterTest, ApplyDarkModeToColorsAndFlags) {
flags, DarkModeFilter::ElementRole::kBackground); flags, DarkModeFilter::ElementRole::kBackground);
ASSERT_NE(flags_or_nullopt, base::nullopt); ASSERT_NE(flags_or_nullopt, base::nullopt);
EXPECT_EQ(SK_ColorBLACK, flags_or_nullopt.value().getColor()); EXPECT_EQ(SK_ColorBLACK, flags_or_nullopt.value().getColor());
EXPECT_NE(nullptr, filter.GetImageFilterForTesting());
} }
TEST(DarkModeFilterTest, InvertedColorCacheSize) { TEST(DarkModeFilterTest, InvertedColorCacheSize) {
...@@ -122,32 +118,39 @@ TEST(DarkModeFilterTest, AnalyzeShouldApplyToImage) { ...@@ -122,32 +118,39 @@ TEST(DarkModeFilterTest, AnalyzeShouldApplyToImage) {
filter.UpdateSettings(settings); filter.UpdateSettings(settings);
// |dst| is smaller than threshold size. // |dst| is smaller than threshold size.
EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(100, 100), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(100, 100),
SkRect::MakeWH(100, 100))); SkRect::MakeWH(100, 100)),
DarkModeResult::kNotClassified);
// |dst| is smaller than threshold size, even |src| is larger. // |dst| is smaller than threshold size, even |src| is larger.
EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 200), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 200),
SkRect::MakeWH(100, 100))); SkRect::MakeWH(100, 100)),
DarkModeResult::kNotClassified);
// |dst| is smaller than threshold size, |src| is smaller. // |dst| is smaller than threshold size, |src| is smaller.
EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20),
SkRect::MakeWH(100, 100))); SkRect::MakeWH(100, 100)),
DarkModeResult::kNotClassified);
// |src| having very smaller width, even |dst| is larger than threshold size. // |src| having very smaller width, even |dst| is larger than threshold size.
EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(5, 200), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(5, 200),
SkRect::MakeWH(5, 200))); SkRect::MakeWH(5, 200)),
DarkModeResult::kNotClassified);
// |src| having very smaller height, even |dst| is larger than threshold size. // |src| having very smaller height, even |dst| is larger than threshold size.
EXPECT_TRUE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 5), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(200, 5),
SkRect::MakeWH(200, 5))); SkRect::MakeWH(200, 5)),
DarkModeResult::kNotClassified);
// |dst| is larger than threshold size. // |dst| is larger than threshold size.
EXPECT_FALSE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 20),
SkRect::MakeWH(200, 200))); SkRect::MakeWH(200, 200)),
DarkModeResult::kDoNotApplyFilter);
// |dst| is larger than threshold size. // |dst| is larger than threshold size.
EXPECT_FALSE(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 200), EXPECT_EQ(filter.AnalyzeShouldApplyToImage(SkRect::MakeWH(20, 200),
SkRect::MakeWH(20, 200))); SkRect::MakeWH(20, 200)),
DarkModeResult::kDoNotApplyFilter);
} }
} // namespace } // namespace
......
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_IMAGE_CACHE_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_IMAGE_CACHE_H_
#include <unordered_map>
#include "base/hash/hash.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/skia/include/core/SkColorFilter.h"
namespace blink {
// DarkModeImageCache - Implements dark mode filter cache for different |src|
// rects from the image.
class PLATFORM_EXPORT DarkModeImageCache {
public:
DarkModeImageCache() = default;
~DarkModeImageCache() = default;
bool Exists(const SkRect& src) {
return cache_.find(DarkModeKey(src)) != cache_.end();
}
sk_sp<SkColorFilter> Get(const SkRect& src) {
auto result = cache_.find(DarkModeKey(src));
return (result != cache_.end()) ? result->second : nullptr;
}
void Add(const SkRect& src, sk_sp<SkColorFilter> dark_mode_color_filter) {
DCHECK(!Exists(src));
cache_.emplace(DarkModeKey(src), std::move(dark_mode_color_filter));
}
size_t Size() { return cache_.size(); }
void Clear() { cache_.clear(); }
private:
struct DarkModeKeyHash;
struct DarkModeKey {
explicit DarkModeKey(SkRect src) : src_(src) {}
bool operator==(const DarkModeKey& other) const {
return src_ == other.src_;
}
private:
SkRect src_;
friend struct DarkModeImageCache::DarkModeKeyHash;
};
struct DarkModeKeyHash {
size_t operator()(const DarkModeKey& key) const {
return base::HashInts(
base::HashInts(base::HashInts(key.src_.x(), key.src_.y()),
key.src_.width()),
key.src_.height());
}
};
std::unordered_map<DarkModeKey, sk_sp<SkColorFilter>, DarkModeKeyHash> cache_;
DISALLOW_COPY_AND_ASSIGN(DarkModeImageCache);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_IMAGE_CACHE_H_
// 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 "third_party/blink/renderer/platform/graphics/dark_mode_image_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/effects/SkHighContrastFilter.h"
namespace blink {
class DarkModeImageCacheTest : public testing::Test {};
TEST_F(DarkModeImageCacheTest, Caching) {
DarkModeImageCache cache;
SkHighContrastConfig config;
config.fInvertStyle = SkHighContrastConfig::InvertStyle::kInvertLightness;
sk_sp<SkColorFilter> filter = SkHighContrastFilter::Make(config);
SkRect src1 = SkRect::MakeXYWH(0, 0, 50, 50);
SkRect src2 = SkRect::MakeXYWH(5, 20, 100, 100);
SkRect src3 = SkRect::MakeXYWH(6, -9, 50, 50);
EXPECT_FALSE(cache.Exists(src1));
EXPECT_EQ(cache.Get(src1), nullptr);
cache.Add(src1, filter);
EXPECT_TRUE(cache.Exists(src1));
EXPECT_EQ(cache.Get(src1), filter);
EXPECT_FALSE(cache.Exists(src2));
EXPECT_EQ(cache.Get(src2), nullptr);
cache.Add(src2, nullptr);
EXPECT_TRUE(cache.Exists(src2));
EXPECT_EQ(cache.Get(src2), nullptr);
EXPECT_EQ(cache.Size(), 2u);
cache.Clear();
EXPECT_EQ(cache.Size(), 0u);
EXPECT_FALSE(cache.Exists(src1));
EXPECT_EQ(cache.Get(src1), nullptr);
EXPECT_FALSE(cache.Exists(src2));
EXPECT_EQ(cache.Get(src2), nullptr);
EXPECT_FALSE(cache.Exists(src3));
EXPECT_EQ(cache.Get(src3), nullptr);
cache.Add(src3, filter);
EXPECT_TRUE(cache.Exists(src3));
EXPECT_EQ(cache.Get(src3), filter);
EXPECT_EQ(cache.Size(), 1u);
}
} // namespace blink
...@@ -9,17 +9,15 @@ ...@@ -9,17 +9,15 @@
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "base/optional.h" #include "base/optional.h"
#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_types.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_image.h" #include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRect.h"
#include "ui/gfx/geometry/rect.h"
namespace blink { namespace blink {
FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, BlockSamples);
FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, FeaturesAndClassification); FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, FeaturesAndClassification);
FORWARD_DECLARE_TEST(DarkModeImageClassifierTest, Caching);
// This class is not threadsafe as the cache used for storing classification // This class is not threadsafe as the cache used for storing classification
// results is not threadsafe. So it can be used only in blink main thread. // results is not threadsafe. So it can be used only in blink main thread.
...@@ -43,38 +41,27 @@ class PLATFORM_EXPORT DarkModeImageClassifier { ...@@ -43,38 +41,27 @@ class PLATFORM_EXPORT DarkModeImageClassifier {
float background_ratio; float background_ratio;
}; };
// Performance warning: |paint_image| will be synchronously decoded if this DarkModeResult Classify(const SkPixmap& pixmap, const SkRect& src);
// function is called in blink main thread.
DarkModeClassification Classify(const PaintImage& paint_image,
const SkRect& src,
const SkRect& dst);
// Removes cache identified by given |image_id|.
static void RemoveCache(PaintImage::Id image_id);
private: private:
DarkModeClassification ClassifyWithFeatures(const Features& features); DarkModeResult ClassifyWithFeatures(const Features& features);
DarkModeClassification ClassifyUsingDecisionTree(const Features& features); DarkModeResult ClassifyUsingDecisionTree(const Features& features);
bool GetBitmap(const PaintImage& paint_image,
const SkRect& src,
SkBitmap* bitmap);
base::Optional<Features> GetFeatures(const PaintImage& paint_image,
const SkRect& src);
enum class ColorMode { kColor = 0, kGrayscale = 1 }; enum class ColorMode { kColor = 0, kGrayscale = 1 };
base::Optional<Features> GetFeatures(const SkPixmap& pixmap,
const SkRect& src);
// Extracts a sample set of pixels (|sampled_pixels|), |transparency_ratio|, // Extracts a sample set of pixels (|sampled_pixels|), |transparency_ratio|,
// and |background_ratio|. // and |background_ratio|.
void GetSamples(const PaintImage& paint_image, void GetSamples(const SkPixmap& pixmap,
const SkRect& src, const SkRect& src,
std::vector<SkColor>* sampled_pixels, std::vector<SkColor>* sampled_pixels,
float* transparency_ratio, float* transparency_ratio,
float* background_ratio); float* background_ratio);
// Gets the |required_samples_count| for a specific |block| of the given // Gets the |required_samples_count| for a specific |block| of the given
// SkBitmap, and returns |sampled_pixels| and |transparent_pixels_count|. // pixmap, and returns |sampled_pixels| and |transparent_pixels_count|.
void GetBlockSamples(const SkBitmap& bitmap, void GetBlockSamples(const SkPixmap& pixmap,
const gfx::Rect& block, const SkIRect& block,
const int required_samples_count, const int required_samples_count,
std::vector<SkColor>* sampled_pixels, std::vector<SkColor>* sampled_pixels,
int* transparent_pixels_count); int* transparent_pixels_count);
...@@ -92,19 +79,9 @@ class PLATFORM_EXPORT DarkModeImageClassifier { ...@@ -92,19 +79,9 @@ class PLATFORM_EXPORT DarkModeImageClassifier {
float ComputeColorBucketsRatio(const std::vector<SkColor>& sampled_pixels, float ComputeColorBucketsRatio(const std::vector<SkColor>& sampled_pixels,
const ColorMode color_mode); const ColorMode color_mode);
// Gets cached value from the given |image_id| cache. FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest, BlockSamples);
DarkModeClassification GetCacheValue(PaintImage::Id image_id,
const SkRect& src);
// Adds cache value |result| to the given |image_id| cache.
void AddCacheValue(PaintImage::Id image_id,
const SkRect& src,
DarkModeClassification result);
// Returns the cache size for the given |image_id|.
size_t GetCacheSize(PaintImage::Id image_id);
FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest, FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest,
FeaturesAndClassification); FeaturesAndClassification);
FRIEND_TEST_ALL_PREFIXES(DarkModeImageClassifierTest, Caching);
}; };
} // namespace blink } // namespace blink
......
// 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_TYPES_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_TYPES_H_
namespace blink {
enum class DarkModeResult : uint8_t {
kDoNotApplyFilter,
kApplyFilter,
kNotClassified
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_DARK_MODE_TYPES_H_
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h"
#include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_filter.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_filter.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_filter_helper.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h" #include "third_party/blink/renderer/platform/graphics/graphics_context_state_saver.h"
#include "third_party/blink/renderer/platform/graphics/interpolation_space.h" #include "third_party/blink/renderer/platform/graphics/interpolation_space.h"
#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h"
...@@ -877,10 +878,9 @@ void GraphicsContext::DrawImage( ...@@ -877,10 +878,9 @@ void GraphicsContext::DrawImage(
image_flags.setFilterQuality(ComputeFilterQuality(image, dest, src)); image_flags.setFilterQuality(ComputeFilterQuality(image, dest, src));
// Do not classify the image if the element has any CSS filters. // Do not classify the image if the element has any CSS filters.
if (!has_filter_property && dark_mode_filter_.IsDarkModeActive() && if (!has_filter_property && dark_mode_filter_.IsDarkModeActive()) {
dark_mode_filter_.AnalyzeShouldApplyToImage(src, dest)) { DarkModeFilterHelper::ApplyToImageIfNeeded(&dark_mode_filter_, image,
dark_mode_filter_.ApplyToImageFlagsIfNeeded( &image_flags, src, dest);
src, dest, image->PaintImageForCurrentFrame(), &image_flags);
} }
image->Draw(canvas_, image_flags, dest, src, should_respect_image_orientation, image->Draw(canvas_, image_flags, dest, src, should_respect_image_orientation,
...@@ -918,11 +918,9 @@ void GraphicsContext::DrawImageRRect( ...@@ -918,11 +918,9 @@ void GraphicsContext::DrawImageRRect(
image_flags.setFilterQuality( image_flags.setFilterQuality(
ComputeFilterQuality(image, dest.Rect(), src_rect)); ComputeFilterQuality(image, dest.Rect(), src_rect));
if (dark_mode_filter_.IsDarkModeActive() && if (dark_mode_filter_.IsDarkModeActive()) {
dark_mode_filter_.AnalyzeShouldApplyToImage(src_rect, dest.Rect())) { DarkModeFilterHelper::ApplyToImageIfNeeded(
dark_mode_filter_.ApplyToImageFlagsIfNeeded( &dark_mode_filter_, image, &image_flags, src_rect, dest.Rect());
src_rect, dest.Rect(), image->PaintImageForCurrentFrame(),
&image_flags);
} }
bool use_shader = (visible_src == src_rect) && bool use_shader = (visible_src == src_rect) &&
......
...@@ -134,12 +134,6 @@ enum MailboxSyncMode { ...@@ -134,12 +134,6 @@ enum MailboxSyncMode {
kOrderingBarrier, kOrderingBarrier,
}; };
enum class DarkModeClassification {
kNotClassified,
kApplyFilter,
kDoNotApplyFilter,
};
// TODO(junov): crbug.com/453113 Relocate ShadowMode to // TODO(junov): crbug.com/453113 Relocate ShadowMode to
// CanvasRenderingContext2DState.h once GraphicsContext no longer uses it. // CanvasRenderingContext2DState.h once GraphicsContext no longer uses it.
enum ShadowMode { enum ShadowMode {
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "third_party/blink/renderer/platform/geometry/float_size.h" #include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/blink/renderer/platform/geometry/length.h" #include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/graphics/bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_image_cache.h"
#include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h" #include "third_party/blink/renderer/platform/graphics/dark_mode_image_classifier.h"
#include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h" #include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h"
#include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
...@@ -65,12 +66,7 @@ Image::Image(ImageObserver* observer, bool is_multipart) ...@@ -65,12 +66,7 @@ Image::Image(ImageObserver* observer, bool is_multipart)
stable_image_id_(PaintImage::GetNextId()), stable_image_id_(PaintImage::GetNextId()),
is_multipart_(is_multipart) {} is_multipart_(is_multipart) {}
Image::~Image() { Image::~Image() = default;
// TODO(prashant.n): This logic is needed to purge cache for the same origin
// page navigations. Redesign this once dark mode filter module gets moved to
// compositor side.
DarkModeImageClassifier::RemoveCache(stable_image_id_);
}
Image* Image::NullImage() { Image* Image::NullImage() {
DCHECK(IsMainThread()); DCHECK(IsMainThread());
...@@ -365,6 +361,13 @@ SkBitmap Image::AsSkBitmapForCurrentFrame( ...@@ -365,6 +361,13 @@ SkBitmap Image::AsSkBitmapForCurrentFrame(
return bitmap; return bitmap;
} }
DarkModeImageCache* Image::GetDarkModeImageCache() {
if (!dark_mode_image_cache_)
dark_mode_image_cache_ = std::make_unique<DarkModeImageCache>();
return dark_mode_image_cache_.get();
}
FloatRect Image::CorrectSrcRectForImageOrientation(FloatSize image_size, FloatRect Image::CorrectSrcRectForImageOrientation(FloatSize image_size,
FloatRect src_rect) const { FloatRect src_rect) const {
ImageOrientation orientation = CurrentFrameOrientation(); ImageOrientation orientation = CurrentFrameOrientation();
......
...@@ -61,6 +61,7 @@ class GraphicsContext; ...@@ -61,6 +61,7 @@ class GraphicsContext;
class Image; class Image;
class WebGraphicsContext3DProvider; class WebGraphicsContext3DProvider;
class WebGraphicsContext3DProviderWrapper; class WebGraphicsContext3DProviderWrapper;
class DarkModeImageCache;
class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
friend class GeneratedImage; friend class GeneratedImage;
...@@ -252,6 +253,8 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { ...@@ -252,6 +253,8 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
// Returns an SkBitmap that is a copy of the image's current frame. // Returns an SkBitmap that is a copy of the image's current frame.
SkBitmap AsSkBitmapForCurrentFrame(RespectImageOrientationEnum); SkBitmap AsSkBitmapForCurrentFrame(RespectImageOrientationEnum);
DarkModeImageCache* GetDarkModeImageCache();
protected: protected:
Image(ImageObserver* = nullptr, bool is_multipart = false); Image(ImageObserver* = nullptr, bool is_multipart = false);
...@@ -284,6 +287,7 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { ...@@ -284,6 +287,7 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> {
WeakPersistent<ImageObserver> image_observer_; WeakPersistent<ImageObserver> image_observer_;
PaintImage::Id stable_image_id_; PaintImage::Id stable_image_id_;
const bool is_multipart_; const bool is_multipart_;
std::unique_ptr<DarkModeImageCache> dark_mode_image_cache_;
DISALLOW_COPY_AND_ASSIGN(Image); DISALLOW_COPY_AND_ASSIGN(Image);
}; };
......
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