Commit 2bb818b7 authored by Adam Raine's avatar Adam Raine Committed by Commit Bot

Tests to ensure CSSPaintImageGenerator is notified at the right time

Added extra test statements to detect if a CSSPaintImageGenerator is
notified before all the registrations and cross thread checks are
finished.

Follow up to:
https://chromium-review.googlesource.com/c/chromium/src/+/1688641

Bug: 948761
Change-Id: Ia82fd1390465a96fbd97e4c0c7016f894fe0dd77
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1689784Reviewed-by: default avatarStephen McGruer <smcgruer@chromium.org>
Reviewed-by: default avatarXida Chen <xidachen@chromium.org>
Commit-Queue: Adam Raine <asraine@google.com>
Cr-Commit-Position: refs/heads/master@{#676133}
parent 041f6b60
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/modules/csspaint/paint_worklet.h" #include "third_party/blink/renderer/modules/csspaint/paint_worklet.h"
#include <memory> #include <memory>
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
...@@ -202,10 +203,40 @@ TEST_F(PaintWorkletTest, NativeAndCustomProperties) { ...@@ -202,10 +203,40 @@ TEST_F(PaintWorkletTest, NativeAndCustomProperties) {
EXPECT_TRUE(generator->HasAlpha()); EXPECT_TRUE(generator->HasAlpha());
} }
TEST_F(PaintWorkletTest, ConsistentGlobalScopeOnMainThread) { class MainOrOffThreadPaintWorkletTest
: public PageTestBase,
public ::testing::WithParamInterface<bool>,
private ScopedOffMainThreadCSSPaintForTest {
public:
MainOrOffThreadPaintWorkletTest()
: ScopedOffMainThreadCSSPaintForTest(GetParam()) {}
};
INSTANTIATE_TEST_SUITE_P(, MainOrOffThreadPaintWorkletTest, ::testing::Bool());
class MockObserver final : public CSSPaintImageGenerator::Observer {
public:
MOCK_METHOD0(PaintImageGeneratorReady, void());
};
TEST_P(MainOrOffThreadPaintWorkletTest, ConsistentGlobalScopeOnMainThread) {
PaintWorklet* paint_worklet_to_test = PaintWorklet* paint_worklet_to_test =
PaintWorklet::From(*GetFrame().GetDocument()->domWindow()); PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
MockObserver* observer = MakeGarbageCollected<MockObserver>();
CSSPaintImageGeneratorImpl* generator_foo =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "foo");
paint_worklet_to_test->AddPendingGenerator("foo", generator_foo);
CSSPaintImageGeneratorImpl* generator_bar =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "bar");
paint_worklet_to_test->AddPendingGenerator("bar", generator_bar);
// The generator should not fire unless it is the second registration
// for the main thread case
EXPECT_CALL(*observer, PaintImageGeneratorReady).Times(0);
Vector<Persistent<PaintWorkletGlobalScope>> global_scopes; Vector<Persistent<PaintWorkletGlobalScope>> global_scopes;
for (size_t i = 0; i < PaintWorklet::kNumGlobalScopesPerThread; ++i) { for (size_t i = 0; i < PaintWorklet::kNumGlobalScopesPerThread; ++i) {
paint_worklet_to_test->AddGlobalScopeForTesting(); paint_worklet_to_test->AddGlobalScopeForTesting();
...@@ -247,6 +278,12 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeOnMainThread) { ...@@ -247,6 +278,12 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeOnMainThread) {
EXPECT_TRUE(global_scopes[0]->FindDefinition("bar")); EXPECT_TRUE(global_scopes[0]->FindDefinition("bar"));
EXPECT_TRUE(paint_worklet_to_test->GetDocumentDefinitionMap().at("bar")); EXPECT_TRUE(paint_worklet_to_test->GetDocumentDefinitionMap().at("bar"));
// When running in main-thread mode, the generator is now ready after this
// call. For off-thread, we are still waiting on the cross-thread
// registration.
if (!RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled())
EXPECT_CALL(*observer, PaintImageGeneratorReady).Times(1);
global_scopes[1]->ScriptController()->Evaluate( global_scopes[1]->ScriptController()->Evaluate(
ScriptSourceCode(bar), SanitizeScriptErrors::kDoNotSanitize); ScriptSourceCode(bar), SanitizeScriptErrors::kDoNotSanitize);
...@@ -254,9 +291,32 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeOnMainThread) { ...@@ -254,9 +291,32 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeOnMainThread) {
} }
TEST_F(PaintWorkletTest, ConsistentGlobalScopeCrossThread) { TEST_F(PaintWorkletTest, ConsistentGlobalScopeCrossThread) {
ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint(true);
PaintWorklet* paint_worklet_to_test = PaintWorklet* paint_worklet_to_test =
PaintWorklet::From(*GetFrame().GetDocument()->domWindow()); PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
MockObserver* observer = MakeGarbageCollected<MockObserver>();
CSSPaintImageGeneratorImpl* generator_foo =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "foo");
paint_worklet_to_test->AddPendingGenerator("foo", generator_foo);
CSSPaintImageGeneratorImpl* generator_bar =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "bar");
paint_worklet_to_test->AddPendingGenerator("bar", generator_bar);
CSSPaintImageGeneratorImpl* generator_loo =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "loo");
paint_worklet_to_test->AddPendingGenerator("loo", generator_loo);
CSSPaintImageGeneratorImpl* generator_gar =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "gar");
paint_worklet_to_test->AddPendingGenerator("gar", generator_gar);
// None of the situations covered in this test should cause the generator to
// fire.
EXPECT_CALL(*observer, PaintImageGeneratorReady).Times(0);
Vector<Persistent<PaintWorkletGlobalScope>> global_scopes; Vector<Persistent<PaintWorkletGlobalScope>> global_scopes;
for (size_t i = 0; i < PaintWorklet::kNumGlobalScopesPerThread; ++i) { for (size_t i = 0; i < PaintWorklet::kNumGlobalScopesPerThread; ++i) {
paint_worklet_to_test->AddGlobalScopeForTesting(); paint_worklet_to_test->AddGlobalScopeForTesting();
...@@ -399,18 +459,63 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeCrossThread) { ...@@ -399,18 +459,63 @@ TEST_F(PaintWorkletTest, ConsistentGlobalScopeCrossThread) {
EXPECT_FALSE(paint_worklet_to_test->GetDocumentDefinitionMap().at("gar")); EXPECT_FALSE(paint_worklet_to_test->GetDocumentDefinitionMap().at("gar"));
} }
class OffThreadPaintWorkletTest : public PageTestBase, TEST_F(PaintWorkletTest, GeneratorNotifiedAfterAllRegistrations) {
public ::testing::WithParamInterface<bool> { ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint(true);
public: PaintWorklet* paint_worklet_to_test =
OffThreadPaintWorkletTest() : off_main_thread_css_paint_(GetParam()) {} PaintWorklet::From(*GetFrame().GetDocument()->domWindow());
private: MockObserver* observer = MakeGarbageCollected<MockObserver>();
ScopedOffMainThreadCSSPaintForTest off_main_thread_css_paint_; CSSPaintImageGeneratorImpl* generator =
}; MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet_to_test, "foo");
paint_worklet_to_test->AddPendingGenerator("foo", generator);
// The generator should not fire until the cross thread check
EXPECT_CALL(*observer, PaintImageGeneratorReady).Times(0);
Vector<Persistent<PaintWorkletGlobalScope>> global_scopes;
for (size_t i = 0; i < PaintWorklet::kNumGlobalScopesPerThread; ++i) {
paint_worklet_to_test->AddGlobalScopeForTesting();
global_scopes.push_back(
PaintWorkletGlobalScopeProxy::From(
paint_worklet_to_test->GetGlobalScopesForTesting()[i])
->global_scope());
}
String foo = R"JS(registerPaint('foo', class {
static get inputProperties() { return ['--foo']; }
paint() {}
});)JS";
global_scopes[0]->ScriptController()->Evaluate(
ScriptSourceCode(foo), SanitizeScriptErrors::kDoNotSanitize);
EXPECT_TRUE(global_scopes[0]->FindDefinition("foo"));
EXPECT_TRUE(paint_worklet_to_test->GetDocumentDefinitionMap().at("foo"));
global_scopes[1]->ScriptController()->Evaluate(
ScriptSourceCode(foo), SanitizeScriptErrors::kDoNotSanitize);
INSTANTIATE_TEST_SUITE_P(, OffThreadPaintWorkletTest, ::testing::Bool()); EXPECT_TRUE(paint_worklet_to_test->GetDocumentDefinitionMap().at("foo"));
CSSPaintDefinition* definition = global_scopes[0]->FindDefinition("foo");
Vector<String> custom_properties;
for (const auto& s : definition->CustomInvalidationProperties()) {
custom_properties.push_back(s);
}
// The cross thread check should cause the generator to fire
EXPECT_CALL(*observer, PaintImageGeneratorReady).Times(1);
paint_worklet_to_test->RegisterMainThreadDocumentPaintDefinition(
"foo", definition->NativeInvalidationProperties(), custom_properties,
definition->InputArgumentTypes(),
definition->GetPaintRenderingContext2DSettings()->alpha());
EXPECT_TRUE(paint_worklet_to_test->GetDocumentDefinitionMap().at("foo"));
}
TEST_P(OffThreadPaintWorkletTest, AllGlobalScopesMustBeCreated) { TEST_P(MainOrOffThreadPaintWorkletTest, AllGlobalScopesMustBeCreated) {
PaintWorklet* paint_worklet_to_test = PaintWorklet* paint_worklet_to_test =
MakeGarbageCollected<PaintWorklet>(&GetFrame()); MakeGarbageCollected<PaintWorklet>(&GetFrame());
......
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