blob: 8a5db881e09595877e2030a1f9f08d777d3805d1 [file] [log] [blame]
// Copyright 2018 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 "cc/tiles/paint_worklet_image_cache.h"
#include "base/bind.h"
#include "cc/paint/paint_worklet_layer_painter.h"
namespace cc {
class PaintWorkletTaskImpl : public TileTask {
public:
PaintWorkletTaskImpl(PaintWorkletImageCache* cache,
const PaintImage& paint_image)
: TileTask(true), cache_(cache), paint_image_(paint_image) {}
// Overridden from Task:
void RunOnWorkerThread() override { cache_->PaintImageInTask(paint_image_); }
// Overridden from TileTask:
void OnTaskCompleted() override {}
protected:
~PaintWorkletTaskImpl() override = default;
private:
PaintWorkletImageCache* cache_;
PaintImage paint_image_;
DISALLOW_COPY_AND_ASSIGN(PaintWorkletTaskImpl);
};
PaintWorkletImageCache::PaintWorkletImageCache() {}
PaintWorkletImageCache::~PaintWorkletImageCache() {}
void PaintWorkletImageCache::SetPaintWorkletLayerPainter(
std::unique_ptr<PaintWorkletLayerPainter> painter) {
painter_ = std::move(painter);
}
scoped_refptr<TileTask> PaintWorkletImageCache::GetTaskForPaintWorkletImage(
const DrawImage& image) {
return base::MakeRefCounted<PaintWorkletTaskImpl>(this, image.paint_image());
}
// TODO(xidachen): dispatch the work to a worklet thread, invoke JS callback.
// Do check the cache first. If there is already a cache entry for this input,
// then there is no need to call the Paint() function.
void PaintWorkletImageCache::PaintImageInTask(const PaintImage& paint_image) {
sk_sp<PaintRecord> record = painter_->Paint();
records_[paint_image.paint_worklet_input()] =
std::make_pair(std::move(record), 0);
}
std::pair<PaintRecord*, base::OnceCallback<void()>>
PaintWorkletImageCache::GetPaintRecordAndRef(PaintWorkletInput* input) {
records_[input].second++;
// The PaintWorkletImageCache object lives as long as the LayerTreeHostImpl,
// and that ensures that this pointer and the input will be alive when this
// callback is executed.
auto callback =
base::BindOnce(&PaintWorkletImageCache::DecrementCacheRefCount,
base::Unretained(this), base::Unretained(input));
return std::make_pair(records_[input].first.get(), std::move(callback));
}
void PaintWorkletImageCache::DecrementCacheRefCount(PaintWorkletInput* input) {
auto it = records_.find(input);
DCHECK(it != records_.end());
auto& pair = it->second;
DCHECK_GT(pair.second, 0u);
pair.second--;
}
} // namespace cc