-
Notifications
You must be signed in to change notification settings - Fork 6k
Initial support for images in Skwasm #42019
Conversation
Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change). If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review. |
dataHandle, | ||
width, | ||
height, | ||
format == ui.PixelFormat.bgra8888, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a bool sufficient to express all pixel formats we have? https://api.flutter.dev/flutter/dart-ui/PixelFormat.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we just have the two formats in web:
enum PixelFormat {
rgba8888,
bgra8888,
}
So I figured it was simpler to pass a bool for now. We can change it to an enum later if we have more than two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, that looks like a bug. PixelFormat
is part of dart:ui
, which is expected to be identical across all platforms.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added support for it in Skwasm, but it's still not supported in all the renderers and the bitmap creation code path. I filed flutter/flutter#126895 as a follow-on.
// Not scaled. | ||
return null; | ||
} | ||
targetWidth = (width * targetHeight! / height).round(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like the compiler failed to figure out that targetHeight
is not null nere. Or am I missing something? Should we file an issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think expecting the compiler to figure out that targetHeight
is non-null here is a little unrealistic. I might be able to restructure the code a little to make it more obvious to the compiler though... Hmmm...
); | ||
if (!allowUpscaling && scaledSize != null && | ||
(scaledSize.width > width || scaledSize.height > height)) { | ||
domWindow.console.warn('Cannot apply targetWidth/targetHeight when allowUpscaling is false.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need to issue a warning. This seems to be the expected behavior. Sometimes you want to shrink the image to save memory, but upscaling can be done in the GPU so you don't want to waste CPU and memory on upscaling prior to rendering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was doing this to be consistent with skiaDecodeImageFromPixels
, which issues this warning under this condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, benefits of revisiting old code! :) Yeah, I don't think skiaDecodeImageFromPixels
should warn either.
SkTileMode tileModeY, | ||
FilterQuality quality, | ||
SkScalar* matrix33) { | ||
if (matrix33) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check? We seem to always pass a non-null matrix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'm going to go the other direction and bubble the nullability up to the higher level APIs. There is at least one place I could avoid passing this data altogether.
Float64List matrix4, | ||
ui.FilterQuality? filterQuality, | ||
) => withStackScope((StackScope scope) { | ||
final RawMatrix33 localMatrix = scope.convertMatrix4toSkMatrix(matrix4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the matrix is never null, can we allocate on the heap to avoid copying the matrix twice, once here and a second time in shader_createFromImage
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two stack allocations is likely cheaper than one heap allocation. Also, I'm not entirely sure it really wins anything to do things on the heap. SkMatrix
is actually not a POD, so you have to actually call the constructor on it (we can't just try to fake construction of it through memory accesses). I wouldn't worry about it much, this is likely to be very fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha. I thought the second one was on the heap.
} | ||
|
||
RuntimeEffectHandle handle; | ||
String name; | ||
int floatUniformCount; | ||
int childShaderCount; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do all of the fields need to be mutable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely not. I should change this.
image as SkwasmImage, | ||
ui.TileMode.clamp, | ||
ui.TileMode.clamp, | ||
toMatrix64(Matrix4.identity().storage), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably cache this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think I should just make this optional and not pass the data at all for the identity case.
final int byteCount = skDataGetSize(dataHandle); | ||
final Pointer<Uint8> dataPointer = skDataGetConstPointer(dataHandle).cast<Uint8>(); | ||
final Uint8List output = Uint8List(byteCount); | ||
for (int i = 0; i < byteCount; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any equivalent to TypedArray.set
for copying one array into another in WasmGC? Then we could create a Uint8List
view into the linear memory and copy it into the GC space as one bulk operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You want WebAssembly/gc#367, which sadly won't make WasmGC MVP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh well...
emscripten_dispatch_to_thread(_thread, EM_FUNC_SIG_VIIII, | ||
reinterpret_cast<void*>(fRasterizeImage), | ||
nullptr, this, image, format, callbackId); | ||
return callbackId; | ||
} | ||
|
||
// Main thread only |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to validate this property at runtime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think I found one. I can make it an assert so that it only executes in debug mode.
uint32_t callbackId) { | ||
sk_sp<SkData> data; | ||
if (format == ImageByteFormat::png) { | ||
data = SkPngEncoder::Encode(_grContext.get(), image, {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A-ha! I bet removing the dependency on SkPngEncoder
will take us below 1MB :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure we can get rid of this though. It might be possible... maybe draw the image to a canvas and then do toDataUrl()
on it? I don't know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, exactly that. I'm not requesting this change in this PR. Just spotted an opportunity for later.
Golden file changes are available for triage from new commit, Click here to view. |
Golden file changes are available for triage from new commit, Click here to view. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…sions) (#126961) Manual roll requested by zra@google.com flutter/engine@fe24767...1c775e3 2023-05-16 zanderso@users.noreply.github.com Revert "[ios_platform_view] only recycle maskView when the view is applying mutators" (flutter/engine#42080) 2023-05-16 gspencergoog@users.noreply.github.com [macOS] Wait for binding to be ready before requesting exits from framework (flutter/engine#41753) 2023-05-16 gspencergoog@users.noreply.github.com [linux] Wait for binding to be ready before requesting exits from framework (flutter/engine#41782) 2023-05-16 jacksongardner@google.com Initial support for images in Skwasm (flutter/engine#42019) 2023-05-16 jacksongardner@google.com Use new `unresolvedCodePoints` API from skia. (flutter/engine#41991) 2023-05-16 jason-simmons@users.noreply.github.com Convert public API NativeFieldWrapper classes to abstract interfaces (flutter/engine#41945) 2023-05-16 737941+loic-sharma@users.noreply.github.com [Windows] Add force redraw to the C++ client wrapper (flutter/engine#42061) 2023-05-16 godofredoc@google.com Fix drone_dimension host_engine_builder. (flutter/engine#42068) 2023-05-16 godofredoc@google.com Add linux_clang_tidy builder. (flutter/engine#41990) 2023-05-16 ychris@google.com [ios_platform_view] only recycle maskView when the view is applying mutators (flutter/engine#41573) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…sions) (flutter#126961) Manual roll requested by zra@google.com flutter/engine@fe24767...1c775e3 2023-05-16 zanderso@users.noreply.github.com Revert "[ios_platform_view] only recycle maskView when the view is applying mutators" (flutter/engine#42080) 2023-05-16 gspencergoog@users.noreply.github.com [macOS] Wait for binding to be ready before requesting exits from framework (flutter/engine#41753) 2023-05-16 gspencergoog@users.noreply.github.com [linux] Wait for binding to be ready before requesting exits from framework (flutter/engine#41782) 2023-05-16 jacksongardner@google.com Initial support for images in Skwasm (flutter/engine#42019) 2023-05-16 jacksongardner@google.com Use new `unresolvedCodePoints` API from skia. (flutter/engine#41991) 2023-05-16 jason-simmons@users.noreply.github.com Convert public API NativeFieldWrapper classes to abstract interfaces (flutter/engine#41945) 2023-05-16 737941+loic-sharma@users.noreply.github.com [Windows] Add force redraw to the C++ client wrapper (flutter/engine#42061) 2023-05-16 godofredoc@google.com Fix drone_dimension host_engine_builder. (flutter/engine#42068) 2023-05-16 godofredoc@google.com Add linux_clang_tidy builder. (flutter/engine#41990) 2023-05-16 ychris@google.com [ios_platform_view] only recycle maskView when the view is applying mutators (flutter/engine#41573) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
This partially implements flutter/flutter#126341
It does not implement image codecs, because they are going to get complicated with transferring video frames to the web worker and so on. I am going to deal with image codecs in a subsequent change.