/*
 * Copyright 2026 Rive
 */

#include "rive/renderer/cmd/deferred_render_factory.hpp"
#include "rive/renderer/cmd/render_replay.hpp"

// Out of line home for the large deferred stream bodies, so every TU that
// touches the deferred headers does not recompile them.
namespace rive::cmd
{

bool sniffImageSize(Span<const uint8_t> b, int& w, int& h)
{
  const uint8_t* d = b.data();
  size_t n = b.size();
  auto be32 = [&](size_t i) {
    return (d[i] << 24) | (d[i + 1] << 16) | (d[i + 2] << 8) | d[i + 3];
  };
  // PNG: 8-byte sig, then IHDR with width/height as big-endian u32 at 16/20.
  if (n >= 24 && d[0] == 0x89 && d[1] == 'P' && d[2] == 'N' && d[3] == 'G')
  {
    w = static_cast<int>(be32(16));
    h = static_cast<int>(be32(20));
    return true;
  }
  // GIF: "GIF87a"/"GIF89a", then width/height little-endian u16 at 6/8.
  if (n >= 10 && d[0] == 'G' && d[1] == 'I' && d[2] == 'F')
  {
    w = d[6] | (d[7] << 8);
    h = d[8] | (d[9] << 8);
    return true;
  }
  // WEBP: RIFF....WEBP; VP8 / VP8L / VP8X carry dims at known offsets.
  if (n >= 30 && d[0] == 'R' && d[1] == 'I' && d[2] == 'F' && d[3] == 'F' &&
      d[8] == 'W' && d[9] == 'E' && d[10] == 'B' && d[11] == 'P')
  {
    if (d[12] == 'V' && d[13] == 'P' && d[14] == '8' && d[15] == ' ')
    {
      w = (d[26] | (d[27] << 8)) & 0x3fff;
      h = (d[28] | (d[29] << 8)) & 0x3fff;
      return true;
    }
    if (d[12] == 'V' && d[13] == 'P' && d[14] == '8' && d[15] == 'L')
    {
      uint32_t bits = d[21] | (d[22] << 8) | (d[23] << 16) | (d[24] << 24);
      w = static_cast<int>((bits & 0x3fff) + 1);
      h = static_cast<int>(((bits >> 14) & 0x3fff) + 1);
      return true;
    }
    if (d[12] == 'V' && d[13] == 'P' && d[14] == '8' && d[15] == 'X')
    {
      w = (d[24] | (d[25] << 8) | (d[26] << 16)) + 1;
      h = (d[27] | (d[28] << 8) | (d[29] << 16)) + 1;
      return true;
    }
  }
  // JPEG: walk markers to an SOF (0xC0..0xCF, excluding non-SOF) for dims.
  if (n >= 4 && d[0] == 0xff && d[1] == 0xd8)
  {
    size_t i = 2;
    while (i + 9 < n)
    {
      if (d[i] != 0xff)
      {
        i++;
        continue;
      }
      uint8_t marker = d[i + 1];
      // SOF0..SOF15 carry dims; skip DHT(C4)/DAA(C8)/DAC(CC) which don't.
      if (marker >= 0xc0 && marker <= 0xcf && marker != 0xc4 &&
          marker != 0xc8 && marker != 0xcc)
      {
        h = (d[i + 5] << 8) | d[i + 6];
        w = (d[i + 7] << 8) | d[i + 8];
        return true;
      }
      uint32_t seg = (d[i + 2] << 8) | d[i + 3];
      i += 2 + seg;
    }
  }
  return false;
}

void replayRenderCommands(
    Factory* factory,
    Renderer* renderer,
    Span<const uint8_t> commands,
    Span<const uint8_t> blobs,
    ResourceTable& table,
    const ReplayHooks& hooks)
{
  auto& paths = table.paths;
  auto& paints = table.paints;
  auto& shaders = table.shaders;
  auto& images = table.images;
  auto& buffers = table.buffers;
  auto& meshInstances = table.imageMeshInstances;

  auto filterAllows = [](ReplayFilter f, RenderCmd c) {
    if (f == ReplayFilter::all)
    {
      return true;
    }
    switch (c)
    {
      case RenderCmd::save:
      case RenderCmd::restore:
      case RenderCmd::transform:
      case RenderCmd::drawPath:
      case RenderCmd::clipPath:
      case RenderCmd::clipStroke:
      case RenderCmd::drawImage:
      case RenderCmd::drawImageMesh:
      case RenderCmd::drawImageMeshInstanced:
      case RenderCmd::applyLayerMask:
      case RenderCmd::modulateOpacity:
      case RenderCmd::modulateColor:
      case RenderCmd::canvasContentBegin:
      case RenderCmd::canvasContentEnd:
      case RenderCmd::canvasSample:
        return f == ReplayFilter::draws;
      case RenderCmd::destroyResource:
        return f == ReplayFilter::destroys;
      default:
        return f == ReplayFilter::resources;
    }
  };

  RenderCommandReader reader(commands, blobs);
  auto path = [&](RenderHandle h) -> RenderPath* { return paths.get(h); };
  auto paint = [&](RenderHandle h) -> RenderPaint* { return paints.get(h); };
  auto image = [&](RenderHandle h) -> RenderImage* { return images.get(h); };
  auto sampler = [](uint8_t wx, uint8_t wy, uint8_t f) {
    return ImageSampler{
        static_cast<ImageWrap>(wx),
        static_cast<ImageWrap>(wy),
        static_cast<ImageFilter>(f)};
  };

  // Draws route into cur: the screen by default, or the active canvas
  // between content brackets. Null drops the draw.
  Renderer* cur = renderer;
  // A restore past these would pop the renderer's base state, whoever
  // recorded it.
  std::unordered_map<const Renderer*, uint32_t> callSaves;
  auto& openSaves = hooks.openSaves != nullptr ? *hooks.openSaves : callSaves;
  auto savesOf = [&](const Renderer* r) {
    return r != nullptr ? &openSaves[r] : nullptr;
  };
  uint32_t* curSaves = savesOf(cur);

  uint8_t type;
  uint8_t prevType = 255;
  size_t prevPos = 0;
  while (reader.next(type))
  {
    if (type > static_cast<uint8_t>(RenderCmd::lastRenderCmd))
    {
      // Unknown opcode: its payload was not consumed, so every later
      // read would desync. Stop.
      fprintf(
          stderr,
          "rive replay ABORT: opcode %u at byte %zu of %zu, last "
          "good opcode %u at byte %zu\n",
          type,
          reader.position() - 1,
          commands.size(),
          prevType,
          prevPos);
      assert(false);
      break;
    }
    prevType = type;
    prevPos = reader.position() - 1;
    const auto cmd = static_cast<RenderCmd>(type);
    if (!filterAllows(hooks.filter, cmd))
    {
      reader.skip(payloadSizeOf(cmd));
      continue;
    }
    switch (cmd)
    {
      case RenderCmd::makePath:
      {
        auto c = reader.read<MakePathPOD>();
        RawPath raw = rebuildRawPath(
            reader.blobAt(
                c.blobOffset,
                c.verbCount * static_cast<uint32_t>(sizeof(PathVerb))),
            reader.blobAt(
                c.pointsOffset,
                c.pointCount * static_cast<uint32_t>(sizeof(Vec2D))));
        paths.set(
            c.id,
            factory->makeRenderPath(raw, static_cast<FillRule>(c.fillRule)),
            c.generation);
        if (c.id >= table.pathFillRules.size())
        {
          table.pathFillRules.resize(c.id + 1);
        }
        table.pathFillRules[c.id] = c.fillRule;
        break;
      }
      case RenderCmd::makeEmptyPath:
      {
        auto c = reader.read<MakeIdPOD>();
        paths.set(c.id, factory->makeEmptyRenderPath(), c.generation);
        if (c.id >= table.pathFillRules.size())
        {
          table.pathFillRules.resize(c.id + 1);
        }
        table.pathFillRules[c.id] = 0;
        break;
      }
      case RenderCmd::makePaint:
      {
        auto c = reader.read<MakeIdPOD>();
        paints.set(c.id, factory->makeRenderPaint(), c.generation);
        if (c.id >= table.paintShadows.size())
        {
          table.paintShadows.resize(c.id + 1);
        }
        table.paintShadows[c.id] = PaintShadow{};
        break;
      }
      case RenderCmd::makeLinearGradient:
      {
        auto c = reader.read<LinearGradientPOD>();
        const ColorInt* colors = reinterpret_cast<const ColorInt*>(
            reader
                .blobAt(
                    c.blobOffset,
                    c.count * static_cast<uint32_t>(sizeof(ColorInt)))
                .data());
        const float* stops = reinterpret_cast<const float*>(
            reader
                .blobAt(
                    c.stopsOffset,
                    c.count * static_cast<uint32_t>(sizeof(float)))
                .data());
        if (colors == nullptr || stops == nullptr)
        {
          break; // blob out of range (corrupt stream)
        }
        shaders.set(
            c.id,
            factory->makeLinearGradient(
                c.sx,
                c.sy,
                c.ex,
                c.ey,
                colors,
                stops,
                c.count),
            c.generation);
        break;
      }
      case RenderCmd::makeRadialGradient:
      {
        auto c = reader.read<RadialGradientPOD>();
        const ColorInt* colors = reinterpret_cast<const ColorInt*>(
            reader
                .blobAt(
                    c.blobOffset,
                    c.count * static_cast<uint32_t>(sizeof(ColorInt)))
                .data());
        const float* stops = reinterpret_cast<const float*>(
            reader
                .blobAt(
                    c.stopsOffset,
                    c.count * static_cast<uint32_t>(sizeof(float)))
                .data());
        if (colors == nullptr || stops == nullptr)
        {
          break; // blob out of range (corrupt stream)
        }
        shaders.set(
            c.id,
            factory->makeRadialGradient(
                c.cx,
                c.cy,
                c.radius,
                colors,
                stops,
                c.count),
            c.generation);
        break;
      }
      case RenderCmd::makeAngularGradient:
      {
        auto c = reader.read<AngularGradientPOD>();
        const ColorInt* colors = reinterpret_cast<const ColorInt*>(
            reader
                .blobAt(
                    c.blobOffset,
                    c.count * static_cast<uint32_t>(sizeof(ColorInt)))
                .data());
        const float* stops = reinterpret_cast<const float*>(
            reader
                .blobAt(
                    c.stopsOffset,
                    c.count * static_cast<uint32_t>(sizeof(float)))
                .data());
        if (colors == nullptr || stops == nullptr)
        {
          break; // blob out of range (corrupt stream)
        }
        shaders.set(
            c.id,
            factory->makeAngularGradient(colors, stops, c.count),
            c.generation);
        break;
      }
      case RenderCmd::decodeImage:
      {
        auto c = reader.read<DecodeImagePOD>();
        images.set(
            c.id,
            factory->decodeImage(reader.blobAt(c.blobOffset, c.byteCount)),
            c.generation);
        break;
      }
      case RenderCmd::makeBuffer:
      {
        auto c = reader.read<MakeBufferPOD>();
        buffers.set(
            c.id,
            factory->makeRenderBuffer(
                static_cast<RenderBufferType>(c.bufferType),
                static_cast<RenderBufferFlags>(c.flags),
                c.sizeInBytes),
            c.generation);
        if (c.id >= table.bufferShadows.size())
        {
          table.bufferShadows.resize(c.id + 1);
        }
        table.bufferShadows[c.id] = {
            static_cast<uint8_t>(c.bufferType),
            static_cast<uint16_t>(c.flags),
            c.sizeInBytes};
        break;
      }
      case RenderCmd::makeImageMeshInstances:
      {
        auto c = reader.read<MakeImageMeshInstancesPOD>();
        meshInstances.set(
            c.id,
            factory->makeImageMeshInstances(c.count),
            c.generation);
        break;
      }
      case RenderCmd::imageMeshInstancesData:
      {
        auto c = reader.read<ImageMeshInstancesDataPOD>();
        Span<const uint8_t> src = reader.blobAt(
            c.blobOffset,
            c.count * static_cast<uint32_t>(sizeof(ImageMeshInstanceData)));
        if (auto* mi = meshInstances.get(c.id))
        {
          if (src.size() == c.count * sizeof(ImageMeshInstanceData))
          {
            Span<ImageMeshInstanceData> dst = mi->edit(c.count);
            std::memcpy(dst.data(), src.data(), src.size_bytes());
            mi->endEdit();
          }
        }
        break;
      }
      case RenderCmd::bufferData:
      {
        auto c = reader.read<BufferDataPOD>();
        Span<const uint8_t> src = reader.blobAt(c.blobOffset, c.size);
        if (auto* b = buffers.get(c.buffer))
        {
          if (src.size() == c.size)
          {
            void* dst = b->map();
            if (dst)
            {
              std::memcpy(dst, src.data(), c.size);
            }
            b->unmap();
          }
        }
        break;
      }
      case RenderCmd::destroyResource:
      {
        auto c = reader.read<DestroyResourcePOD>();
        table.destroy(static_cast<ResourceKind>(c.kind), c.id, c.generation);
        break;
      }
      case RenderCmd::resourceNewVersion:
      {
        // A drawn resource was mutated again: alias the outgoing
        // version for the draws that pinned it and continue on a
        // fresh object carrying the shadowed state.
        auto c = reader.read<ResourceVersionPOD>();
        switch (static_cast<ResourceKind>(c.kind))
        {
          case ResourceKind::paint:
          {
            auto fresh = factory->makeRenderPaint();
            if (fresh != nullptr && c.id < table.paintShadows.size())
            {
              const PaintShadow& sh = table.paintShadows[c.id];
              fresh->style(static_cast<RenderPaintStyle>(sh.style));
              fresh->color(sh.color);
              fresh->thickness(sh.thickness);
              fresh->join(static_cast<StrokeJoin>(sh.join));
              fresh->cap(static_cast<StrokeCap>(sh.cap));
              fresh->strokePosition(
                  static_cast<StrokePosition>(sh.strokePosition));
              fresh->feather(sh.feather);
              fresh->additiveness(sh.additiveness);
              fresh->blendMode(static_cast<BlendMode>(sh.blendMode));
              fresh->shaderTransform(sh.transform);
              if (sh.shader != kInvalidRenderHandle)
              {
                fresh->shader(shaders.shared(sh.shader));
              }
              if (sh.image != kInvalidRenderHandle)
              {
                RenderImage* im = (sh.image & kCanvasHandleFlag)
                                      ? (hooks.canvasImage
                                             ? hooks.canvasImage(
                                                   sh.image & kCanvasHandleMask)
                                             : nullptr)
                                      : images.get(sh.image);
                if (im != nullptr && !(sh.image & kCanvasHandleFlag) &&
                    hooks.prepImage)
                {
                  im = hooks.prepImage(im);
                  table.markPaintImagePending(c.id, im == nullptr);
                }
                fresh->modulatedImage(
                    im,
                    ImageSampler{
                        static_cast<ImageWrap>(sh.imageWrapX),
                        static_cast<ImageWrap>(sh.imageWrapY),
                        static_cast<ImageFilter>(sh.imageFilter)},
                    Mat2D(
                        sh.imageXX,
                        sh.imageXY,
                        sh.imageYX,
                        sh.imageYY,
                        sh.imageTX,
                        sh.imageTY));
              }
            }
            paints.newVersion(c.id, c.version, std::move(fresh));
            break;
          }
          case ResourceKind::path:
          {
            // Seed from the outgoing version so a non rewind
            // mutation appends onto prior geometry; a rewind bump
            // clears the seed via its own recorded command.
            auto fresh = factory->makeEmptyRenderPath();
            if (fresh != nullptr)
            {
              if (auto* outgoing = paths.get(c.id))
              {
                fresh->addRenderPath(outgoing, Mat2D());
              }
              if (c.id < table.pathFillRules.size())
              {
                fresh->fillRule(
                    static_cast<FillRule>(table.pathFillRules[c.id]));
              }
            }
            paths.newVersion(c.id, c.version, std::move(fresh));
            break;
          }
          case ResourceKind::buffer:
          {
            rcp<RenderBuffer> fresh;
            if (c.id < table.bufferShadows.size())
            {
              const BufferShadow& sh = table.bufferShadows[c.id];
              fresh = factory->makeRenderBuffer(
                  static_cast<RenderBufferType>(sh.type),
                  static_cast<RenderBufferFlags>(sh.flags),
                  sh.size);
            }
            buffers.newVersion(c.id, c.version, std::move(fresh));
            break;
          }
          case ResourceKind::imageMeshInstances:
          {
            meshInstances.newVersion(
                c.id,
                c.version,
                factory->makeImageMeshInstances(0));
            break;
          }
          default:
            break; // shaders and images never mutate
        }
        break;
      }

      case RenderCmd::pathRewind:
      {
        auto c = reader.read<ResIdPOD>();
        if (auto* p = path(c.id))
        {
          p->rewind();
        }
        break;
      }
      case RenderCmd::pathFillRule:
      {
        auto c = reader.read<PathFillRulePOD>();
        if (auto* p = path(c.path))
        {
          p->fillRule(static_cast<FillRule>(c.fillRule));
          table.pathFillRules[c.path] = c.fillRule;
        }
        break;
      }
      case RenderCmd::pathAddRawPath:
      {
        auto c = reader.read<PathRawPOD>();
        RawPath raw = rebuildRawPath(
            reader.blobAt(
                c.blobOffset,
                c.verbCount * static_cast<uint32_t>(sizeof(PathVerb))),
            reader.blobAt(
                c.pointsOffset,
                c.pointCount * static_cast<uint32_t>(sizeof(Vec2D))));
        if (auto* p = path(c.path))
        {
          p->addRawPath(raw);
        }
        break;
      }
      case RenderCmd::pathAddRenderPath:
      {
        auto c = reader.read<PathAddPathPOD>();
        RenderPath* src = paths.get(c.src);
        if (auto* p = path(c.path))
        {
          if (src)
            p->addRenderPath(src, Mat2D(c.xx, c.xy, c.yx, c.yy, c.tx, c.ty));
        }
        break;
      }

      case RenderCmd::paintStyle:
      {
        auto c = reader.read<PaintU8POD>();
        if (auto* pt = paint(c.paint))
        {
          pt->style(static_cast<RenderPaintStyle>(c.value));
          table.paintShadows[c.paint].style = c.value;
        }
        break;
      }
      case RenderCmd::paintColor:
      {
        auto c = reader.read<PaintColorPOD>();
        if (auto* pt = paint(c.paint))
        {
          pt->color(c.color);
          table.paintShadows[c.paint].color = c.color;
        }
        break;
      }
      case RenderCmd::paintThickness:
      {
        auto c = reader.read<PaintFloatPOD>();
        if (auto* pt = paint(c.paint))
        {
          pt->thickness(c.value);
          table.paintShadows[c.paint].thickness = c.value;
        }
        break;
      }
      case RenderCmd::paintJoin:
      {
        auto c = reader.read<PaintU8POD>();
        if (auto* pt = paint(c.paint))
        {
          pt->join(static_cast<StrokeJoin>(c.value));
          table.paintShadows[c.paint].join = c.value;
        }
        break;
      }
      case RenderCmd::paintCap:
      {
        auto c = reader.read<PaintU8POD>();
        if (auto* pt = paint(c.paint))
        {
          pt->cap(static_cast<StrokeCap>(c.value));
          table.paintShadows[c.paint].cap = c.value;
        }
        break;
      }
      case RenderCmd::paintStrokePosition:
      {
        auto c = reader.read<PaintU8POD>();
        if (auto* pt = paint(c.paint))
        {
          pt->strokePosition(static_cast<StrokePosition>(c.value));
          table.paintShadows[c.paint].strokePosition = c.value;
        }
        break;
      }
      case RenderCmd::paintFeather:
      {
        auto c = reader.read<PaintFloatPOD>();
        if (auto* pt = paint(c.paint))
        {
          pt->feather(c.value);
          table.paintShadows[c.paint].feather = c.value;
        }
        break;
      }
      case RenderCmd::paintAdditiveness:
      {
        auto c = reader.read<PaintFloatPOD>();
        if (auto* pt = paint(c.paint))
        {
          pt->additiveness(c.value);
          table.paintShadows[c.paint].additiveness = c.value;
        }
        break;
      }
      case RenderCmd::paintBlendMode:
      {
        auto c = reader.read<PaintU8POD>();
        if (auto* pt = paint(c.paint))
        {
          pt->blendMode(static_cast<BlendMode>(c.value));
          table.paintShadows[c.paint].blendMode = c.value;
        }
        break;
      }
      case RenderCmd::paintShader:
      {
        auto c = reader.read<PaintShaderPOD>();
        if (auto* pt = paint(c.paint))
        {
          pt->shader(shaders.shared(c.shader));
          table.paintShadows[c.paint].shader = c.shader;
        }
        break;
      }
      case RenderCmd::paintShaderTransform:
      {
        auto c = reader.read<PaintMat2DPOD>();
        if (auto* pt = paint(c.paint))
        {
          Mat2D transform(c.xx, c.xy, c.yx, c.yy, c.tx, c.ty);
          pt->shaderTransform(transform);
          table.paintShadows[c.paint].transform = transform;
        }
        break;
      }
      case RenderCmd::paintModulatedImage:
      {
        auto c = reader.read<PaintModulatedImagePOD>();
        if (auto* pt = paint(c.paint))
        {
          RenderImage* im = c.image == kInvalidRenderHandle ? nullptr
                            : (c.image & kCanvasHandleFlag)
                                ? (hooks.canvasImage
                                       ? hooks.canvasImage(
                                             c.image & kCanvasHandleMask)
                                       : nullptr)
                                : image(c.image);
          bool pendingImage = false;
          if (im != nullptr && !(c.image & kCanvasHandleFlag) &&
              hooks.prepImage)
          {
            im = hooks.prepImage(im);
            pendingImage = im == nullptr;
          }
          table.markPaintImagePending(c.paint, pendingImage);
          pt->modulatedImage(
              im,
              sampler(c.wrapX, c.wrapY, c.filter),
              Mat2D(c.xx, c.xy, c.yx, c.yy, c.tx, c.ty));
          PaintShadow& sh = table.paintShadows[c.paint];
          sh.image = c.image;
          sh.imageWrapX = c.wrapX;
          sh.imageWrapY = c.wrapY;
          sh.imageFilter = c.filter;
          sh.imageXX = c.xx;
          sh.imageXY = c.xy;
          sh.imageYX = c.yx;
          sh.imageYY = c.yy;
          sh.imageTX = c.tx;
          sh.imageTY = c.ty;
        }
        break;
      }
      case RenderCmd::paintInvalidateStroke:
      {
        auto c = reader.read<ResIdPOD>();
        if (auto* pt = paint(c.id))
        {
          pt->invalidateStroke();
        }
        break;
      }

      case RenderCmd::save:
        if (cur)
        {
          cur->save();
          ++*curSaves;
        }
        break;
      case RenderCmd::restore:
        if (cur && *curSaves > 0)
        {
          --*curSaves;
          cur->restore();
        }
        break;
      case RenderCmd::transform:
      {
        auto c = reader.read<TransformPOD>();
        if (cur)
        {
          cur->transform(Mat2D(c.xx, c.xy, c.yx, c.yy, c.tx, c.ty));
        }
        break;
      }
      case RenderCmd::drawPath:
      {
        auto c = reader.read<DrawPathPOD>();
        RenderPath* p = paths.get(c.path, c.pathVersion);
        RenderPaint* pt = paints.get(c.paint, c.paintVersion);
        if (cur && p && pt)
        {
          cur->drawPath(p, pt);
        }
        else if (cur != nullptr && hooks.stats != nullptr)
        {
          hooks.stats->droppedDraws = hooks.stats->droppedDraws + 1;
          replay_detail::logDroppedDraw(type, c.path, c.paint);
        }
        break;
      }
      case RenderCmd::clipPath:
      {
        auto c = reader.read<ClipPathPOD>();
        if (cur)
        {
          if (auto* p = paths.get(c.path, c.version))
            cur->clipPath(p);
        }
        break;
      }
      case RenderCmd::clipStroke:
      {
        auto c = reader.read<ClipStrokePOD>();
        if (cur)
        {
          if (auto* p = paths.get(c.path, c.version))
            cur->clipStroke(
                p,
                {
                    .thickness = c.thickness,
                    .join = StrokeJoin(c.join),
                    .cap = StrokeCap(c.cap),
                    .position = StrokePosition(c.position),
                });
        }
        break;
      }

      case RenderCmd::drawImage:
      {
        auto c = reader.read<DrawImagePOD>();
        RenderImage* im = (c.image & kCanvasHandleFlag)
                              ? (hooks.canvasImage
                                     ? hooks.canvasImage(
                                           c.image & kCanvasHandleMask)
                                     : nullptr)
                              : image(c.image);
        if (cur && im)
        {
          cur->drawImage(
              im,
              sampler(c.wrapX, c.wrapY, c.filter),
              static_cast<BlendMode>(c.blendMode),
              c.opacity,
              c.additiveness);
        }
        else if (cur != nullptr && hooks.stats != nullptr)
        {
          hooks.stats->droppedDraws = hooks.stats->droppedDraws + 1;
          replay_detail::logDroppedDraw(type, c.image, 0);
        }
        break;
      }
      case RenderCmd::applyLayerMask:
      {
        auto c = reader.read<ApplyLayerMaskPOD>();
        // The mask is nearly always a canvas image (layer masking
        // rasterizes its coverage into one), so the canvas hook is the
        // expected path here rather than the exception.
        RenderImage* im = (c.mask & kCanvasHandleFlag)
                              ? (hooks.canvasImage
                                     ? hooks.canvasImage(
                                           c.mask & kCanvasHandleMask)
                                     : nullptr)
                              : image(c.mask);
        if (cur && im)
        {
          cur->applyLayerMask(
              im,
              sampler(c.wrapX, c.wrapY, c.filter),
              static_cast<LayerMaskMode>(c.mode));
        }
        else if (cur != nullptr && hooks.stats != nullptr)
        {
          hooks.stats->droppedDraws = hooks.stats->droppedDraws + 1;
          replay_detail::logDroppedDraw(type, c.mask, 0);
        }
        break;
      }
      case RenderCmd::drawImageMesh:
      {
        auto c = reader.read<DrawImageMeshPOD>();
        RenderImage* im = (c.image & kCanvasHandleFlag)
                              ? (hooks.canvasImage
                                     ? hooks.canvasImage(
                                           c.image & kCanvasHandleMask)
                                     : nullptr)
                              : image(c.image);
        rcp<RenderBuffer> vb = buffers.shared(c.vertices, c.vertexVersion);
        rcp<RenderBuffer> uv = buffers.shared(c.uvCoords, c.uvVersion);
        rcp<RenderBuffer> ib = buffers.shared(c.indices, c.indexVersion);
        if (cur && im && vb && uv && ib)
        {
          cur->drawImageMesh(
              im,
              sampler(c.wrapX, c.wrapY, c.filter),
              vb,
              uv,
              ib,
              c.vertexCount,
              c.indexCount,
              static_cast<BlendMode>(c.blendMode),
              c.opacity,
              c.additiveness);
        }
        else if (cur != nullptr && hooks.stats != nullptr)
        {
          hooks.stats->droppedDraws = hooks.stats->droppedDraws + 1;
          replay_detail::logDroppedDraw(type, c.image, 0);
        }
        break;
      }
      case RenderCmd::drawImageMeshInstanced:
      {
        auto c = reader.read<DrawImageMeshInstancedPOD>();
        RenderImage* im = (c.image & kCanvasHandleFlag)
                              ? (hooks.canvasImage
                                     ? hooks.canvasImage(
                                           c.image & kCanvasHandleMask)
                                     : nullptr)
                              : image(c.image);
        rcp<RenderBuffer> vb = buffers.shared(c.vertices, c.vertexVersion);
        rcp<RenderBuffer> uv = buffers.shared(c.uvCoords, c.uvVersion);
        rcp<RenderBuffer> ib = buffers.shared(c.indices, c.indexVersion);
        rcp<ImageMeshInstances> mi = meshInstances.shared(
            c.instances,
            c.instancesVersion);
        if (cur && im && vb && uv && ib && mi)
        {
          cur->drawImageMeshInstanced(
              im,
              sampler(c.wrapX, c.wrapY, c.filter),
              vb,
              uv,
              ib,
              c.vertexCount,
              c.indexCount,
              std::move(mi));
        }
        else if (cur != nullptr && hooks.stats != nullptr)
        {
          hooks.stats->droppedDraws = hooks.stats->droppedDraws + 1;
          replay_detail::logDroppedDraw(type, c.image, 0);
        }
        break;
      }
      case RenderCmd::modulateOpacity:
      {
        auto c = reader.read<OpacityPOD>();
        if (cur)
        {
          cur->modulateOpacity(c.opacity);
        }
        break;
      }
      case RenderCmd::modulateColor:
      {
        auto c = reader.read<ModulateColorPOD>();
        if (cur)
        {
          cur->modulateColor(c.color, c.replace != 0);
        }
        break;
      }

      case RenderCmd::canvasContentBegin:
      {
        auto c = reader.read<CanvasContentPOD>();
        cur = hooks.beginCanvasContent ? hooks.beginCanvasContent(
                                             c.canvasId & kCanvasHandleMask,
                                             c.clearColor)
                                       : nullptr;
        curSaves = savesOf(cur);
        break;
      }
      case RenderCmd::canvasContentEnd:
      {
        reader.read<ResIdPOD>(); // advance past the canvas id
        cur = renderer;          // back to the screen; null drops draws
        curSaves = savesOf(cur);
        break;
      }
      case RenderCmd::canvasSample:
        reader.read<ResIdPOD>(); // read by the canvas schedule only
        break;
    }
  }
  if (reader.overrun())
  {
    fprintf(
        stderr,
        "rive replay ABORT: payload overrun at byte %zu of %zu\n",
        reader.position(),
        commands.size());
    assert(false);
  }
}

void retryPendingPaintImages(ResourceTable& table, const ReplayHooks& hooks)
{
  auto& pending = table.pendingPaintImages;
  if (pending.empty() || !hooks.prepImage)
  {
    return;
  }
  for (size_t i = 0; i < pending.size();)
  {
    RenderHandle id = pending[i];
    RenderPaint* pt = table.paints.get(id);
    const PaintShadow* sh = id < table.paintShadows.size()
                                ? &table.paintShadows[id]
                                : nullptr;
    // The paint or its image went away, or the image is no longer a
    // decoded one: nothing left to ready.
    RenderImage* im = pt != nullptr && sh != nullptr &&
                              sh->image != kInvalidRenderHandle &&
                              !(sh->image & kCanvasHandleFlag)
                          ? table.images.get(sh->image)
                          : nullptr;
    if (im == nullptr)
    {
      pending.erase(pending.begin() + i);
      continue;
    }
    RenderImage* ready = hooks.prepImage(im);
    if (ready == nullptr)
    {
      i++;
      continue;
    }
    pt->modulatedImage(
        ready,
        ImageSampler{
            static_cast<ImageWrap>(sh->imageWrapX),
            static_cast<ImageWrap>(sh->imageWrapY),
            static_cast<ImageFilter>(sh->imageFilter)},
        Mat2D(
            sh->imageXX,
            sh->imageXY,
            sh->imageYX,
            sh->imageYY,
            sh->imageTX,
            sh->imageTY));
    pending.erase(pending.begin() + i);
  }
}

} // namespace rive::cmd
