39 size_t samples_per_frame,
40 float shutter_angle,
float shutter_phase) {
41 if (!samples_per_frame || shutter_angle <= 0) {
47 const auto samples_duration = shutter_angle / 360,
48 phase = shutter_phase / 360,
49 dt = samples_duration / (samples_per_frame - 1);
59 size_t samples,
float phase,
float dt)
61 , fAnimator(std::move(animator))
62 , fSampleCount(samples)
70SkRect MotionBlurEffect::seekToSample(
size_t sample_idx,
const SkMatrix& ctm)
const {
72 fAnimator->seek(fT + fPhase + fDT * sample_idx);
75 return this->
children()[0]->revalidate(
nullptr, ctm);
80 fVisibleSampleCount = 0;
82 for (
size_t i = 0;
i < fSampleCount; ++
i) {
90void MotionBlurEffect::renderToRaster8888Pow2Samples(
SkCanvas* canvas,
91 const RenderContext* ctx)
const {
96 const int shift =
SkNextLog2(fVisibleSampleCount);
97 SkASSERT((
size_t(1)<<shift) == fVisibleSampleCount);
113 std::vector<uint64_t> accum(
info.width() *
info.height());
116 bool needs_clear =
false;
117 for (
size_t i = 0;
i < fSampleCount; ++
i) {
120 if (!child->isVisible()) {
129 child->render(canvas, ctx);
133 const uint32_t*
src = layer;
134 uint64_t*
dst = accum.data();
136 for (
int y = 0;
y <
info.height();
y++) {
138 int n =
info.width();
139 const auto row =
src;
160 src = (
const uint32_t*)( (
const char*)row + rowBytes );
163 SkASSERT(frames_rendered == fVisibleSampleCount);
166 const uint64_t*
src = accum.data();
167 uint32_t*
dst = layer;
168 for (
int y = 0;
y <
info.height();
y++) {
170 int n =
info.width();
171 const auto row =
dst;
174 skvx::cast<uint8_t>(
s >> shift).store(
dst);
182 skvx::cast<uint8_t>(
s >> shift).store(
dst);
189 dst = (uint32_t*)( (
char*)row + rowBytes );
193void MotionBlurEffect::onRender(
SkCanvas* canvas,
const RenderContext* ctx)
const {
194 if (!fVisibleSampleCount) {
199 const auto& child = this->
children()[0];
203 AutoInvalBlocker aib(
this, child);
209 this->renderToRaster8888Pow2Samples(canvas, ctx);
218 const float frame_alpha = 1.0f / fVisibleSampleCount;
222 ScopedRenderContext frame_ctx(canvas, ctx);
225 const bool isolate_frames = !!frame_ctx->fBlender;
226 if (isolate_frames) {
230 frame_ctx = frame_ctx.modulateOpacity(frame_alpha)
235 for (
size_t i = 0;
i < fSampleCount; ++
i) {
238 if (!child->isVisible()) {
243 if (isolate_frames) {
244 canvas->
saveLayer(
nullptr, &frame_paint);
247 child->render(canvas, frame_ctx);
251 SkASSERT(frames_rendered == fVisibleSampleCount);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
static int SkNextLog2(uint32_t value)
constexpr bool SkIsPow2(T value)
#define INHERITED(method,...)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr size_t SkToSizeT(S x)
static sk_sp< SkBlender > Mode(SkBlendMode mode)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
bool peekPixels(SkPixmap *pixmap)
void clear(SkColor color)
SkMatrix getTotalMatrix() const
SkImageInfo imageInfo() const
void * accessTopLayerPixels(SkImageInfo *info, size_t *rowBytes, SkIPoint *origin=nullptr)
void setBlendMode(SkBlendMode mode)
AutoInvalBlocker(const MotionBlurEffect *mb, const sk_sp< RenderNode > &child)
static sk_sp< MotionBlurEffect > Make(sk_sp< Animator > animator, sk_sp< sksg::RenderNode > child, size_t samples_per_frame, float shutter_angle, float shutter_phase)
const std::vector< sk_sp< RenderNode > > & children() const
void observeInval(const sk_sp< Node > &)
void unobserveInval(const sk_sp< Node > &)
const SkRect & bounds() const
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
SkColorType colorType() const
static constexpr SkRect MakeEmpty()
void join(const SkRect &r)
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)