Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@jonahwilliams
Copy link
Contributor

@jonahwilliams jonahwilliams commented Aug 4, 2022

I adopted the code added in flutter/flutter#78068 to the html render via @flar to convert drawImageNine calls into drawImageRect calls.

return desc;
}

static impeller::SamplerDescriptor ToSamplerDescriptor(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBD: What is the difference between the flutter::DlFilterMode and flutter::DlImageSampling ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Here I just convert the DlFilterMode into an impeller::SamplerDescriptor like we would for flutter::DlImageSampling

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ImageSampling represents more options than FilterMode. I haven't investigated why, but Skia only allows this subset for drawImageNine so we parallel what they allow in our DL API.

flutter::DlFilterMode filter,
bool render_with_attributes) {
// Needs https://github.com/flutter/flutter/issues/95434
// Don't implement this one since it is not exposed by flutter,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A note for myself since I actually spent some time searching for usages of this in the engine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, the DLCanvasRecorder converts the calls back to drawImageNine after Skia converted them to a lattice...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added that detail too...

@jonahwilliams jonahwilliams requested review from bdero and flar August 4, 2022 21:41
Copy link
Contributor

@flar flar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just formatting nits...

// which is 8 values
auto dstC = dst0 + destDim * edge0Dim / edgesDim;
return {
img0, dst0, imgC0, dstC, imgC1, dstC, img1, dst1,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these return vectors could be initialized 4 values at a time it is easier to read the slices out and see how they relate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

auto dstC0 = dst0 + edge0Dim;
auto dstC1 = dst1 - edge1Dim;
return {img0, dst0, imgC0, dstC0, imgC0, dstC0,
imgC1, dstC1, imgC1, dstC1, img1, dst1};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is even more confusing because the middle slice is split between the first and second rows...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

flutter::DlFilterMode filter,
bool render_with_attributes) {
// Needs https://github.com/flutter/flutter/issues/95434
// Don't implement this one since it is not exposed by flutter,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More importantly, the DLCanvasRecorder converts the calls back to drawImageNine after Skia converted them to a lattice...

return desc;
}

static impeller::SamplerDescriptor ToSamplerDescriptor(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ImageSampling represents more options than FilterMode. I haven't investigated why, but Skia only allows this subset for drawImageNine so we parallel what they allow in our DL API.

@flar
Copy link
Contributor

flar commented Aug 4, 2022

FWIW, I wrote this interactive test app when I was working on the version of this code in the web source base...

Nine-slice interactive scaler
import 'dart:ui' as ui;

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Nine Slice Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Nine Slice Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ui.Image theImage;
  double size = 200.0;

  @override
  void initState() {
    super.initState();
    makeImage().then((image) => setState(() {
      theImage = image;
    }));
  }

  void newSize(double newSize) {
    setState(() {
      size = newSize;
    });
  }

  Future<ui.Image> makeImage() {
    Rect bounds = Rect.fromLTWH(0, 0, 200, 200);
    ui.PictureRecorder recorder = ui.PictureRecorder();
    Canvas canvas = Canvas(recorder, bounds);
    paintCheckerboard(canvas, bounds, 10, 10, Colors.white, Colors.grey);
    paintCheckerboard(canvas, bounds.deflate(50), 10, 10, Colors.blue, Colors.green);
    return recorder.endRecording().toImage(200, 200);
  }

  paintCheckerboard(Canvas canvas, Rect bounds, double w, double h, Color c1, Color c2) {
    Paint p = Paint();
    double y = bounds.top;
    for (int i = 0; i < bounds.height / h; i++) {
      double x = bounds.left;
      for (int j = 0; j < bounds.width / w; j++) {
        p.color = (i ^ j) & 1 == 0 ? c1 : c2;
        canvas.drawRect(Rect.fromLTWH(x, y, w, h), p);
        x += w;
      }
      y += h;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: theImage == null ? null : CustomPaint(
          size: Size(size, size),
          painter: NineSlicePainter(
            theImage,
            const Rect.fromLTWH(50, 50, 100, 100),
            Rect.fromLTWH(0, 0, size, size),
          ),
          willChange: false,
          isComplex: false,
        ),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Wrap(
          children: [
            Slider(
              value: size,
              min: 50,
              max: 300,
              onChanged: theImage == null ? null : newSize,
            ),
          ],
        ),
      ),
    );
  }
}

class NineSlicePainter extends CustomPainter {
  NineSlicePainter(this.theImage, this.center, this.dst);

  Rect center;
  Rect dst;
  ui.Image theImage;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawImageNine(theImage, center, dst, Paint());
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    if (oldDelegate is NineSlicePainter) {
      return oldDelegate.dst != dst || oldDelegate.theImage != theImage;
    }
    return true;
  }
}

@flar
Copy link
Contributor

flar commented Aug 5, 2022

👍

@jonahwilliams jonahwilliams added the autosubmit Merge PR when tree becomes green via auto submit App label Aug 5, 2022
@auto-submit auto-submit bot merged commit a478045 into flutter:main Aug 5, 2022
@jonahwilliams jonahwilliams deleted the add_nine_patch_converter branch August 5, 2022 01:12
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 5, 2022
betrevisan pushed a commit to betrevisan/engine that referenced this pull request Aug 5, 2022
emilyabest pushed a commit to emilyabest/engine that referenced this pull request Aug 12, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

autosubmit Merge PR when tree becomes green via auto submit App e: impeller

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants