| // 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 |