[Impeller] libImpeller: Expose APIs to draw shadows. (#165517)

Fixes https://github.com/flutter/flutter/issues/165146
This commit is contained in:
Chinmay Garde 2025-03-20 10:28:00 -07:00 committed by GitHub
parent 554c814ada
commit 2db84b20f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 102 additions and 0 deletions

View File

@ -181,4 +181,17 @@ void DisplayListBuilder::DrawParagraph(const Paragraph& paragraph,
handle->Paint(&builder_, point.x, point.y);
}
void DisplayListBuilder::DrawShadow(const Path& path,
const flutter::DlColor& color,
float elevation,
bool occluder_is_transparent,
float device_pixel_ratio) {
builder_.DrawShadow(flutter::DlPath(path.GetPath()), // path
color, // shadow color
elevation, // elevation
occluder_is_transparent, // occluder transparency
device_pixel_ratio // dpr
);
}
} // namespace impeller::interop

View File

@ -110,6 +110,12 @@ class DisplayListBuilder final
void DrawParagraph(const Paragraph& paragraph, Point point);
void DrawShadow(const Path& path,
const flutter::DlColor& color,
float elevation,
bool occluder_is_transparent,
float device_pixel_ratio);
ScopedObject<DisplayList> Build();
private:

View File

@ -1150,6 +1150,21 @@ void ImpellerDisplayListBuilderDrawParagraph(ImpellerDisplayListBuilder builder,
GetPeer(builder)->DrawParagraph(*GetPeer(paragraph), ToImpellerType(*point));
}
IMPELLER_EXTERN_C
void ImpellerDisplayListBuilderDrawShadow(ImpellerDisplayListBuilder builder,
ImpellerPath path,
const ImpellerColor* color,
float elevation,
bool occluder_is_transparent,
float device_pixel_ratio) {
GetPeer(builder)->DrawShadow(*GetPeer(path), //
ToDisplayListType(*color), //
elevation, //
occluder_is_transparent, //
device_pixel_ratio //
);
}
IMPELLER_EXTERN_C
ImpellerParagraphBuilder ImpellerParagraphBuilderNew(
ImpellerTypographyContext context) {

View File

@ -2098,6 +2098,30 @@ void ImpellerDisplayListBuilderDrawParagraph(
ImpellerParagraph IMPELLER_NONNULL paragraph,
const ImpellerPoint* IMPELLER_NONNULL point);
//------------------------------------------------------------------------------
/// @brief Draw a shadow for a Path given a material elevation. If the
/// occluding object is not opaque, additional hints (via the
/// `occluder_is_transparent` argument) must be provided to render
/// the shadow correctly.
///
/// @param[in] builder The builder.
/// @param[in] path The shadow path.
/// @param[in] color The shadow color.
/// @param[in] elevation The material elevation.
/// @param[in] occluder_is_transparent
/// If the object casting the shadow is transparent.
/// @param[in] device_pixel_ratio
/// The device pixel ratio.
///
IMPELLER_EXPORT
void ImpellerDisplayListBuilderDrawShadow(
ImpellerDisplayListBuilder IMPELLER_NONNULL builder,
ImpellerPath IMPELLER_NONNULL path,
const ImpellerColor* IMPELLER_NONNULL color,
float elevation,
bool occluder_is_transparent,
float device_pixel_ratio);
//------------------------------------------------------------------------------
// Display List Builder: Drawing Textures
//------------------------------------------------------------------------------

View File

@ -73,6 +73,7 @@ struct Proc {
PROC(ImpellerDisplayListBuilderDrawOval) \
PROC(ImpellerDisplayListBuilderDrawPaint) \
PROC(ImpellerDisplayListBuilderDrawParagraph) \
PROC(ImpellerDisplayListBuilderDrawShadow) \
PROC(ImpellerDisplayListBuilderDrawPath) \
PROC(ImpellerDisplayListBuilderDrawRect) \
PROC(ImpellerDisplayListBuilderDrawRoundedRect) \
@ -1345,6 +1346,20 @@ class DisplayListBuilder final
return *this;
}
//----------------------------------------------------------------------------
/// @see ImpellerDisplayListBuilderDrawShadow
///
DisplayListBuilder& DrawShadow(const Path& path,
const ImpellerColor& shadow_color,
float elevation,
bool occluder_is_transparent,
float device_pixel_ratio) {
gGlobalProcTable.ImpellerDisplayListBuilderDrawShadow(
Get(), path.Get(), &shadow_color, elevation, occluder_is_transparent,
device_pixel_ratio);
return *this;
}
//----------------------------------------------------------------------------
/// @see ImpellerDisplayListBuilderDrawPath
///

View File

@ -474,4 +474,33 @@ TEST_P(InteropPlaygroundTest, CanRenderTextAlignments) {
}));
}
TEST_P(InteropPlaygroundTest, CanRenderShadows) {
hpp::DisplayListBuilder builder;
{
builder.DrawRect(ImpellerRect{0, 0, 400, 400},
hpp::Paint{}.SetColor(ImpellerColor{
0.0, 1.0, 0.0, 1.0, kImpellerColorSpaceSRGB}));
}
ImpellerRect box = {100, 100, 100, 100};
{
hpp::PathBuilder path_builder;
path_builder.AddRect(box);
ImpellerColor shadow_color = {0.0, 0.0, 0.0, 1.0, kImpellerColorSpaceSRGB};
builder.DrawShadow(path_builder.Build(), shadow_color, 4.0f, false, 1.0f);
}
{
hpp::Paint red_paint;
red_paint.SetColor(
ImpellerColor{1.0, 0.0, 0.0, 1.0, kImpellerColorSpaceSRGB});
builder.DrawRect(box, red_paint);
}
auto dl = builder.Build();
ASSERT_TRUE(
OpenPlaygroundHere([&](const auto& context, const auto& surface) -> bool {
hpp::Surface window(surface.GetC());
window.Draw(dl);
return true;
}));
}
} // namespace impeller::interop::testing