-
Notifications
You must be signed in to change notification settings - Fork 6k
[Impeller] implement experimental canvas in snapshot controller. #53750
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,9 @@ | |
#include "flutter/impeller/display_list/dl_image_impeller.h" | ||
#include "flutter/impeller/geometry/size.h" | ||
#include "flutter/shell/common/snapshot_controller.h" | ||
#include "impeller/renderer/render_target.h" | ||
|
||
#define EXPERIMENTAL_CANVAS false | ||
|
||
namespace flutter { | ||
|
||
|
@@ -21,37 +24,84 @@ sk_sp<DlImage> DoMakeRasterSnapshot( | |
SkISize size, | ||
const std::shared_ptr<impeller::AiksContext>& context) { | ||
TRACE_EVENT0("flutter", __FUNCTION__); | ||
if (!context) { | ||
return nullptr; | ||
} | ||
// Determine render target size. | ||
auto max_size = context->GetContext() | ||
->GetResourceAllocator() | ||
->GetMaxTextureSizeSupported(); | ||
double scale_factor_x = | ||
static_cast<double>(max_size.width) / static_cast<double>(size.width()); | ||
double scale_factor_y = | ||
static_cast<double>(max_size.height) / static_cast<double>(size.height()); | ||
double scale_factor = std::min(1.0, std::min(scale_factor_x, scale_factor_y)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC, std::min has an overload that takes an initializer list. So you should be able do do just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
|
||
auto render_target_size = impeller::ISize(size.width(), size.height()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
|
||
// Scale down the render target size to the max supported by the | ||
// GPU if necessary. Exceeding the max would otherwise cause a | ||
// null result. | ||
if (scale_factor < 1.0) { | ||
render_target_size.width *= scale_factor; | ||
render_target_size.height *= scale_factor; | ||
} | ||
|
||
#if EXPERIMENTAL_CANVAS | ||
// Do not use the render target cache as the lifecycle of this texture | ||
// will outlive a particular frame. | ||
impeller::ISize impeller_size = impeller::ISize(size.width(), size.height()); | ||
impeller::RenderTargetAllocator render_target_allocator = | ||
impeller::RenderTargetAllocator( | ||
context->GetContext()->GetResourceAllocator()); | ||
impeller::RenderTarget target; | ||
if (context->GetContext()->GetCapabilities()->SupportsOffscreenMSAA()) { | ||
target = render_target_allocator.CreateOffscreenMSAA( | ||
*context->GetContext(), // context | ||
impeller_size, // size | ||
/*mip_count=*/1, | ||
"Picture Snapshot MSAA", // label | ||
impeller::RenderTarget:: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: This could perhaps be dried up using a ternary since only the last argument differs based on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean adding a new CreateOffscreen that differentiates MSAA via an argument? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nothing as involved as all that. Just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But the methods are different There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. derp. Sorry. |
||
kDefaultColorAttachmentConfigMSAA // color_attachment_config | ||
); | ||
} else { | ||
target = render_target_allocator.CreateOffscreen( | ||
*context->GetContext(), // context | ||
impeller_size, // size | ||
/*mip_count=*/1, | ||
"Picture Snapshot", // label | ||
impeller::RenderTarget:: | ||
kDefaultColorAttachmentConfig // color_attachment_config | ||
); | ||
} | ||
|
||
impeller::TextFrameDispatcher collector(context->GetContentContext(), | ||
impeller::Matrix()); | ||
display_list->Dispatch(collector, SkIRect::MakeSize(size)); | ||
impeller::ExperimentalDlDispatcher impeller_dispatcher( | ||
context->GetContentContext(), target, | ||
display_list->root_has_backdrop_filter(), | ||
display_list->max_root_blend_mode(), | ||
impeller::IRect::MakeSize(impeller_size)); | ||
display_list->Dispatch(impeller_dispatcher, SkIRect::MakeSize(size)); | ||
impeller_dispatcher.FinishRecording(); | ||
|
||
context->GetContentContext().GetLazyGlyphAtlas()->ResetTextFrames(); | ||
|
||
return impeller::DlImageImpeller::Make(target.GetRenderTargetTexture(), | ||
DlImage::OwningContext::kRaster); | ||
#else | ||
impeller::DlDispatcher dispatcher; | ||
display_list->Dispatch(dispatcher); | ||
impeller::Picture picture = dispatcher.EndRecordingAsPicture(); | ||
if (context) { | ||
auto max_size = context->GetContext() | ||
->GetResourceAllocator() | ||
->GetMaxTextureSizeSupported(); | ||
double scale_factor_x = | ||
static_cast<double>(max_size.width) / static_cast<double>(size.width()); | ||
double scale_factor_y = static_cast<double>(max_size.height) / | ||
static_cast<double>(size.height()); | ||
double scale_factor = | ||
std::min(1.0, std::min(scale_factor_x, scale_factor_y)); | ||
|
||
auto render_target_size = impeller::ISize(size.width(), size.height()); | ||
|
||
// Scale down the render target size to the max supported by the | ||
// GPU if necessary. Exceeding the max would otherwise cause a | ||
// null result. | ||
if (scale_factor < 1.0) { | ||
render_target_size.width *= scale_factor; | ||
render_target_size.height *= scale_factor; | ||
} | ||
|
||
std::shared_ptr<impeller::Image> image = | ||
picture.ToImage(*context, render_target_size); | ||
if (image) { | ||
return impeller::DlImageImpeller::Make(image->GetTexture(), | ||
DlImage::OwningContext::kRaster); | ||
} | ||
|
||
std::shared_ptr<impeller::Image> image = | ||
picture.ToImage(*context, render_target_size); | ||
if (image) { | ||
return impeller::DlImageImpeller::Make(image->GetTexture(), | ||
DlImage::OwningContext::kRaster); | ||
} | ||
#endif // EXPERIMENTAL_CANVAS | ||
|
||
return nullptr; | ||
} | ||
|
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 some context on why this isn't in a GN rule somewhere and applied globally instead of on a per TU basis?
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.
factoring out to a gn rule seems like a good idea, will make it easier to flip on/off to see if there are any golden diffs or test failures.
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.
Don't mean to block this patch though. We can do that later.
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.
It was easy, done.