-
Notifications
You must be signed in to change notification settings - Fork 6k
Reland Skia Caching improvements #10434
Conversation
shell/common/shell_unittests.cc
Outdated
| if (DartVM::IsRunningPrecompiledCode()) { | ||
| // This covers profile and release modes which use AOT (where this flag does | ||
| // This covers profile and release modes which use AOT (where this flag | ||
| does |
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 there are some unintentional reformattings in this file
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.
Yeah clang format reflowed some comments that I then uncommented. Will fix
shell/common/shell_test.cc
Outdated
| shell->GetTaskRunners().GetPlatformTaskRunner(), | ||
| [shell, &latch, message = std::move(message)]() { | ||
| if (!shell->weak_engine_) { | ||
| return; |
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 missed signaling the latch here. Consider instead:
if (auto engine = shell->weak_engine_) {
engine->Handle(...);
}
latch.Signal();
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.
Ahh right, thanks. Fixed.
| } | ||
|
|
||
| void Rasterizer::SetResourceCacheMaxBytes(int max_bytes) { | ||
| void Rasterizer::SetResourceCacheMaxBytes(size_t max_bytes, bool from_user) { |
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.
This API is timing sensitive and depends on the surface already being acquired. It would be better if the cache size in bytes was instead stored in an std::optional<size_t> on the rasterizer.. Then, here and in Rasterizer::Setup, you could use value_or(some_default) to set the cache size of context of the surface. Similarly, the getter would then just the cache size from the optional ivar instead of depending on the surface being present. This scheme would also make the setting survive rasterizer teardown and re-setup.
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.
done
| return; | ||
| } | ||
|
|
||
| GrContext* context = surface_->GetContext(); |
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.
Making this call after Rasterizer::Teardown but before the next Setup will dereference a null pointer.
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.
fixed
|
|
||
| // This is the formula Android uses. | ||
| // https://android.googlesource.com/platform/frameworks/base/+/master/libs/hwui/renderthread/CacheManager.cpp#41 | ||
| size_t max_bytes = metrics.physical_width * metrics.physical_height * 12 * 4; |
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 can move this to a constant in rasterizer and use std::optionals default as discussed above.
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 I'm clear on which part should be the constant. Just the 12 * 4 part?
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.
maybe a static method on rasterizer that takes width and height?
shell/common/rasterizer.h
Outdated
| /// @brief The current value of Skia's resource cache size, if a surface | ||
| /// is present. | ||
| /// | ||
| /// @attention This cache setting will be invalidated when the surface is |
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.
This attention block is not true anymore. You just fixed it :)
| } | ||
|
|
||
| std::optional<size_t> Rasterizer::GetResourceCacheMaxBytes() const { | ||
| if (!surface_) { |
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.
The validity of this call still depends on the the presence of a surface. Why not just access the optional and return the size_t instead of an optional? Now that the value is maintained between teardowns and setups, the contexts cache size should always be consistent with that in the optional.
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.
What happens if this is called before the first setup, and before anyone has attempted to set the metrics?
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.
Return kGrCacheMaxByteSize maybe?
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.
But that's not really accurate, and that symbol is defined as an implementation detail of gl_surface_cpu.cc. It's different on Fuchsia for instance, where they override it in another place.
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.
Ok then. Bad idea. Thanks for clarifying.
| /// | ||
| /// @return The size of Skia's resource cache, if available. | ||
| /// | ||
| std::optional<size_t> GetResourceCacheMaxBytes() const; |
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.
Per discussion above, this can now be just size_t GetResourceCacheMaxBytes() const;
shell/common/shell_unittests.cc
Outdated
| FrameTiming timing; | ||
| for (auto phase : FrameTiming::kPhases) { | ||
| ASSERT_TRUE(phase > lastPhaseIndex); // Ensure that kPhases are in order. | ||
| ASSERT_TRUE(phase > lastPhaseIndex); // Ensure that kPhases are in ƒorder. |
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 don't think you meant to add the function symbol here.
shell/common/shell_unittests.cc
Outdated
| EXPECT_EQ(shell->GetRasterizer()->GetResourceCacheMaxBytes(), 3840000U); | ||
|
|
||
| std::string request_json = | ||
| "{\"method\": \"Skia.setResourceCacheMaxBytes\", \"args\": 10000}"; |
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.
Nit: Consider using raw string literals when constructing JSON (properly formatted) inline for readability. Or use RapidJSON.
| std::vector<uint8_t> data(request_json.begin(), request_json.end()); | ||
| auto platform_message = fml::MakeRefCounted<PlatformMessage>( | ||
| "flutter/skia", std::move(data), nullptr); | ||
| SendEnginePlatformMessage(shell.get(), std::move(platform_message)); |
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.
Can you make sure a reply is received for this message? I think that's broken right now.
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.
There's no reply on this mesage. It's not implemented at all. What's the use case for it?
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.
See b/137134910 for details. Without a reply applications can't await setting this, so have no visibility into when the change has taken effect. I think sending an empty message around here would fix it:
Line 945 in d937b69
| rasterizer->SetResourceCacheMaxBytes(max_bytes); |
message->response->CompleteEmpty() should be enough.
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've added an empty reply and a test for it.
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.
in b50cab1
[email protected]:flutter/engine.git/compare/bd988f6cc3d0...9605017 git log bd988f6..9605017 --no-merges --oneline 2019-08-03 [email protected] Reland Skia Caching improvements (flutter/engine#10434) 2019-08-02 [email protected] Delete unused create_macos_gen_snapshot.py script (flutter/engine#10479) 2019-08-02 [email protected] Add #else, #endif condition comments (flutter/engine#10477) 2019-08-02 [email protected] Roll fuchsia/sdk/core/mac-amd64 from eAnGy... to Mzwf3... (flutter/engine#10476) The AutoRoll server is located here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff ([email protected]), and stop the roller if necessary.
This relands #9503, which was reverted because it didn't work. The underlying problem of letting embedders get the engine directly to set the viewport metrics has been resolved by #9747
This additionally adds a test to make sure these values get set correctly on the Rasterizer.
This patch is important because our current default (512MB) is simply too large for lower end devices with small amounts of RAM. There have been numerous reports of memory usage related crashes when this cache is allowed to grow to its current limit, e.g. on an iPhone with 1GB of RAM.
/cc @abhishekamit - Please let me know if you have concerns with this patch.