finish method

Future<void> finish()

Decodes every batch's alpha atlas, then replays the tape onto canvas: fallback ops drive a real CanvasPdfDevice, strip batches draw as shader-carrying drawVertices under the device->page transform. Await before endRecording(); the device is unusable afterwards.

Implementation

Future<void> finish() async {
  assert(!_finished, 'StripPdfDevice.finish() called twice');
  _finished = true;
  flushPending();
  _flushSlug(flushPointCount - 1);
  final plan = _plan;
  if (plan != null &&
      (flushPointCount != plan.totalFlushPoints ||
          _planNext != plan.batches.length ||
          _planSlugNext != plan.slugBatches.length ||
          _planSlugFallbackNext != plan.slugFallbackOrdinals.length)) {
    // Desync is only detectable once the walk is complete; nothing has
    // painted yet (painting starts below), so the caller can discard the
    // recording and re-run with local binning.
    totalPlanMismatches++;
    throw StripPlanMismatchError(
        'flush points: device $flushPointCount vs plan '
        '${plan.totalFlushPoints}; consumed $_planNext of '
        '${plan.batches.length} strip and $_planSlugNext of '
        '${plan.slugBatches.length} Slug batches; consumed '
        '$_planSlugFallbackNext of ${plan.slugFallbackOrdinals.length} '
        'Slug fallbacks');
  }
  if (plan != null && !debugVerifyPrecomputed) totalPlanPictures++;
  final sw = Stopwatch()..start();
  final program = await _loadProgram();
  final slugProgram = _slugBatches.isEmpty ? null : await _loadSlugProgram();
  await Future.wait([
    for (final b in _batches) b.decodeAtlas(),
    for (final b in _slugBatches) b.decodeAtlas(),
  ]);
  totalAtlasDecodeMicros += sw.elapsedMicroseconds;

  sw.reset();
  final fallback = CanvasPdfDevice(canvas, images: images);
  for (final entry in _tape) {
    if (entry is StripBatch) {
      _drawBatch(program, entry);
    } else if (entry is SlugBatch) {
      _drawSlugBatch(slugProgram!, entry);
    } else {
      (entry as void Function(CanvasPdfDevice))(fallback);
    }
  }
  totalReplayMicros += sw.elapsedMicroseconds;
}