blob: 5dd2a94d4456cc9b1870846a350436590c78a156 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// 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/css_paint_image_generator_impl.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/modules/csspaint/css_paint_definition.h"
#include "third_party/blink/renderer/modules/csspaint/document_paint_definition.h"
#include "third_party/blink/renderer/modules/csspaint/paint_worklet.h"
#include "third_party/blink/renderer/platform/graphics/image.h"
namespace blink {
CSSPaintImageGenerator* CSSPaintImageGeneratorImpl::Create(
const String& name,
const Document& document,
Observer* observer) {
PaintWorklet* paint_worklet = PaintWorklet::From(*document.domWindow());
DCHECK(paint_worklet);
CSSPaintImageGeneratorImpl* generator;
if (paint_worklet->GetDocumentDefinitionMap().Contains(name)) {
generator =
MakeGarbageCollected<CSSPaintImageGeneratorImpl>(paint_worklet, name);
} else {
generator = MakeGarbageCollected<CSSPaintImageGeneratorImpl>(
observer, paint_worklet, name);
paint_worklet->AddPendingGenerator(name, generator);
}
return generator;
}
CSSPaintImageGeneratorImpl::CSSPaintImageGeneratorImpl(
PaintWorklet* paint_worklet,
const String& name)
: CSSPaintImageGeneratorImpl(nullptr, paint_worklet, name) {}
CSSPaintImageGeneratorImpl::CSSPaintImageGeneratorImpl(
Observer* observer,
PaintWorklet* paint_worklet,
const String& name)
: observer_(observer), paint_worklet_(paint_worklet), name_(name) {}
CSSPaintImageGeneratorImpl::~CSSPaintImageGeneratorImpl() = default;
void CSSPaintImageGeneratorImpl::NotifyGeneratorReady() {
DCHECK(observer_);
observer_->PaintImageGeneratorReady();
}
scoped_refptr<Image> CSSPaintImageGeneratorImpl::Paint(
const ImageResourceObserver& observer,
const gfx::SizeF& container_size,
const CSSStyleValueVector* data) {
return paint_worklet_->Paint(name_, observer, container_size, data);
}
bool CSSPaintImageGeneratorImpl::HasDocumentDefinition() const {
return paint_worklet_->GetDocumentDefinitionMap().Contains(name_);
}
bool CSSPaintImageGeneratorImpl::GetValidDocumentDefinition(
DocumentPaintDefinition*& definition) const {
if (!HasDocumentDefinition())
return false;
definition = paint_worklet_->GetDocumentDefinitionMap().at(name_);
// In off-thread CSS Paint, we register CSSPaintDefinition on the worklet
// thread first. Once the same CSSPaintDefinition is successfully registered
// to all the paint worklet global scopes, we then post to the main thread and
// register that CSSPaintDefinition on the main thread. So for the off-thread
// case, as long as the DocumentPaintDefinition exists in the map, it should
// be valid.
if (RuntimeEnabledFeatures::OffMainThreadCSSPaintEnabled()) {
DCHECK(definition);
return true;
}
if (definition->GetRegisteredDefinitionCount() !=
PaintWorklet::kNumGlobalScopesPerThread) {
definition = nullptr;
return false;
}
return definition;
}
unsigned CSSPaintImageGeneratorImpl::GetRegisteredDefinitionCountForTesting()
const {
if (!HasDocumentDefinition())
return 0;
DocumentPaintDefinition* definition =
paint_worklet_->GetDocumentDefinitionMap().at(name_);
return definition->GetRegisteredDefinitionCount();
}
const Vector<CSSPropertyID>&
CSSPaintImageGeneratorImpl::NativeInvalidationProperties() const {
DEFINE_STATIC_LOCAL(Vector<CSSPropertyID>, empty_vector, ());
DocumentPaintDefinition* definition;
if (!GetValidDocumentDefinition(definition))
return empty_vector;
return definition->NativeInvalidationProperties();
}
const Vector<AtomicString>&
CSSPaintImageGeneratorImpl::CustomInvalidationProperties() const {
DEFINE_STATIC_LOCAL(Vector<AtomicString>, empty_vector, ());
DocumentPaintDefinition* definition;
if (!GetValidDocumentDefinition(definition))
return empty_vector;
return definition->CustomInvalidationProperties();
}
bool CSSPaintImageGeneratorImpl::HasAlpha() const {
DocumentPaintDefinition* definition;
if (!GetValidDocumentDefinition(definition))
return false;
return definition->alpha();
}
const Vector<CSSSyntaxDefinition>&
CSSPaintImageGeneratorImpl::InputArgumentTypes() const {
DEFINE_STATIC_LOCAL(Vector<CSSSyntaxDefinition>, empty_vector, ());
DocumentPaintDefinition* definition;
if (!GetValidDocumentDefinition(definition))
return empty_vector;
return definition->InputArgumentTypes();
}
bool CSSPaintImageGeneratorImpl::IsImageGeneratorReady() const {
return HasDocumentDefinition();
}
int CSSPaintImageGeneratorImpl::WorkletId() const {
return paint_worklet_->WorkletId();
}
void CSSPaintImageGeneratorImpl::Trace(Visitor* visitor) const {
visitor->Trace(observer_);
visitor->Trace(paint_worklet_);
CSSPaintImageGenerator::Trace(visitor);
}
} // namespace blink