Commit 0977dd12 authored by Xida Chen's avatar Xida Chen Committed by Commit Bot

Move native paint worklet off thread

This CL moves the paint of the background color off the main
thread. Here is the design doc:
https://docs.google.com/document/d/1usCnwWs8HsH5FU_185q6MsrZehFmpl5QgbbB4pvHIjI/edit

In particular, we follow the infra of paint worklet.
When main thread paints, we create a PaintDeferredImage,
which is a place holder that does nothing. And then we
create a NativePaintWorkletInput that captures necessary
info and pass it to the compositor thread. After commit,
we ask the compositor thread to use the information from
the NativePaintWorkletInput and paint the background color.
Once the paint is done, we activate the pending tree.

There is no need to add new test, as long as the current
test are passing because this CL should not cause any
behavior change.

Bug: 1139004
Change-Id: Id487ca3c8511e620bcc652e75199f893227a50e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2466140
Commit-Queue: Xida Chen <xidachen@chromium.org>
Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#828858}
parent 883d6577
......@@ -2,30 +2,29 @@
// 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/core/css/native_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h"
namespace blink {
namespace {
NativePaintImageGenerator::NativePaintImageGeneratorCreateFunction
g_create_function = nullptr;
BackgroundColorPaintImageGenerator::
BackgroundColorPaintImageGeneratorCreateFunction g_create_function =
nullptr;
} // namespace
// static
void NativePaintImageGenerator::Init(
NativePaintImageGeneratorCreateFunction create_function) {
void BackgroundColorPaintImageGenerator::Init(
BackgroundColorPaintImageGeneratorCreateFunction create_function) {
DCHECK(!g_create_function);
g_create_function = create_function;
}
// static
std::unique_ptr<NativePaintImageGenerator> NativePaintImageGenerator::Create() {
BackgroundColorPaintImageGenerator* BackgroundColorPaintImageGenerator::Create(
LocalFrame& local_root) {
DCHECK(g_create_function);
return g_create_function();
return g_create_function(local_root);
}
NativePaintImageGenerator::~NativePaintImageGenerator() = default;
} // 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_CORE_CSS_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/css/native_paint_image_generator.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/skia/include/core/SkColor.h"
namespace blink {
class Image;
class LocalFrame;
class CORE_EXPORT BackgroundColorPaintImageGenerator
: public NativePaintImageGenerator {
public:
static BackgroundColorPaintImageGenerator* Create(LocalFrame&);
~BackgroundColorPaintImageGenerator() override = default;
typedef BackgroundColorPaintImageGenerator* (
*BackgroundColorPaintImageGeneratorCreateFunction)(LocalFrame&);
static void Init(
BackgroundColorPaintImageGeneratorCreateFunction create_function);
virtual scoped_refptr<Image> Paint(const FloatSize& container_size,
SkColor color) = 0;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_H_
......@@ -7,6 +7,8 @@ blink_core_sources_css = [
"abstract_property_set_css_style_declaration.h",
"active_style_sheets.cc",
"active_style_sheets.h",
"background_color_paint_image_generator.cc",
"background_color_paint_image_generator.h",
"basic_shape_functions.cc",
"basic_shape_functions.h",
"binary_data_font_face_source.cc",
......@@ -383,7 +385,6 @@ blink_core_sources_css = [
"media_values_dynamic.h",
"media_values_initial_viewport.cc",
"media_values_initial_viewport.h",
"native_paint_image_generator.cc",
"native_paint_image_generator.h",
"offscreen_font_selector.cc",
"offscreen_font_selector.h",
......
......@@ -31,6 +31,8 @@ class CORE_EXPORT PaintWorkletInput : public cc::PaintWorkletInput {
const FloatSize& ContainerSize() const { return container_size_; }
protected:
PaintWorkletInput(const FloatSize& container_size, int worklet_id)
: container_size_(container_size), worklet_id_(worklet_id) {}
PaintWorkletInput(const FloatSize& container_size,
int worklet_id,
cc::PaintWorkletInput::PropertyKeys property_keys)
......
......@@ -6,24 +6,18 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_NATIVE_PAINT_IMAGE_GENERATOR_H_
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class Image;
class CORE_EXPORT NativePaintImageGenerator {
class CORE_EXPORT NativePaintImageGenerator
: public GarbageCollected<NativePaintImageGenerator> {
public:
static std::unique_ptr<NativePaintImageGenerator> Create();
virtual ~NativePaintImageGenerator();
virtual ~NativePaintImageGenerator() = default;
typedef std::unique_ptr<NativePaintImageGenerator> (
*NativePaintImageGeneratorCreateFunction)();
static void Init(NativePaintImageGeneratorCreateFunction);
virtual void Shutdown() = 0;
virtual scoped_refptr<Image> Paint(const FloatSize& container_size,
SkColor color) = 0;
virtual void Trace(Visitor* visitor) const {}
};
} // namespace blink
......
......@@ -75,6 +75,7 @@
#include "third_party/blink/renderer/core/content_capture/content_capture_manager.h"
#include "third_party/blink/renderer/core/core_initializer.h"
#include "third_party/blink/renderer/core/core_probe_sink.h"
#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/document_style_environment_variables.h"
#include "third_party/blink/renderer/core/css/style_change_reason.h"
#include "third_party/blink/renderer/core/dom/child_frame_disconnector.h"
......@@ -506,6 +507,7 @@ void LocalFrame::Trace(Visitor* visitor) const {
visitor->Trace(high_priority_frame_receiver_);
visitor->Trace(text_fragment_selector_generator_);
visitor->Trace(saved_scroll_offsets_);
visitor->Trace(background_color_paint_image_generator_);
Frame::Trace(visitor);
Supplementable<LocalFrame>::Trace(visitor);
}
......@@ -584,6 +586,10 @@ void LocalFrame::DetachImpl(FrameDetachType type) {
performance_monitor_->Shutdown();
if (ad_tracker_)
ad_tracker_->Shutdown();
// Unregister only if this is LocalRoot because the paint_image_generator_
// was created on LocalRoot.
if (background_color_paint_image_generator_)
background_color_paint_image_generator_->Shutdown();
}
idleness_detector_->Shutdown();
if (inspector_issue_reporter_)
......@@ -680,6 +686,17 @@ void LocalFrame::CheckCompleted() {
GetDocument()->CheckCompleted();
}
BackgroundColorPaintImageGenerator*
LocalFrame::GetBackgroundColorPaintImageGenerator() {
LocalFrame& local_root = LocalFrameRoot();
// One background color paint worklet per root frame.
if (!local_root.background_color_paint_image_generator_) {
local_root.background_color_paint_image_generator_ =
BackgroundColorPaintImageGenerator::Create(local_root);
}
return local_root.background_color_paint_image_generator_.Get();
}
const SecurityContext* LocalFrame::GetSecurityContext() const {
return DomWindow() ? &DomWindow()->GetSecurityContext() : nullptr;
}
......
......@@ -127,6 +127,7 @@ class LayoutView;
class LocalDOMWindow;
class LocalWindowProxy;
class LocalFrameClient;
class BackgroundColorPaintImageGenerator;
class Node;
class NodeTraversal;
class PerformanceMonitor;
......@@ -235,6 +236,7 @@ class CORE_EXPORT LocalFrame final
TextSuggestionController& GetTextSuggestionController() const;
SpellChecker& GetSpellChecker() const;
FrameConsole& Console() const;
BackgroundColorPaintImageGenerator* GetBackgroundColorPaintImageGenerator();
// A local root is the root of a connected subtree that contains only
// LocalFrames. The local root is responsible for coordinating input, layout,
......@@ -936,6 +938,9 @@ class CORE_EXPORT LocalFrame final
// Access to the global raw/unsanitized system clipboard
Member<RawSystemClipboard> raw_system_clipboard_;
Member<BackgroundColorPaintImageGenerator>
background_color_paint_image_generator_;
using SavedScrollOffsets = HeapHashMap<Member<Node>, ScrollOffset>;
Member<SavedScrollOffsets> saved_scroll_offsets_;
......
......@@ -5,7 +5,7 @@
#include "third_party/blink/renderer/core/paint/box_painter_base.h"
#include "base/optional.h"
#include "third_party/blink/renderer/core/css/native_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/node_computed_style.h"
#include "third_party/blink/renderer/core/frame/settings.h"
......@@ -489,13 +489,14 @@ void DrawTiledBackground(GraphicsContext& context,
respect_orientation);
}
void FillRectWithPaintWorklet(const BoxPainterBase::FillLayerInfo& info,
void FillRectWithPaintWorklet(const Document* document,
const BoxPainterBase::FillLayerInfo& info,
Node* node,
const FloatRoundedRect& dest_rect,
GraphicsContext& context) {
FloatRect src_rect = dest_rect.Rect();
std::unique_ptr<NativePaintImageGenerator> generator =
NativePaintImageGenerator::Create();
BackgroundColorPaintImageGenerator* generator =
document->GetFrame()->GetBackgroundColorPaintImageGenerator();
scoped_refptr<Image> paint_worklet_image =
generator->Paint(src_rect.Size(), SkColor(info.color));
context.DrawImageRRect(
......@@ -504,7 +505,8 @@ void FillRectWithPaintWorklet(const BoxPainterBase::FillLayerInfo& info,
SkBlendMode::kSrcOver, info.respect_image_orientation);
}
inline bool PaintFastBottomLayer(Node* node,
inline bool PaintFastBottomLayer(const Document* document,
Node* node,
const PaintInfo& paint_info,
const BoxPainterBase::FillLayerInfo& info,
const PhysicalRect& rect,
......@@ -591,7 +593,7 @@ inline bool PaintFastBottomLayer(Node* node,
// Paint the color if needed.
if (info.should_paint_color) {
if (info.should_paint_color_with_paint_worklet_image) {
FillRectWithPaintWorklet(info, node, color_border, context);
FillRectWithPaintWorklet(document, info, node, color_border, context);
} else {
context.FillRoundedRect(color_border, info.color);
}
......@@ -754,7 +756,8 @@ FloatRoundedRect RoundedBorderRectForClip(
return border;
}
void PaintFillLayerBackground(GraphicsContext& context,
void PaintFillLayerBackground(const Document* document,
GraphicsContext& context,
const BoxPainterBase::FillLayerInfo& info,
Node* node,
Image* image,
......@@ -769,8 +772,8 @@ void PaintFillLayerBackground(GraphicsContext& context,
if (info.is_bottom_layer && info.color.Alpha() && info.should_paint_color) {
IntRect background_rect(PixelSnappedIntRect(scrolled_paint_rect));
if (info.should_paint_color_with_paint_worklet_image) {
FillRectWithPaintWorklet(info, node, FloatRoundedRect(background_rect),
context);
FillRectWithPaintWorklet(document, info, node,
FloatRoundedRect(background_rect), context);
} else {
context.FillRect(background_rect, info.color);
}
......@@ -900,8 +903,8 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
(bleed_avoidance == kBackgroundBleedShrinkBackground ||
did_adjust_paint_rect);
if (!disable_fast_path &&
PaintFastBottomLayer(node_, paint_info, info, rect, border_rect, geometry,
image.get(), composite_op)) {
PaintFastBottomLayer(document_, node_, paint_info, info, rect,
border_rect, geometry, image.get(), composite_op)) {
return;
}
......@@ -941,8 +944,8 @@ void BoxPainterBase::PaintFillLayer(const PaintInfo& paint_info,
break;
}
PaintFillLayerBackground(context, info, node_, image.get(), composite_op,
geometry, scrolled_paint_rect);
PaintFillLayerBackground(document_, context, info, node_, image.get(),
composite_op, geometry, scrolled_paint_rect);
}
void BoxPainterBase::PaintFillLayerTextFillBox(
......@@ -966,8 +969,9 @@ void BoxPainterBase::PaintFillLayerTextFillBox(
context.Clip(mask_rect);
context.BeginLayer(1, composite_op);
PaintFillLayerBackground(context, info, node_, image, SkBlendMode::kSrcOver,
geometry, scrolled_paint_rect);
PaintFillLayerBackground(document_, context, info, node_, image,
SkBlendMode::kSrcOver, geometry,
scrolled_paint_rect);
// Create the text mask layer and draw the text into the mask. We do this by
// painting using a special paint phase that signals to InlineTextBoxes that
......
......@@ -6,6 +6,10 @@ import("//third_party/blink/renderer/modules/modules.gni")
blink_modules_sources("csspaint") {
sources = [
"background_color_paint_image_generator_impl.cc",
"background_color_paint_image_generator_impl.h",
"background_color_paint_worklet.cc",
"background_color_paint_worklet.h",
"css_paint_definition.cc",
"css_paint_definition.h",
"css_paint_image_generator_impl.cc",
......@@ -14,10 +18,9 @@ blink_modules_sources("csspaint") {
"css_paint_worklet.h",
"document_paint_definition.cc",
"document_paint_definition.h",
"native_paint_image_generator_impl.cc",
"native_paint_image_generator_impl.h",
"native_paint_worklet.cc",
"native_paint_worklet.h",
"native_paint_worklet_proxy_client.h",
"paint_rendering_context_2d.cc",
"paint_rendering_context_2d.h",
"paint_size.h",
......@@ -27,6 +30,8 @@ blink_modules_sources("csspaint") {
"paint_worklet_global_scope.h",
"paint_worklet_global_scope_proxy.cc",
"paint_worklet_global_scope_proxy.h",
"paint_worklet_id_generator.cc",
"paint_worklet_id_generator.h",
"paint_worklet_messaging_proxy.cc",
"paint_worklet_messaging_proxy.h",
"paint_worklet_pending_generator_registry.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 "third_party/blink/renderer/modules/csspaint/background_color_paint_image_generator_impl.h"
#include "third_party/blink/renderer/modules/csspaint/background_color_paint_worklet.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
namespace blink {
BackgroundColorPaintImageGenerator*
BackgroundColorPaintImageGeneratorImpl::Create(LocalFrame& local_root) {
BackgroundColorPaintWorklet* background_color_paint_worklet =
BackgroundColorPaintWorklet::Create(local_root);
DCHECK(background_color_paint_worklet);
BackgroundColorPaintImageGeneratorImpl* generator =
MakeGarbageCollected<BackgroundColorPaintImageGeneratorImpl>(
background_color_paint_worklet);
return generator;
}
BackgroundColorPaintImageGeneratorImpl::BackgroundColorPaintImageGeneratorImpl(
BackgroundColorPaintWorklet* background_color_paint_worklet)
: background_color_paint_worklet_(background_color_paint_worklet) {}
scoped_refptr<Image> BackgroundColorPaintImageGeneratorImpl::Paint(
const FloatSize& container_size,
SkColor color) {
return background_color_paint_worklet_->Paint(container_size, color);
}
void BackgroundColorPaintImageGeneratorImpl::Shutdown() {
background_color_paint_worklet_->UnregisterProxyClient();
}
void BackgroundColorPaintImageGeneratorImpl::Trace(Visitor* visitor) const {
visitor->Trace(background_color_paint_worklet_);
BackgroundColorPaintImageGenerator::Trace(visitor);
}
} // namespace blink
......@@ -2,10 +2,10 @@
// 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_MODULES_CSSPAINT_NATIVE_PAINT_IMAGE_GENERATOR_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_NATIVE_PAINT_IMAGE_GENERATOR_IMPL_H_
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_IMPL_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_IMPL_H_
#include "third_party/blink/renderer/core/css/native_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "v8/include/v8.h"
......@@ -13,24 +13,28 @@
namespace blink {
class Image;
class NativePaintWorklet;
class BackgroundColorPaintWorklet;
class MODULES_EXPORT NativePaintImageGeneratorImpl final
: public NativePaintImageGenerator {
class MODULES_EXPORT BackgroundColorPaintImageGeneratorImpl final
: public BackgroundColorPaintImageGenerator {
public:
static std::unique_ptr<NativePaintImageGenerator> Create();
static BackgroundColorPaintImageGenerator* Create(LocalFrame&);
explicit NativePaintImageGeneratorImpl(std::unique_ptr<NativePaintWorklet>);
~NativePaintImageGeneratorImpl() override;
explicit BackgroundColorPaintImageGeneratorImpl(BackgroundColorPaintWorklet*);
~BackgroundColorPaintImageGeneratorImpl() override = default;
// The |container_size| is without subpixel snapping.
scoped_refptr<Image> Paint(const FloatSize& container_size,
SkColor color) final;
void Shutdown() final;
void Trace(Visitor*) const override;
private:
std::unique_ptr<NativePaintWorklet> native_paint_worklet_;
Member<BackgroundColorPaintWorklet> background_color_paint_worklet_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_NATIVE_PAINT_IMAGE_GENERATOR_IMPL_H_
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_IMAGE_GENERATOR_IMPL_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/modules/csspaint/background_color_paint_worklet.h"
#include "third_party/blink/renderer/core/css/cssom/paint_worklet_deferred_image.h"
#include "third_party/blink/renderer/core/css/cssom/paint_worklet_input.h"
#include "third_party/blink/renderer/modules/csspaint/native_paint_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h"
#include "third_party/blink/renderer/platform/graphics/platform_paint_worklet_layer_painter.h"
namespace blink {
namespace {
// This class includes information that is required by the compositor thread
// when painting background color.
class BackgroundColorPaintWorkletInput : public PaintWorkletInput {
public:
BackgroundColorPaintWorkletInput(const FloatSize& container_size,
int worklet_id,
SkColor color)
: PaintWorkletInput(container_size, worklet_id), color_(color) {}
~BackgroundColorPaintWorkletInput() override = default;
SkColor BackgroundColor() const { return color_; }
private:
SkColor color_;
};
class BackgroundColorPaintWorkletProxyClient
: public NativePaintWorkletProxyClient {
DISALLOW_COPY_AND_ASSIGN(BackgroundColorPaintWorkletProxyClient);
public:
static BackgroundColorPaintWorkletProxyClient* Create(int worklet_id) {
return MakeGarbageCollected<BackgroundColorPaintWorkletProxyClient>(
worklet_id);
}
explicit BackgroundColorPaintWorkletProxyClient(int worklet_id)
: NativePaintWorkletProxyClient(worklet_id) {}
~BackgroundColorPaintWorkletProxyClient() override = default;
// PaintWorkletPainter implementation.
sk_sp<PaintRecord> Paint(
const CompositorPaintWorkletInput* compositor_input,
const CompositorPaintWorkletJob::AnimatedPropertyValues&
animated_property_values) override {
const BackgroundColorPaintWorkletInput* input =
static_cast<const BackgroundColorPaintWorkletInput*>(compositor_input);
FloatSize container_size = input->ContainerSize();
SkColor color = input->BackgroundColor();
PaintRenderingContext2DSettings* context_settings =
PaintRenderingContext2DSettings::Create();
auto* rendering_context = MakeGarbageCollected<PaintRenderingContext2D>(
RoundedIntSize(container_size), context_settings, 1, 1);
rendering_context->GetPaintCanvas()->drawColor(color);
return rendering_context->GetRecord();
}
};
} // namespace
// static
BackgroundColorPaintWorklet* BackgroundColorPaintWorklet::Create(
LocalFrame& local_root) {
return MakeGarbageCollected<BackgroundColorPaintWorklet>(local_root);
}
BackgroundColorPaintWorklet::BackgroundColorPaintWorklet(LocalFrame& local_root)
: NativePaintWorklet(local_root) {
// This is called only once per document.
BackgroundColorPaintWorkletProxyClient* client =
BackgroundColorPaintWorkletProxyClient::Create(worklet_id_);
RegisterProxyClient(client);
}
BackgroundColorPaintWorklet::~BackgroundColorPaintWorklet() = default;
scoped_refptr<Image> BackgroundColorPaintWorklet::Paint(
const FloatSize& container_size,
SkColor color) {
scoped_refptr<BackgroundColorPaintWorkletInput> input =
base::MakeRefCounted<BackgroundColorPaintWorkletInput>(
container_size, worklet_id_, color);
return PaintWorkletDeferredImage::Create(std::move(input), container_size);
}
} // 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_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_WORKLET_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_WORKLET_H_
#include <memory>
#include "base/macros.h"
#include "third_party/blink/renderer/modules/csspaint/native_paint_worklet.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/geometry/float_size.h"
#include "third_party/skia/include/core/SkColor.h"
namespace blink {
class Image;
class LocalFrame;
class MODULES_EXPORT BackgroundColorPaintWorklet : public NativePaintWorklet {
DISALLOW_COPY_AND_ASSIGN(BackgroundColorPaintWorklet);
public:
static BackgroundColorPaintWorklet* Create(LocalFrame&);
explicit BackgroundColorPaintWorklet(LocalFrame&);
~BackgroundColorPaintWorklet() final;
// The |container_size| is without subpixel snapping.
scoped_refptr<Image> Paint(const FloatSize& container_size, SkColor color);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_BACKGROUND_COLOR_PAINT_WORKLET_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/modules/csspaint/native_paint_image_generator_impl.h"
#include "third_party/blink/renderer/modules/csspaint/native_paint_worklet.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
namespace blink {
std::unique_ptr<NativePaintImageGenerator>
NativePaintImageGeneratorImpl::Create() {
std::unique_ptr<NativePaintWorklet> native_paint_worklet =
std::make_unique<NativePaintWorklet>();
DCHECK(native_paint_worklet);
std::unique_ptr<NativePaintImageGeneratorImpl> generator =
std::make_unique<NativePaintImageGeneratorImpl>(
std::move(native_paint_worklet));
return generator;
}
NativePaintImageGeneratorImpl::NativePaintImageGeneratorImpl(
std::unique_ptr<NativePaintWorklet> native_paint_worklet)
: native_paint_worklet_(std::move(native_paint_worklet)) {}
NativePaintImageGeneratorImpl::~NativePaintImageGeneratorImpl() = default;
scoped_refptr<Image> NativePaintImageGeneratorImpl::Paint(
const FloatSize& container_size,
SkColor color) {
return native_paint_worklet_->Paint(container_size, color);
}
} // namespace blink
......@@ -4,26 +4,53 @@
#include "third_party/blink/renderer/modules/csspaint/native_paint_worklet.h"
#include "third_party/blink/renderer/modules/csspaint/paint_rendering_context_2d.h"
#include "third_party/blink/renderer/platform/graphics/paint_generated_image.h"
#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h"
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/modules/csspaint/native_paint_worklet_proxy_client.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_id_generator.h"
#include "third_party/blink/renderer/platform/graphics/paint_worklet_paint_dispatcher.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread.h"
#include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h"
namespace blink {
NativePaintWorklet::NativePaintWorklet() = default;
NativePaintWorklet::NativePaintWorklet(LocalFrame& local_root)
: worklet_id_(PaintWorkletIdGenerator::NextId()) {
DCHECK(local_root.IsLocalRoot());
paint_dispatcher_ =
WebLocalFrameImpl::FromFrame(local_root)
->FrameWidgetImpl()
->EnsureCompositorPaintDispatcher(&compositor_host_queue_);
DCHECK(IsMainThread());
ThreadCreationParams params(ThreadType::kDedicatedWorkerThread);
// TODO(crbug.com/1143407): We don't need this thread if we can make the
// compositor thread support GC.
worker_thread_ = Thread::CreateThread(params.SetSupportsGC(true));
}
NativePaintWorklet::~NativePaintWorklet() = default;
void NativePaintWorklet::RegisterProxyClient(
NativePaintWorkletProxyClient* client) {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
worker_thread_->GetTaskRunner();
// At this moment, we are in the paint phase which is before commit, we queue
// a task to the compositor thread to register the |paint_dispatcher_|. When
// compositor schedules the actual paint job (PaintWorkletPainter::Paint),
// which is after commit, the |paint_dispatcher_| should have been registerted
// and ready to use.
PostCrossThreadTask(
*compositor_host_queue_, FROM_HERE,
CrossThreadBindOnce(
&PaintWorkletPaintDispatcher::RegisterPaintWorkletPainter,
paint_dispatcher_, WrapCrossThreadPersistent(client), task_runner));
}
scoped_refptr<Image> NativePaintWorklet::Paint(const FloatSize& container_size,
SkColor color) {
PaintRenderingContext2DSettings* context_settings =
PaintRenderingContext2DSettings::Create();
auto* rendering_context = MakeGarbageCollected<PaintRenderingContext2D>(
RoundedIntSize(container_size), context_settings, 1, 1);
rendering_context->GetPaintCanvas()->drawColor(color);
sk_sp<PaintRecord> paint_record = rendering_context->GetRecord();
if (!paint_record)
return nullptr;
return PaintGeneratedImage::Create(paint_record, container_size);
void NativePaintWorklet::UnregisterProxyClient() {
PostCrossThreadTask(
*compositor_host_queue_, FROM_HERE,
CrossThreadBindOnce(
&PaintWorkletPaintDispatcher::UnregisterPaintWorkletPainter,
paint_dispatcher_, worklet_id_));
}
} // namespace blink
......@@ -15,16 +15,46 @@
namespace blink {
class MODULES_EXPORT NativePaintWorklet {
class LocalFrame;
class NativePaintWorkletProxyClient;
class PaintWorkletPaintDispatcher;
class SingleThreadTaskRunner;
class Thread;
// NativePaintWorklet contains the shared information by all kinds of native
// paint worklet. We allow the instance creation of its subclasses, but not this
// class. Each subclass would have its own implementation of the Paint function.
// For example, the BackgroundColorPaintWorklet takes a SkColor in its Paint
// function.
class MODULES_EXPORT NativePaintWorklet
: public GarbageCollected<NativePaintWorklet> {
DISALLOW_COPY_AND_ASSIGN(NativePaintWorklet);
public:
explicit NativePaintWorklet();
virtual ~NativePaintWorklet();
virtual ~NativePaintWorklet() = default;
// The |container_size| is without subpixel snapping.
scoped_refptr<Image> Paint(const FloatSize& container_size, SkColor color);
int WorkletId() const { return worklet_id_; }
private:
DISALLOW_COPY_AND_ASSIGN(NativePaintWorklet);
// Register the NativePaintWorkletProxyClient to the compositor thread that
// will hold a cross thread persistent pointer to it. This should be called
// during the construction of native paint worklets, to ensure that the proxy
// client is ready on the compositor thread when dispatching a paint job.
void RegisterProxyClient(NativePaintWorkletProxyClient*);
// Unregister the painter to ensure that there is no memory leakage on the
// compositor thread.
void UnregisterProxyClient();
virtual void Trace(Visitor*) const {}
protected:
explicit NativePaintWorklet(LocalFrame& local_root);
int worklet_id_;
base::WeakPtr<PaintWorkletPaintDispatcher> paint_dispatcher_;
scoped_refptr<base::SingleThreadTaskRunner> compositor_host_queue_;
// The worker thread that does the paint work.
std::unique_ptr<Thread> worker_thread_;
};
} // 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_MODULES_CSSPAINT_NATIVE_PAINT_WORKLET_PROXY_CLIENT_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_NATIVE_PAINT_WORKLET_PROXY_CLIENT_H_
#include "base/macros.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/graphics/paint_worklet_painter.h"
namespace blink {
// This class contains the shared bits for all kinds of
// NativePaintWorkletProxyClient. Instance creation of this class is not
// allowed, but its subclasses are allowed. Each subclass should have its own
// implementation of the Paint function from the PaintWorkletPainter.
class MODULES_EXPORT NativePaintWorkletProxyClient
: public GarbageCollected<NativePaintWorkletProxyClient>,
public PaintWorkletPainter {
DISALLOW_COPY_AND_ASSIGN(NativePaintWorkletProxyClient);
public:
~NativePaintWorkletProxyClient() override = default;
// PaintWorkletPainter implementation.
int GetWorkletId() const override { return worklet_id_; }
protected:
explicit NativePaintWorkletProxyClient(int worklet_id)
: worklet_id_(worklet_id) {}
private:
const int worklet_id_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_NATIVE_PAINT_WORKLET_PROXY_CLIENT_H_
......@@ -4,7 +4,6 @@
#include "third_party/blink/renderer/modules/csspaint/paint_worklet.h"
#include "base/atomic_sequence_num.h"
#include "base/rand_util.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/css/cssom/prepopulated_computed_style_property_map.h"
......@@ -16,20 +15,12 @@
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/modules/csspaint/css_paint_definition.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_global_scope.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_id_generator.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet_messaging_proxy.h"
#include "third_party/blink/renderer/platform/graphics/paint_generated_image.h"
namespace blink {
namespace {
base::AtomicSequenceNumber g_next_worklet_id;
int NextId() {
// Start id from 1. This way it safe to use it as key in hashmap with default
// key traits.
return g_next_worklet_id.GetNext() + 1;
}
} // namespace
const wtf_size_t PaintWorklet::kNumGlobalScopesPerThread = 2u;
const size_t kMaxPaintCountToSwitch = 30u;
......@@ -49,7 +40,7 @@ PaintWorklet::PaintWorklet(LocalDOMWindow& window)
Supplement<LocalDOMWindow>(window),
pending_generator_registry_(
MakeGarbageCollected<PaintWorkletPendingGeneratorRegistry>()),
worklet_id_(NextId()),
worklet_id_(PaintWorkletIdGenerator::NextId()),
is_paint_off_thread_(
RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled() &&
Thread::CompositorThread()) {}
......
// 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/modules/csspaint/paint_worklet_id_generator.h"
#include <limits>
#include "base/check_op.h"
namespace blink {
namespace {
// Note that the NextId() is called from the main thread only, and that's why
// it is fine with current_id being int. In the future, if NextId is called from
// a thread other than the main thread, then we should use AtomicSequenceNumber.
static int current_id = 0;
} // namespace
int PaintWorkletIdGenerator::NextId() {
CHECK_LT(current_id, std::numeric_limits<int>::max());
return ++current_id;
}
} // 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_MODULES_CSSPAINT_PAINT_WORKLET_ID_GENERATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_PAINT_WORKLET_ID_GENERATOR_H_
#include "third_party/blink/renderer/modules/modules_export.h"
namespace blink {
class MODULES_EXPORT PaintWorkletIdGenerator {
public:
static int NextId();
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_CSSPAINT_PAINT_WORKLET_ID_GENERATOR_H_
......@@ -16,8 +16,8 @@
#include "third_party/blink/public/web/web_local_frame_client.h"
#include "third_party/blink/public/web/web_view_client.h"
#include "third_party/blink/renderer/bindings/modules/v8/module_bindings_initializer.h"
#include "third_party/blink/renderer/core/css/background_color_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/css_paint_image_generator.h"
#include "third_party/blink/renderer/core/css/native_paint_image_generator.h"
#include "third_party/blink/renderer/core/dom/context_features_client_impl.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_backend_impl.h"
......@@ -42,8 +42,8 @@
#include "third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h"
#include "third_party/blink/renderer/modules/canvas/imagebitmap/image_bitmap_rendering_context.h"
#include "third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.h"
#include "third_party/blink/renderer/modules/csspaint/background_color_paint_image_generator_impl.h"
#include "third_party/blink/renderer/modules/csspaint/css_paint_image_generator_impl.h"
#include "third_party/blink/renderer/modules/csspaint/native_paint_image_generator_impl.h"
#include "third_party/blink/renderer/modules/device_orientation/device_motion_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_absolute_controller.h"
#include "third_party/blink/renderer/modules/device_orientation/device_orientation_controller.h"
......@@ -120,7 +120,8 @@ void ModulesInitializer::Initialize() {
DraggedIsolatedFileSystem::Init(
DraggedIsolatedFileSystemImpl::PrepareForDataObject);
CSSPaintImageGenerator::Init(CSSPaintImageGeneratorImpl::Create);
NativePaintImageGenerator::Init(NativePaintImageGeneratorImpl::Create);
BackgroundColorPaintImageGenerator::Init(
BackgroundColorPaintImageGeneratorImpl::Create);
WebDatabaseHost::GetInstance().Init();
MediaSourceRegistryImpl::Init();
......
......@@ -61,3 +61,6 @@ crbug.com/1123189 virtual/threaded-composited-iframes/external/wpt/is-input-pend
crbug.com/1123189 virtual/threaded-composited-iframes/external/wpt/is-input-pending/security/cross-origin-subframe-complex-clip.sub.html [ Failure ]
crbug.com/1124979 compositing/video/video-controls-layer-creation.html [ Pass Failure ]
crbug.com/1150468 virtual/composite-bgcolor-animation/external/wpt/css/css-backgrounds/* [ Skip ]
crbug.com/1150468 virtual/composite-bgcolor-animation-hidpi/external/wpt/css/css-backgrounds/hidpi/* [ Skip ]
......@@ -186,8 +186,15 @@
{
"prefix": "composite-bgcolor-animation",
"bases": ["external/wpt/css/css-backgrounds"],
"args": ["--enable-threaded-compositing",
"--enable-blink-features=CompositeBGColorAnimation"]
"args": ["--enable-blink-features=CompositeBGColorAnimation",
"--enable-threaded-compositing"]
},
{
"prefix": "composite-bgcolor-animation-hidpi",
"bases": ["external/wpt/css/css-backgrounds/hidpi"],
"args": ["--enable-blink-features=CompositeBGColorAnimation",
"--enable-threaded-compositing",
"--force-device-scale-factor=2"]
},
{
"prefix": "composite-after-paint",
......
<!DOCTYPE html>
<body>
<canvas id="canvas" width="400" height="800"></canvas>
</body>
<script>
var canvas = document.getElementById('canvas');
canvas.style.width = (canvas.width / 2) + 'px';
canvas.style.height = (canvas.height / 2) + 'px';
var ctx = canvas.getContext('2d');
ctx.scale(2, 2);
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, 100, 150);
ctx.fillStyle = 'red';
ctx.fillRect(0, 150, 200, 250);
</script>
<!DOCTYPE html>
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#background-color">
<link rel="match" href="simple-bg-color-ref.html">
<style>
.box1 {
width: 100px;
height: 150px;
background-color: green;
}
.box2 {
width: 200px;
height: 250px;
background-color: red;
}
</style>
<body>
<div class='box1'></div>
<div class='box2'></div>
</body>
# This suite runs the test in
external/wpt/css/composite-bg-color-animation/hidpi with
# --enable-blink-features=CompositeBGColorAnimation
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