Flutter Impeller
impeller::testing Namespace Reference

Classes

class  ArchivistFixture
 
struct  BlendModeSelection
 
class  CompareFunctionUIData
 
struct  Foo
 
class  GoldenDigest
 Manages a global variable for tracking instances of golden images. More...
 
class  GoldenTests
 
class  MetalScreenshot
 A screenshot that was produced from MetalScreenshoter. More...
 
class  MetalScreenshoter
 Converts Pictures to MetalScreenshots with the playground backend. More...
 
class  RendererDartTest
 
struct  RWFoo
 
class  Sample
 
class  SampleWithVector
 
class  TestAllocator
 
class  TestPassDelegate
 
class  TestRenderTargetAllocator
 
struct  TextRenderOptions
 
class  WorkingDirectory
 

Typedefs

using AiksTest = AiksPlayground
 
using AiksCanvasTest = ::testing::Test
 
using ArchiveTest = ArchivistFixture
 
using DisplayListTest = DlPlayground
 
using EntityTest = EntityPlayground
 
using ComputeSubgroupTest = ComputePlaygroundTest
 
using ComputeTest = ComputePlaygroundTest
 
using DeviceBufferTest = Playground
 
using RendererTest = PlaygroundTest
 
using RuntimeStageTest = RuntimeStagePlayground
 
using TypographerTest = PlaygroundTest
 

Functions

 INSTANTIATE_PLAYGROUND_SUITE (AiksTest)
 
 TEST_P (AiksTest, RotateColorFilteredPath)
 
 TEST_P (AiksTest, CanvasCTMCanBeUpdated)
 
 TEST_P (AiksTest, CanvasCanPushPopCTM)
 
 TEST_P (AiksTest, CanRenderColoredRect)
 
 TEST_P (AiksTest, CanRenderImage)
 
 TEST_P (AiksTest, CanRenderInvertedImage)
 
 TEST_P (AiksTest, CanRenderTiledTextureClamp)
 
 TEST_P (AiksTest, CanRenderTiledTextureRepeat)
 
 TEST_P (AiksTest, CanRenderTiledTextureMirror)
 
 TEST_P (AiksTest, CanRenderTiledTextureDecal)
 
 TEST_P (AiksTest, CanRenderTiledTextureClampWithTranslate)
 
 TEST_P (AiksTest, CanRenderImageRect)
 
 TEST_P (AiksTest, CanRenderStrokes)
 
 TEST_P (AiksTest, CanRenderCurvedStrokes)
 
 TEST_P (AiksTest, CanRenderClips)
 
 TEST_P (AiksTest, CanRenderNestedClips)
 
 TEST_P (AiksTest, CanRenderDifferenceClips)
 
 TEST_P (AiksTest, CanRenderWithContiguousClipRestores)
 
 TEST_P (AiksTest, ClipsUseCurrentTransform)
 
 TEST_P (AiksTest, CanSaveLayerStandalone)
 
 TEST_P (AiksTest, CanRenderLinearGradientClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientDecalWithColorFilter)
 
static void CanRenderLinearGradientWithDithering (AiksTest *aiks_test, bool use_dithering)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithDitheringDisabled)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithDitheringEnabled)
 
static void CanRenderRadialGradientWithDithering (AiksTest *aiks_test, bool use_dithering)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithDitheringDisabled)
 
 TEST_P (AiksTest, CanRenderRadialGradientWithDitheringEnabled)
 
static void CanRenderSweepGradientWithDithering (AiksTest *aiks_test, bool use_dithering)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithDitheringDisabled)
 
 TEST_P (AiksTest, CanRenderSweepGradientWithDitheringEnabled)
 
static void CanRenderConicalGradientWithDithering (AiksTest *aiks_test, bool use_dithering)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithDitheringDisabled)
 
 TEST_P (AiksTest, CanRenderConicalGradientWithDitheringEnabled)
 
 TEST_P (AiksTest, CanRenderLinearGradientWithOverlappingStopsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderLinearGradientWayManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderLinearGradientManyColorsUnevenStops)
 
 TEST_P (AiksTest, CanRenderLinearGradientMaskBlur)
 
 TEST_P (AiksTest, CanRenderRadialGradient)
 
 TEST_P (AiksTest, CanRenderRadialGradientManyColors)
 
 TEST_P (AiksTest, CanRenderSweepGradientClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientDecal)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsClamp)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsRepeat)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsMirror)
 
 TEST_P (AiksTest, CanRenderSweepGradientManyColorsDecal)
 
 TEST_P (AiksTest, CanRenderConicalGradient)
 
 TEST_P (AiksTest, CanRenderGradientDecalWithBackground)
 
 TEST_P (AiksTest, CanRenderDifferentShapesWithSameColorSource)
 
 TEST_P (AiksTest, CanPictureConvertToImage)
 
 TEST_P (AiksTest, BlendModeShouldCoverWholeScreen)
 
 TEST_P (AiksTest, CanRenderGroupOpacity)
 
 TEST_P (AiksTest, CoordinateConversionsAreCorrect)
 
 TEST_P (AiksTest, CanPerformFullScreenMSAA)
 
 TEST_P (AiksTest, CanPerformSkew)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBounds)
 
 TEST_P (AiksTest, CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated)
 
 TEST_P (AiksTest, CanRenderRoundedRectWithNonUniformRadii)
 
 TEST_P (AiksTest, CanRenderDifferencePaths)
 
 TEST_P (AiksTest, CanDrawAnOpenPath)
 
 TEST_P (AiksTest, CanDrawAnOpenPathThatIsntARect)
 
static sk_sp< SkData > OpenFixtureAsSkData (const char *fixture_name)
 
bool RenderTextInCanvasSkia (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
 
bool RenderTextInCanvasSTB (const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
 
 TEST_P (AiksTest, CanRenderTextFrame)
 
 TEST_P (AiksTest, CanRenderTextFrameSTB)
 
 TEST_P (AiksTest, TextFrameSubpixelAlignment)
 
 TEST_P (AiksTest, CanRenderItalicizedText)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrame)
 
 TEST_P (AiksTest, CanRenderEmojiTextFrameWithAlpha)
 
 TEST_P (AiksTest, CanRenderTextInSaveLayer)
 
 TEST_P (AiksTest, CanRenderTextOutsideBoundaries)
 
 TEST_P (AiksTest, TextRotated)
 
 TEST_P (AiksTest, CanDrawPaint)
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimes)
 
 TEST_P (AiksTest, CanDrawPaintWithAdvancedBlend)
 
 TEST_P (AiksTest, DrawPaintWithAdvancedBlendOverFilter)
 
 TEST_P (AiksTest, DrawAdvancedBlendPartlyOffscreen)
 
static BlendModeSelection GetBlendModeSelection ()
 
 TEST_P (AiksTest, CanDrawPaintMultipleTimesInteractive)
 
 TEST_P (AiksTest, PaintBlendModeIsRespected)
 
 TEST_P (AiksTest, ColorWheel)
 
 TEST_P (AiksTest, TransformMultipliesCorrectly)
 
 TEST_P (AiksTest, SolidStrokesRenderCorrectly)
 
 TEST_P (AiksTest, GradientStrokesRenderCorrectly)
 
 TEST_P (AiksTest, CoverageOriginShouldBeAccountedForInSubpasses)
 
 TEST_P (AiksTest, DrawRectStrokesRenderCorrectly)
 
 TEST_P (AiksTest, SaveLayerDrawsBehindSubsequentEntities)
 
 TEST_P (AiksTest, SiblingSaveLayerBoundsAreRespected)
 
 TEST_P (AiksTest, CanRenderClippedLayers)
 
 TEST_P (AiksTest, SaveLayerFiltersScaleWithTransform)
 
 TEST_P (AiksTest, PaintWithFilters)
 
 TEST_P (AiksTest, OpacityPeepHoleApplicationTest)
 
 TEST_P (AiksTest, DrawPaintAbsorbsClears)
 
 TEST_P (AiksTest, ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent)
 
 TEST_P (AiksTest, DrawRectAbsorbsClears)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRRect)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegativeRotation)
 
 TEST_P (AiksTest, DrawRectAbsorbsClearsNegative)
 
 TEST_P (AiksTest, ClipRectElidesNoOpClips)
 
 TEST_P (AiksTest, ClearColorOptimizationDoesNotApplyForBackdropFilters)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpass)
 
 TEST_P (AiksTest, CollapsedDrawPaintInSubpassBackdropFilter)
 
 TEST_P (AiksTest, ForegroundBlendSubpassCollapseOptimization)
 
 TEST_P (AiksTest, ColorMatrixFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, LinearToSrgbFilterSubpassCollapseOptimization)
 
 TEST_P (AiksTest, SrgbToLinearFilterSubpassCollapseOptimization)
 
static Picture BlendModeTest (BlendMode blend_mode, const std::shared_ptr< Image > &src_image, const std::shared_ptr< Image > &dst_image)
 
 TEST_P (AiksTest, TranslucentSaveLayerDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerImageDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly)
 
 TEST_P (AiksTest, TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly)
 
 TEST_P (AiksTest, CanRenderTinyOverlappingSubpasses)
 
 TEST_P (AiksTest, CanRenderOffscreenCheckerboard)
 
 TEST_P (AiksTest, OpaqueEntitiesGetCoercedToSource)
 
 TEST_P (AiksTest, CanRenderDestructiveSaveLayer)
 
 TEST_P (AiksTest, CanRenderMaskBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderBackdropBlurInteractive)
 
 TEST_P (AiksTest, CanRenderBackdropBlur)
 
 TEST_P (AiksTest, CanRenderBackdropBlurHugeSigma)
 
 TEST_P (AiksTest, CanRenderClippedBlur)
 
 TEST_P (AiksTest, CanRenderForegroundBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderForegroundAdvancedBlendWithMaskBlur)
 
 TEST_P (AiksTest, CanRenderClippedRuntimeEffects)
 
 TEST_P (AiksTest, DrawPaintTransformsBounds)
 
 TEST_P (AiksTest, CanDrawPoints)
 
 TEST_P (AiksTest, DrawAtlasWithColorAdvancedAndTransform)
 
 TEST_P (AiksTest, DrawAtlasAdvancedAndTransform)
 
 TEST_P (AiksTest, CanDrawPointsWithTextureMap)
 
 TEST_P (AiksTest, TextForegroundShaderWithTransform)
 
 TEST_P (AiksTest, CanCanvasDrawPicture)
 
 TEST_P (AiksTest, CanCanvasDrawPictureWithAdvancedBlend)
 
 TEST_P (AiksTest, CanCanvasDrawPictureWithBackdropFilter)
 
 TEST_P (AiksTest, DrawPictureWithText)
 
 TEST_P (AiksTest, DrawPictureClipped)
 
 TEST_P (AiksTest, MatrixSaveLayerFilter)
 
 TEST_P (AiksTest, MatrixBackdropFilter)
 
 TEST_P (AiksTest, SolidColorApplyColorFilter)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Linear)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Radial)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Conical)
 
 APPLY_COLOR_FILTER_GRADIENT_TEST (Sweep)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer)
 
 TEST_P (AiksTest, DrawScaledTextWithPerspectiveSaveLayer)
 
 TEST_P (AiksTest, PipelineBlendSingleParameter)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectlyInteractive)
 
 TEST_P (AiksTest, ClippedBlurFilterRendersCorrectly)
 
 TEST_P (AiksTest, CaptureContext)
 
 TEST_P (AiksTest, CaptureInactivatedByDefault)
 
 TEST_P (AiksTest, ReleasesTextureOnTeardown)
 
 TEST_P (AiksTest, VerticesGeometryUVPositionData)
 
 TEST_P (AiksTest, ClearBlendWithBlur)
 
 TEST_P (AiksTest, ClearBlend)
 
 TEST_P (AiksTest, MatrixImageFilterMagnify)
 
 TEST_P (AiksTest, ClearColorOptimizationWhenSubpassIsBiggerThanParentPass)
 
 TEST_P (AiksTest, MaskBlurWithZeroSigmaIsSkipped)
 
 TEST_P (AiksTest, SubpassWithClearColorOptimization)
 
 TEST (AiksCanvasTest, EmptyCullRect)
 
 TEST (AiksCanvasTest, InitialCullRect)
 
 TEST (AiksCanvasTest, TranslatedCullRect)
 
 TEST (AiksCanvasTest, ScaledCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAboveCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffBelowCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffLeftOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffRightOfCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstVCoveredCullRect)
 
 TEST (AiksCanvasTest, RectClipDiffAgainstHCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, RRectClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect)
 
 TEST (AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstEmptyCullRect)
 
 TEST (AiksCanvasTest, PathClipIntersectAgainstCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstNonCoveredCullRect)
 
 TEST (AiksCanvasTest, PathClipDiffAgainstFullyCoveredCullRect)
 
 TEST (AiksCanvasTest, DisableLocalBoundsRectForFilteredSaveLayers)
 
 TEST_F (ArchiveTest, SimpleInitialization)
 
 TEST_F (ArchiveTest, AddStorageClass)
 
 TEST_F (ArchiveTest, AddData)
 
 TEST_F (ArchiveTest, AddDataMultiple)
 
 TEST_F (ArchiveTest, ReadData)
 
 TEST_F (ArchiveTest, ReadDataWithNames)
 
 TEST_F (ArchiveTest, CanReadWriteVectorOfArchivables)
 
 TEST (ThreadTest, CanCreateMutex)
 
 TEST (ThreadTest, CanCreateMutexLock)
 
 TEST (ThreadTest, CanCreateRWMutex)
 
 TEST (ThreadTest, CanCreateRWMutexLock)
 
 TEST (StringsTest, CanSPrintF)
 
static std::shared_ptr< fml::Mapping > CreateMappingFromString (std::string p_string)
 
const std::string CreateStringFromMapping (const fml::Mapping &mapping)
 
 TEST (BlobTest, CanReadAndWriteBlobs)
 
 TEST (AllocatorTest, TextureDescriptorCompatibility)
 
flutter::DlColor toColor (const float *components)
 
 INSTANTIATE_PLAYGROUND_SUITE (DisplayListTest)
 
 TEST_P (DisplayListTest, DrawPictureWithAClip)
 
 TEST_P (DisplayListTest, CanDrawRect)
 
 TEST_P (DisplayListTest, CanDrawTextBlob)
 
 TEST_P (DisplayListTest, CanDrawTextBlobWithGradient)
 
 TEST_P (DisplayListTest, CanDrawTextWithSaveLayer)
 
 TEST_P (DisplayListTest, CanDrawImage)
 
 TEST_P (DisplayListTest, CanDrawCapsAndJoins)
 
 TEST_P (DisplayListTest, CanDrawArc)
 
 TEST_P (DisplayListTest, StrokedPathsDrawCorrectly)
 
 TEST_P (DisplayListTest, CanDrawWithOddPathWinding)
 
 TEST_P (DisplayListTest, CanDrawAnOpenPath)
 
 TEST_P (DisplayListTest, CanDrawWithMaskBlur)
 
 TEST_P (DisplayListTest, CanDrawStrokedText)
 
 TEST_P (DisplayListTest, StrokedTextNotOffsetFromNormalText)
 
 TEST_P (DisplayListTest, IgnoreMaskFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawWithBlendColorFilter)
 
 TEST_P (DisplayListTest, CanDrawWithColorFilterImageFilter)
 
 TEST_P (DisplayListTest, CanDrawWithImageBlurFilter)
 
 TEST_P (DisplayListTest, CanDrawWithComposeImageFilter)
 
 TEST_P (DisplayListTest, CanClampTheResultingColorOfColorMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawBackdropFilter)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImage)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterWidthBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterHeightBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCenterBiggerThanDest)
 
 TEST_P (DisplayListTest, CanDrawNinePatchImageCornersScaledDown)
 
 TEST_P (DisplayListTest, CanDrawPoints)
 
 TEST_P (DisplayListTest, CanDrawZeroLengthLine)
 
 TEST_P (DisplayListTest, CanDrawShadow)
 
 TEST_P (DisplayListTest, DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists)
 
 TEST_P (DisplayListTest, TransparentShadowProducesCorrectColor)
 
 TEST_P (DisplayListTest, CanConvertTriangleFanToTriangles)
 
 TEST_P (DisplayListTest, CanDrawZeroWidthLine)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilter)
 
 TEST_P (DisplayListTest, CanDrawWithMatrixFilterWhenSavingLayer)
 
 TEST_P (DisplayListTest, CanDrawRectWithLinearToSrgbColorFilter)
 
 TEST_P (DisplayListTest, CanDrawPaintWithColorSource)
 
 TEST_P (DisplayListTest, CanBlendDstOverAndDstCorrectly)
 
 TEST_P (DisplayListTest, CanDrawCorrectlyWithColorFilterAndImageFilter)
 
 TEST_P (DisplayListTest, MaskBlursApplyCorrectlyToColorSources)
 
 TEST_P (DisplayListTest, DrawVerticesSolidColorTrianglesWithoutIndices)
 
 TEST_P (DisplayListTest, DrawVerticesLinearGradientWithoutIndices)
 
 TEST_P (DisplayListTest, DrawVerticesLinearGradientWithTextureCoordinates)
 
 TEST_P (DisplayListTest, DrawVerticesImageSourceWithTextureCoordinates)
 
 TEST_P (DisplayListTest, DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending)
 
 TEST_P (DisplayListTest, DrawVerticesSolidColorTrianglesWithIndices)
 
 TEST_P (DisplayListTest, DrawVerticesPremultipliesColors)
 
 TEST_P (DisplayListTest, DrawShapes)
 
 TEST_P (DisplayListTest, DrawVerticesBlendModes)
 
 TEST (SkiaConversionsTest, ToColor)
 
 TEST (SkiaConversionsTest, GradientStopConversion)
 
 TEST (SkiaConversionsTest, GradientMissing0)
 
 TEST (SkiaConversionsTest, GradientMissingLastValue)
 
 TEST (SkiaConversionsTest, GradientStopGreaterThan1)
 
 TEST (SkiaConversionsTest, GradientConversionNonMonotonic)
 
 TEST (FilterInputTest, CanSetLocalTransformForTexture)
 
 TEST (FilterInputTest, IsLeaf)
 
 TEST (FilterInputTest, SetCoverageInputs)
 
 INSTANTIATE_PLAYGROUND_SUITE (EntityTest)
 
 TEST_P (EntityTest, CanCreateEntity)
 
auto CreatePassWithRectPath (Rect rect, std::optional< Rect > bounds_hint, bool collapse=false)
 
 TEST_P (EntityTest, EntityPassRespectsSubpassBoundsLimit)
 
 TEST_P (EntityTest, EntityPassCanMergeSubpassIntoParent)
 
 TEST_P (EntityTest, EntityPassCoverageRespectsCoverageLimit)
 
 TEST_P (EntityTest, FilterCoverageRespectsCropRect)
 
 TEST_P (EntityTest, CanDrawRect)
 
 TEST_P (EntityTest, CanDrawRRect)
 
 TEST_P (EntityTest, GeometryBoundsAreTransformed)
 
 TEST_P (EntityTest, ThreeStrokesInOnePath)
 
 TEST_P (EntityTest, StrokeWithTextureContents)
 
 TEST_P (EntityTest, TriangleInsideASquare)
 
 TEST_P (EntityTest, StrokeCapAndJoinTest)
 
 TEST_P (EntityTest, CubicCurveTest)
 
 TEST_P (EntityTest, CanDrawCorrectlyWithRotatedTransformation)
 
 TEST_P (EntityTest, CubicCurveAndOverlapTest)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins)
 
 TEST_P (EntityTest, SolidColorContentsStrokeSetMiterLimit)
 
 TEST_P (EntityTest, BlendingModeOptions)
 
 TEST_P (EntityTest, BezierCircleScaled)
 
 TEST_P (EntityTest, Filters)
 
 TEST_P (EntityTest, GaussianBlurFilter)
 
 TEST_P (EntityTest, MorphologyFilter)
 
 TEST_P (EntityTest, SetBlendMode)
 
 TEST_P (EntityTest, ContentsGetBoundsForEmptyPathReturnsNullopt)
 
 TEST_P (EntityTest, SolidStrokeCoverageIsCorrect)
 
 TEST_P (EntityTest, BorderMaskBlurCoverageIsCorrect)
 
 TEST_P (EntityTest, DrawAtlasNoColor)
 
 TEST_P (EntityTest, DrawAtlasWithColorAdvanced)
 
 TEST_P (EntityTest, DrawAtlasWithColorSimple)
 
 TEST_P (EntityTest, DrawAtlasUsesProvidedCullRectForCoverage)
 
 TEST_P (EntityTest, DrawAtlasWithOpacity)
 
 TEST_P (EntityTest, DrawAtlasNoColorFullSize)
 
 TEST_P (EntityTest, SolidFillCoverageIsCorrect)
 
 TEST_P (EntityTest, SolidFillShouldRenderIsCorrect)
 
 TEST_P (EntityTest, DoesNotCullEntitiesByDefault)
 
 TEST_P (EntityTest, ClipContentsShouldRenderIsCorrect)
 
 TEST_P (EntityTest, ClipContentsGetStencilCoverageIsCorrect)
 
 TEST_P (EntityTest, RRectShadowTest)
 
 TEST_P (EntityTest, ColorMatrixFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, ColorMatrixFilterEditable)
 
 TEST_P (EntityTest, LinearToSrgbFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, LinearToSrgbFilter)
 
 TEST_P (EntityTest, SrgbToLinearFilterCoverageIsCorrect)
 
 TEST_P (EntityTest, SrgbToLinearFilter)
 
 TEST_P (EntityTest, AtlasContentsSubAtlas)
 
static Vector3 RGBToYUV (Vector3 rgb, YUVColorSpace yuv_color_space)
 
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures (Context *context, YUVColorSpace yuv_color_space)
 
 TEST_P (EntityTest, YUVToRGBFilter)
 
 TEST_P (EntityTest, RuntimeEffect)
 
 TEST_P (EntityTest, InheritOpacityTest)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorAdvancedBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorClearBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorDstBlend)
 
 TEST_P (EntityTest, ColorFilterWithForegroundColorSrcInBlend)
 
 TEST_P (EntityTest, CoverageForStrokePathWithNegativeValuesInTransform)
 
 TEST_P (EntityTest, SolidColorContentsIsOpaque)
 
 TEST_P (EntityTest, ConicalGradientContentsIsOpaque)
 
 TEST_P (EntityTest, LinearGradientContentsIsOpaque)
 
 TEST_P (EntityTest, RadialGradientContentsIsOpaque)
 
 TEST_P (EntityTest, SweepGradientContentsIsOpaque)
 
 TEST_P (EntityTest, TiledTextureContentsIsOpaque)
 
 TEST_P (EntityTest, TessellateConvex)
 
 TEST_P (EntityTest, PointFieldGeometryDivisions)
 
 TEST_P (EntityTest, PointFieldGeometryCoverage)
 
 TEST_P (EntityTest, ColorFilterContentsWithLargeGeometry)
 
 TEST_P (EntityTest, TextContentsCeilsGlyphScaleToDecimal)
 
 TEST_P (EntityTest, AdvancedBlendCoverageHintIsNotResetByEntityPass)
 
 TEST (EntityGeometryTest, RectGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversArea)
 
 TEST (EntityGeometryTest, FillPathGeometryCoversAreaNoInnerRect)
 
 TEST (RenderTargetCacheTest, CachesUsedTexturesAcrossFrames)
 
 TEST (RenderTargetCacheTest, DoesNotPersistFailedAllocations)
 
 TEST (GeometryTest, ScalarNearlyEqual)
 
 TEST (GeometryTest, MakeColumn)
 
 TEST (GeometryTest, MakeRow)
 
 TEST (GeometryTest, RotationMatrix)
 
 TEST (GeometryTest, InvertMultMatrix)
 
 TEST (GeometryTest, MatrixBasis)
 
 TEST (GeometryTest, MutliplicationMatrix)
 
 TEST (GeometryTest, DeterminantTest)
 
 TEST (GeometryTest, InvertMatrix)
 
 TEST (GeometryTest, TestDecomposition)
 
 TEST (GeometryTest, TestDecomposition2)
 
 TEST (GeometryTest, TestRecomposition)
 
 TEST (GeometryTest, TestRecomposition2)
 
 TEST (GeometryTest, MatrixVectorMultiplication)
 
 TEST (GeometryTest, MatrixMakeRotationFromQuaternion)
 
 TEST (GeometryTest, MatrixTransformDirection)
 
 TEST (GeometryTest, MatrixGetMaxBasisLength)
 
 TEST (GeometryTest, MatrixGetMaxBasisLengthXY)
 
 TEST (GeometryTest, MatrixMakeOrthographic)
 
 TEST (GeometryTest, MatrixMakePerspective)
 
 TEST (GeometryTest, MatrixGetBasisVectors)
 
 TEST (GeometryTest, MatrixGetDirectionScale)
 
 TEST (GeometryTest, MatrixIsAligned)
 
 TEST (GeometryTest, MatrixTranslationScaleOnly)
 
 TEST (GeometryTest, MatrixLookAt)
 
 TEST (GeometryTest, QuaternionLerp)
 
 TEST (GeometryTest, QuaternionVectorMultiply)
 
 TEST (GeometryTest, EmptyPath)
 
 TEST (GeometryTest, SimplePath)
 
 TEST (GeometryTest, BoundingBoxCubic)
 
 TEST (GeometryTest, BoundingBoxOfCompositePathIsCorrect)
 
 TEST (GeometryTest, ExtremaOfCubicPathComponentIsCorrect)
 
 TEST (GeometryTest, PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect)
 
 TEST (GeometryTest, CanGenerateMipCounts)
 
 TEST (GeometryTest, CanConvertTTypesExplicitly)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOps)
 
 TEST (GeometryTest, CanPerformAlgebraicPointOpsWithArithmeticTypes)
 
 TEST (GeometryTest, PointIntegerCoercesToFloat)
 
 TEST (GeometryTest, SizeCoercesToPoint)
 
 TEST (GeometryTest, CanUsePointAssignmentOperators)
 
 TEST (GeometryTest, PointDotProduct)
 
 TEST (GeometryTest, PointCrossProduct)
 
 TEST (GeometryTest, PointReflect)
 
 TEST (GeometryTest, PointAbs)
 
 TEST (GeometryTest, PointAngleTo)
 
 TEST (GeometryTest, PointMin)
 
 TEST (GeometryTest, Vector3Min)
 
 TEST (GeometryTest, Vector4Min)
 
 TEST (GeometryTest, PointMax)
 
 TEST (GeometryTest, Vector3Max)
 
 TEST (GeometryTest, Vector4Max)
 
 TEST (GeometryTest, PointFloor)
 
 TEST (GeometryTest, Vector3Floor)
 
 TEST (GeometryTest, Vector4Floor)
 
 TEST (GeometryTest, PointCeil)
 
 TEST (GeometryTest, Vector3Ceil)
 
 TEST (GeometryTest, Vector4Ceil)
 
 TEST (GeometryTest, PointRound)
 
 TEST (GeometryTest, Vector3Round)
 
 TEST (GeometryTest, Vector4Round)
 
 TEST (GeometryTest, PointLerp)
 
 TEST (GeometryTest, Vector3Lerp)
 
 TEST (GeometryTest, Vector4Lerp)
 
 TEST (GeometryTest, CanUseVector3AssignmentOperators)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3Ops)
 
 TEST (GeometryTest, CanPerformAlgebraicVector3OpsWithArithmeticTypes)
 
 TEST (GeometryTest, ColorPremultiply)
 
 TEST (GeometryTest, ColorR8G8B8A8)
 
 TEST (GeometryTest, ColorLerp)
 
 TEST (GeometryTest, ColorClamp01)
 
 TEST (GeometryTest, ColorMakeRGBA8)
 
 TEST (GeometryTest, ColorApplyColorMatrix)
 
 TEST (GeometryTest, ColorLinearToSRGB)
 
 TEST (GeometryTest, ColorSRGBToLinear)
 
 TEST (GeometryTest, BlendModeToString)
 
 TEST (GeometryTest, CanConvertBetweenDegressAndRadians)
 
 TEST (GeometryTest, RectMakeSize)
 
 TEST (GeometryTest, RectUnion)
 
 TEST (GeometryTest, RectIntersection)
 
 TEST (GeometryTest, RectIntersectsWithRect)
 
 TEST (GeometryTest, RectCutout)
 
 TEST (GeometryTest, RectContainsPoint)
 
 TEST (GeometryTest, RectContainsRect)
 
 TEST (GeometryTest, RectGetPoints)
 
 TEST (GeometryTest, RectShift)
 
 TEST (GeometryTest, RectGetTransformedPoints)
 
 TEST (GeometryTest, RectMakePointBounds)
 
 TEST (GeometryTest, RectExpand)
 
 TEST (GeometryTest, RectGetPositive)
 
 TEST (GeometryTest, RectScale)
 
 TEST (GeometryTest, RectDirections)
 
 TEST (GeometryTest, RectProject)
 
 TEST (GeometryTest, CubicPathComponentPolylineDoesNotIncludePointOne)
 
 TEST (GeometryTest, PathCreatePolyLineDoesNotDuplicatePoints)
 
 TEST (GeometryTest, PathBuilderSetsCorrectContourPropertiesForAddCommands)
 
 TEST (GeometryTest, PathCreatePolylineGeneratesCorrectContourData)
 
 TEST (GeometryTest, PolylineGetContourPointBoundsReturnsCorrectRanges)
 
 TEST (GeometryTest, PathAddRectPolylineHasCorrectContourData)
 
 TEST (GeometryTest, PathPolylineDuplicatesAreRemovedForSameContour)
 
 TEST (GeometryTest, MatrixPrinting)
 
 TEST (GeometryTest, PointPrinting)
 
 TEST (GeometryTest, Vector3Printing)
 
 TEST (GeometryTest, Vector4Printing)
 
 TEST (GeometryTest, ColorPrinting)
 
 TEST (GeometryTest, ToIColor)
 
 TEST (GeometryTest, Gradient)
 
 TEST (GeometryTest, HalfConversions)
 
 TEST (GeometryTest, PathShifting)
 
 TEST (GeometryTest, PathBuilderWillComputeBounds)
 
 TEST_F (GoldenTests, ConicalGradient)
 
 TEST (BlitCommandVkTest, BlitCopyTextureToTextureCommandVK)
 
 TEST (BlitCommandVkTest, BlitCopyTextureToBufferCommandVK)
 
 TEST (BlitCommandVkTest, BlitCopyBufferToTextureCommandVK)
 
 TEST (BlitCommandVkTest, BlitGenerateMipmapCommandVK)
 
 TEST (CommandEncoderVKTest, DeleteEncoderAfterThreadDies)
 
 TEST (CommandEncoderVKTest, CleanupAfterSubmit)
 
 TEST (CommandPoolRecyclerVKTest, GetsACommandPoolPerThread)
 
 TEST (CommandPoolRecyclerVKTest, GetsTheSameCommandPoolOnSameThread)
 
 TEST (CommandPoolRecyclerVKTest, ReclaimMakesCommandPoolAvailable)
 
 TEST (ContextVKTest, DeletesCommandPools)
 
 TEST (ContextVKTest, DeletesCommandPoolsOnAllThreads)
 
 TEST (ContextVKTest, DeletePipelineAfterContext)
 
 TEST (ContextVKTest, DeleteShaderFunctionAfterContext)
 
 TEST (ContextVKTest, DeletePipelineLibraryAfterContext)
 
 TEST (ContextVKTest, CanCreateContextInAbsenceOfValidationLayers)
 
 TEST (ContextVKTest, CanCreateContextWithValidationLayers)
 
 TEST (FenceWaiterVKTest, IgnoresNullFence)
 
 TEST (FenceWaiterVKTest, IgnoresNullCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallback)
 
 TEST (FenceWaiterVKTest, ExecutesFenceCallbackX2)
 
 TEST (FenceWaiterVKTest, ExecutesNewFenceThenOldFence)
 
 TEST (FenceWaiterVKTest, AddFenceDoesNothingIfTerminating)
 
 TEST (FenceWaiterVKTest, InProgressFencesStillWaitIfTerminated)
 
 TEST (PassBindingsCacheTest, bindPipeline)
 
 TEST (PassBindingsCacheTest, setStencilReference)
 
 TEST (PassBindingsCacheTest, setScissor)
 
 TEST (PassBindingsCacheTest, setViewport)
 
 TEST (ResourceManagerVKTest, CreatesANewInstance)
 
 TEST (ResourceManagerVKTest, ReclaimMovesAResourceAndDestroysIt)
 
 TEST (ResourceManagerVKTest, TerminatesWhenOutOfScope)
 
 TEST (ResourceManagerVKTest, IsThreadSafe)
 
 CAPABILITY_TEST (SupportsOffscreenMSAA, false)
 
 CAPABILITY_TEST (SupportsSSBO, false)
 
 CAPABILITY_TEST (SupportsBufferToTextureBlits, false)
 
 CAPABILITY_TEST (SupportsTextureToTextureBlits, false)
 
 CAPABILITY_TEST (SupportsFramebufferFetch, false)
 
 CAPABILITY_TEST (SupportsCompute, false)
 
 CAPABILITY_TEST (SupportsComputeSubgroups, false)
 
 CAPABILITY_TEST (SupportsReadFromOnscreenTexture, false)
 
 CAPABILITY_TEST (SupportsReadFromResolve, false)
 
 CAPABILITY_TEST (SupportsDecalSamplerAddressMode, false)
 
 CAPABILITY_TEST (SupportsDeviceTransientTextures, false)
 
 TEST (CapabilitiesTest, DefaultColorFormat)
 
 TEST (CapabilitiesTest, DefaultStencilFormat)
 
 TEST (CapabilitiesTest, DefaultDepthStencilFormat)
 
 INSTANTIATE_COMPUTE_SUITE (ComputeSubgroupTest)
 
 TEST_P (ComputeSubgroupTest, CapabilitiesSuportSubgroups)
 
 TEST_P (ComputeSubgroupTest, PathPlayground)
 
 TEST_P (ComputeSubgroupTest, LargePath)
 
 TEST_P (ComputeSubgroupTest, QuadAndCubicInOnePath)
 
 TEST_P (ComputeTest, CapabilitiesReportSupport)
 
 TEST_P (ComputeTest, CanCreateComputePass)
 
 TEST_P (ComputeTest, CanComputePrefixSum)
 
 TEST_P (ComputeTest, 1DThreadgroupSizingIsCorrect)
 
 TEST_P (ComputeTest, CanComputePrefixSumLargeInteractive)
 
 TEST_P (ComputeTest, MultiStageInputAndOutput)
 
 TEST_P (ComputeTest, CanCompute1DimensionalData)
 
 TEST_P (ComputeTest, ReturnsEarlyWhenAnyGridDimensionIsZero)
 
 TEST (HostBufferTest, TestInitialization)
 
 TEST (HostBufferTest, CanEmplace)
 
 TEST (HostBufferTest, CanEmplaceWithAlignment)
 
 TEST (PipelineDescriptorTest, PrimitiveTypeHashEquality)
 
 TEST (PoolTest, Simple)
 
 TEST (PoolTest, Overload)
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererDartTest)
 
 TEST_P (RendererDartTest, CanRunDartInPlaygroundFrame)
 
 TEST_P (RendererDartTest, CanInstantiateFlutterGPUContext)
 
 TEST_P (RendererDartTest, CanEmplaceHostBuffer)
 
 INSTANTIATE_PLAYGROUND_SUITE (RendererTest)
 
 TEST_P (RendererTest, CanCreateBoxPrimitive)
 
 TEST_P (RendererTest, CanRenderPerspectiveCube)
 
 TEST_P (RendererTest, CanRenderMultiplePrimitives)
 
 TEST_P (RendererTest, CanRenderToTexture)
 
 TEST_P (RendererTest, CanRenderInstanced)
 
 TEST_P (RendererTest, CanBlitTextureToTexture)
 
 TEST_P (RendererTest, CanBlitTextureToBuffer)
 
 TEST_P (RendererTest, CanGenerateMipmaps)
 
 TEST_P (RendererTest, TheImpeller)
 
 TEST_P (RendererTest, ArrayUniforms)
 
 TEST_P (RendererTest, InactiveUniforms)
 
 TEST_P (RendererTest, CanCreateCPUBackedTexture)
 
 TEST_P (RendererTest, DefaultIndexSize)
 
 TEST_P (RendererTest, DefaultIndexBehavior)
 
 TEST_P (RendererTest, VertexBufferBuilder)
 
static const CompareFunctionUIDataCompareFunctionUI ()
 
 TEST_P (RendererTest, StencilMask)
 
 INSTANTIATE_PLAYGROUND_SUITE (RuntimeStageTest)
 
 TEST (RuntimeStageTest, CanReadValidBlob)
 
 TEST (RuntimeStageTest, CanRejectInvalidBlob)
 
 TEST (RuntimeStageTest, CanReadUniforms)
 
 TEST_P (RuntimeStageTest, CanRegisterStage)
 
 TEST_P (RuntimeStageTest, CanCreatePipelineFromRuntimeStage)
 
 TEST (TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus)
 
static std::shared_ptr< GlyphAtlasCreateGlyphAtlas (Context &context, const TypographerContext *typographer_context, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const TextFrame &frame)
 
 TEST_P (TypographerTest, CanConvertTextBlob)
 
 TEST_P (TypographerTest, CanCreateRenderContext)
 
 TEST_P (TypographerTest, CanCreateGlyphAtlas)
 
static sk_sp< SkData > OpenFixtureAsSkData (const char *fixture_name)
 
 TEST_P (TypographerTest, LazyAtlasTracksColor)
 
 TEST_P (TypographerTest, GlyphAtlasWithOddUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecycledIfUnchanged)
 
 TEST_P (TypographerTest, GlyphAtlasTextureIsRecreatedIfTypeChanges)
 
 TEST_P (TypographerTest, MaybeHasOverlapping)
 
 TEST_P (TypographerTest, RectanglePackerAddsNonoverlapingRectangles)
 

Variables

static int64_t LastSample = 0
 
std::vector< Pointgolden_cubic_and_quad_points
 

Typedef Documentation

◆ AiksCanvasTest

using impeller::testing::AiksCanvasTest = typedef ::testing::Test

Definition at line 16 of file canvas_unittests.cc.

◆ AiksTest

Definition at line 52 of file aiks_unittests.cc.

◆ ArchiveTest

Definition at line 106 of file archivist_unittests.cc.

◆ ComputeSubgroupTest

◆ ComputeTest

Definition at line 26 of file compute_unittests.cc.

◆ DeviceBufferTest

Definition at line 12 of file device_buffer_unittests.cc.

◆ DisplayListTest

Definition at line 45 of file dl_unittests.cc.

◆ EntityTest

Definition at line 67 of file entity_unittests.cc.

◆ RendererTest

Definition at line 49 of file renderer_unittests.cc.

◆ RuntimeStageTest

◆ TypographerTest

Function Documentation

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [1/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Conical  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [2/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Linear  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [3/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Radial  )

◆ APPLY_COLOR_FILTER_GRADIENT_TEST() [4/4]

impeller::testing::APPLY_COLOR_FILTER_GRADIENT_TEST ( Sweep  )

◆ BlendModeTest()

static Picture impeller::testing::BlendModeTest ( BlendMode  blend_mode,
const std::shared_ptr< Image > &  src_image,
const std::shared_ptr< Image > &  dst_image 
)
static
  1. Save layer blending (top squares).
  2. CPU blend modes (bottom squares).
  3. Image blending (top right).

Compare these results with the images in the Flutter blend mode documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html

Definition at line 2523 of file aiks_unittests.cc.

2525  {
2526  Color destination_color = Color::CornflowerBlue().WithAlpha(0.75);
2527  auto source_colors = std::vector<Color>({Color::White().WithAlpha(0.75),
2528  Color::LimeGreen().WithAlpha(0.75),
2529  Color::Black().WithAlpha(0.75)});
2530 
2531  Canvas canvas;
2532 
2533  canvas.DrawPaint({.color = Color::Black()});
2534 
2535  //----------------------------------------------------------------------------
2536  /// 1. Save layer blending (top squares).
2537  ///
2538 
2539  canvas.Save();
2540  for (const auto& color : source_colors) {
2541  canvas.Save();
2542  {
2543  canvas.ClipRect(Rect::MakeXYWH(50, 50, 100, 100));
2544  // Perform the blend in a SaveLayer so that the initial backdrop color is
2545  // fully transparent black. SourceOver blend the result onto the parent
2546  // pass.
2547  canvas.SaveLayer({});
2548  {
2549  canvas.DrawPaint({.color = destination_color});
2550  // Draw the source color in an offscreen pass and blend it to the parent
2551  // pass.
2552  canvas.SaveLayer({.blend_mode = blend_mode});
2553  { //
2554  canvas.DrawRect({50, 50, 100, 100}, {.color = color});
2555  }
2556  canvas.Restore();
2557  }
2558  canvas.Restore();
2559  }
2560  canvas.Restore();
2561  canvas.Translate(Vector2(100, 0));
2562  }
2563  canvas.RestoreToCount(0);
2564 
2565  //----------------------------------------------------------------------------
2566  /// 2. CPU blend modes (bottom squares).
2567  ///
2568 
2569  canvas.Save();
2570  canvas.Translate({0, 100});
2571 
2572  // Perform the blend in a SaveLayer so that the initial backdrop color is
2573  // fully transparent black. SourceOver blend the result onto the parent pass.
2574  canvas.SaveLayer({});
2575  // canvas.DrawPaint({.color = destination_color});
2576  for (const auto& color : source_colors) {
2577  // Simply write the CPU blended color to the pass.
2578  canvas.DrawRect({50, 50, 100, 100},
2579  {.color = destination_color.Blend(color, blend_mode),
2580  .blend_mode = BlendMode::kSourceOver});
2581  canvas.Translate(Vector2(100, 0));
2582  }
2583  canvas.RestoreToCount(0);
2584 
2585  //----------------------------------------------------------------------------
2586  /// 3. Image blending (top right).
2587  ///
2588  /// Compare these results with the images in the Flutter blend mode
2589  /// documentation: https://api.flutter.dev/flutter/dart-ui/BlendMode.html
2590  ///
2591 
2592  canvas.Save();
2593  // canvas.ClipRect(Rect::MakeXYWH(500, 0, 500, 500));
2594  canvas.SaveLayer({.blend_mode = BlendMode::kSourceOver});
2595  {
2596  canvas.DrawImage(dst_image, {400, 50}, {.blend_mode = BlendMode::kSource});
2597  canvas.DrawImage(src_image, {400, 50}, {.blend_mode = blend_mode});
2598  }
2599  canvas.RestoreToCount(0);
2600 
2601  return canvas.EndRecordingAsPicture();
2602 }

References impeller::Color::Blend(), impeller::Canvas::DrawPaint(), and impeller::Color::WithAlpha().

◆ CanRenderConicalGradientWithDithering()

static void impeller::testing::CanRenderConicalGradientWithDithering ( AiksTest aiks_test,
bool  use_dithering 
)
static

Definition at line 509 of file aiks_unittests.cc.

510  {
511  Canvas canvas;
512  canvas.Scale(aiks_test->GetContentScale());
513  Paint paint;
514  canvas.Translate({100.0, 100.0, 0});
515 
516  // #FFF -> #000
517  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
518  Color{0.0, 0.0, 0.0, 1.0}};
519  std::vector<Scalar> stops = {0.0, 1.0};
520 
521  paint.color_source = ColorSource::MakeConicalGradient(
522  {100, 100}, 100, std::move(colors), std::move(stops), {0, 1}, 0,
523  Entity::TileMode::kMirror, {});
524  paint.dither = use_dithering;
525 
526  canvas.DrawRect({0, 0, 600, 600}, paint);
527  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
528 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Playground::GetContentScale(), impeller::Entity::kMirror, impeller::ColorSource::MakeConicalGradient(), impeller::AiksPlayground::OpenPlaygroundHere(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

Referenced by TEST_P().

◆ CanRenderLinearGradientWithDithering()

static void impeller::testing::CanRenderLinearGradientWithDithering ( AiksTest aiks_test,
bool  use_dithering 
)
static

Definition at line 425 of file aiks_unittests.cc.

426  {
427  Canvas canvas;
428  Paint paint;
429  canvas.Translate({100.0, 100.0, 0});
430 
431  // 0xffcccccc --> 0xff333333, taken from
432  // https://github.com/flutter/flutter/issues/118073#issue-1521699748
433  std::vector<Color> colors = {Color{0.8, 0.8, 0.8, 1.0},
434  Color{0.2, 0.2, 0.2, 1.0}};
435  std::vector<Scalar> stops = {0.0, 1.0};
436 
437  paint.color_source = ColorSource::MakeLinearGradient(
438  {0, 0}, {800, 500}, std::move(colors), std::move(stops),
439  Entity::TileMode::kClamp, {});
440  paint.dither = use_dithering;
441  canvas.DrawRect({0, 0, 800, 500}, paint);
442  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
443 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeLinearGradient(), impeller::AiksPlayground::OpenPlaygroundHere(), and impeller::Canvas::Translate().

Referenced by TEST_P().

◆ CanRenderRadialGradientWithDithering()

static void impeller::testing::CanRenderRadialGradientWithDithering ( AiksTest aiks_test,
bool  use_dithering 
)
static

Definition at line 453 of file aiks_unittests.cc.

454  {
455  Canvas canvas;
456  Paint paint;
457  canvas.Translate({100.0, 100.0, 0});
458 
459  // #FFF -> #000
460  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
461  Color{0.0, 0.0, 0.0, 1.0}};
462  std::vector<Scalar> stops = {0.0, 1.0};
463 
464  paint.color_source = ColorSource::MakeRadialGradient(
465  {600, 600}, 600, std::move(colors), std::move(stops),
466  Entity::TileMode::kClamp, {});
467  paint.dither = use_dithering;
468  canvas.DrawRect({0, 0, 1200, 1200}, paint);
469  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
470 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeRadialGradient(), impeller::AiksPlayground::OpenPlaygroundHere(), and impeller::Canvas::Translate().

Referenced by TEST_P().

◆ CanRenderSweepGradientWithDithering()

static void impeller::testing::CanRenderSweepGradientWithDithering ( AiksTest aiks_test,
bool  use_dithering 
)
static

Definition at line 480 of file aiks_unittests.cc.

481  {
482  Canvas canvas;
483  canvas.Scale(aiks_test->GetContentScale());
484  Paint paint;
485  canvas.Translate({100.0, 100.0, 0});
486 
487  // #FFF -> #000
488  std::vector<Color> colors = {Color{1.0, 1.0, 1.0, 1.0},
489  Color{0.0, 0.0, 0.0, 1.0}};
490  std::vector<Scalar> stops = {0.0, 1.0};
491 
492  paint.color_source = ColorSource::MakeSweepGradient(
493  {100, 100}, Degrees(45), Degrees(135), std::move(colors),
494  std::move(stops), Entity::TileMode::kMirror, {});
495  paint.dither = use_dithering;
496 
497  canvas.DrawRect({0, 0, 600, 600}, paint);
498  ASSERT_TRUE(aiks_test->OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
499 }

References impeller::Paint::color_source, impeller::Paint::dither, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Playground::GetContentScale(), impeller::Entity::kMirror, impeller::ColorSource::MakeSweepGradient(), impeller::AiksPlayground::OpenPlaygroundHere(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

Referenced by TEST_P().

◆ CAPABILITY_TEST() [1/11]

impeller::testing::CAPABILITY_TEST ( SupportsBufferToTextureBlits  ,
false   
)

◆ CAPABILITY_TEST() [2/11]

impeller::testing::CAPABILITY_TEST ( SupportsCompute  ,
false   
)

◆ CAPABILITY_TEST() [3/11]

impeller::testing::CAPABILITY_TEST ( SupportsComputeSubgroups  ,
false   
)

◆ CAPABILITY_TEST() [4/11]

impeller::testing::CAPABILITY_TEST ( SupportsDecalSamplerAddressMode  ,
false   
)

◆ CAPABILITY_TEST() [5/11]

impeller::testing::CAPABILITY_TEST ( SupportsDeviceTransientTextures  ,
false   
)

◆ CAPABILITY_TEST() [6/11]

impeller::testing::CAPABILITY_TEST ( SupportsFramebufferFetch  ,
false   
)

◆ CAPABILITY_TEST() [7/11]

impeller::testing::CAPABILITY_TEST ( SupportsOffscreenMSAA  ,
false   
)

◆ CAPABILITY_TEST() [8/11]

impeller::testing::CAPABILITY_TEST ( SupportsReadFromOnscreenTexture  ,
false   
)

◆ CAPABILITY_TEST() [9/11]

impeller::testing::CAPABILITY_TEST ( SupportsReadFromResolve  ,
false   
)

◆ CAPABILITY_TEST() [10/11]

impeller::testing::CAPABILITY_TEST ( SupportsSSBO  ,
false   
)

◆ CAPABILITY_TEST() [11/11]

impeller::testing::CAPABILITY_TEST ( SupportsTextureToTextureBlits  ,
false   
)

◆ CompareFunctionUI()

static const CompareFunctionUIData& impeller::testing::CompareFunctionUI ( )
static

Definition at line 1104 of file renderer_unittests.cc.

1104  {
1105  static CompareFunctionUIData data;
1106  return data;
1107 }

Referenced by TEST_P().

◆ CreateGlyphAtlas()

static std::shared_ptr<GlyphAtlas> impeller::testing::CreateGlyphAtlas ( Context context,
const TypographerContext typographer_context,
GlyphAtlas::Type  type,
Scalar  scale,
const std::shared_ptr< GlyphAtlasContext > &  atlas_context,
const TextFrame frame 
)
static

Definition at line 25 of file typographer_unittests.cc.

31  {
32  FontGlyphMap font_glyph_map;
33  frame.CollectUniqueFontGlyphPairs(font_glyph_map, scale);
34  return typographer_context->CreateGlyphAtlas(context, type, atlas_context,
35  font_glyph_map);
36 }

References impeller::TextFrame::CollectUniqueFontGlyphPairs(), and impeller::TypographerContext::CreateGlyphAtlas().

Referenced by TEST_P().

◆ CreateMappingFromString()

static std::shared_ptr<fml::Mapping> impeller::testing::CreateMappingFromString ( std::string  p_string)
static

Definition at line 15 of file blobcat_unittests.cc.

16  {
17  auto string = std::make_shared<std::string>(std::move(p_string));
18  return std::make_shared<fml::NonOwnedMapping>(
19  reinterpret_cast<const uint8_t*>(string->data()), string->size(),
20  [string](auto, auto) {});
21 }

Referenced by TEST().

◆ CreatePassWithRectPath()

auto impeller::testing::CreatePassWithRectPath ( Rect  rect,
std::optional< Rect bounds_hint,
bool  collapse = false 
)

Definition at line 109 of file entity_unittests.cc.

111  {
112  auto subpass = std::make_unique<EntityPass>();
113  Entity entity;
114  entity.SetContents(SolidColorContents::Make(
115  PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
116  subpass->AddEntity(entity);
117  subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
118  subpass->SetBoundsLimit(bounds_hint);
119  return subpass;
120 }

References impeller::PathBuilder::AddRect(), impeller::SolidColorContents::Make(), impeller::Color::Red(), and impeller::Entity::SetContents().

Referenced by TEST_P().

◆ CreateStringFromMapping()

const std::string impeller::testing::CreateStringFromMapping ( const fml::Mapping &  mapping)

Definition at line 23 of file blobcat_unittests.cc.

23  {
24  return std::string{reinterpret_cast<const char*>(mapping.GetMapping()),
25  mapping.GetSize()};
26 }

Referenced by TEST().

◆ CreateTestYUVTextures()

static std::vector<std::shared_ptr<Texture> > impeller::testing::CreateTestYUVTextures ( Context context,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 2029 of file entity_unittests.cc.

2031  {
2032  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
2033  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
2034  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
2035  Vector3 white = {1.0, 1.0, 1.0};
2036  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
2037  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
2038  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
2039  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
2040  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
2041  std::vector<uint8_t> y_data;
2042  std::vector<uint8_t> uv_data;
2043  for (int i = 0; i < 4; i++) {
2044  auto yuv = yuvs[i];
2045  uint8_t y = std::round(yuv.x * 255.0);
2046  uint8_t u = std::round(yuv.y * 255.0);
2047  uint8_t v = std::round(yuv.z * 255.0);
2048  for (int j = 0; j < 16; j++) {
2049  y_data.push_back(y);
2050  }
2051  for (int j = 0; j < 8; j++) {
2052  uv_data.push_back(j % 2 == 0 ? u : v);
2053  }
2054  }
2055  impeller::TextureDescriptor y_texture_descriptor;
2056  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2057  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
2058  y_texture_descriptor.size = {8, 8};
2059  auto y_texture =
2060  context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
2061  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
2062  if (!y_texture->SetContents(y_mapping)) {
2063  FML_DLOG(ERROR) << "Could not copy contents into Y texture.";
2064  }
2065 
2066  impeller::TextureDescriptor uv_texture_descriptor;
2067  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
2068  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
2069  uv_texture_descriptor.size = {4, 4};
2070  auto uv_texture =
2071  context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
2072  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
2073  if (!uv_texture->SetContents(uv_mapping)) {
2074  FML_DLOG(ERROR) << "Could not copy contents into UV texture.";
2075  }
2076 
2077  return {y_texture, uv_texture};
2078 }

References impeller::TextureDescriptor::format, impeller::Context::GetResourceAllocator(), impeller::kHostVisible, impeller::kR8G8UNormInt, impeller::kR8UNormInt, RGBToYUV(), impeller::TextureDescriptor::size, and impeller::TextureDescriptor::storage_mode.

Referenced by TEST_P().

◆ GetBlendModeSelection()

static BlendModeSelection impeller::testing::GetBlendModeSelection ( )
static

Definition at line 1610 of file aiks_unittests.cc.

1610  {
1611  std::vector<const char*> blend_mode_names;
1612  std::vector<BlendMode> blend_mode_values;
1613  {
1614  const std::vector<std::tuple<const char*, BlendMode>> blends = {
1616  assert(blends.size() ==
1617  static_cast<size_t>(Entity::kLastAdvancedBlendMode) + 1);
1618  for (const auto& [name, mode] : blends) {
1619  blend_mode_names.push_back(name);
1620  blend_mode_values.push_back(mode);
1621  }
1622  }
1623 
1624  return {blend_mode_names, blend_mode_values};
1625 }

References BLEND_MODE_TUPLE, and IMPELLER_FOR_EACH_BLEND_MODE.

Referenced by TEST_P().

◆ INSTANTIATE_COMPUTE_SUITE()

impeller::testing::INSTANTIATE_COMPUTE_SUITE ( ComputeSubgroupTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [1/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( AiksTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [2/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( DisplayListTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [3/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( EntityTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [4/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererDartTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [5/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RendererTest  )

◆ INSTANTIATE_PLAYGROUND_SUITE() [6/6]

impeller::testing::INSTANTIATE_PLAYGROUND_SUITE ( RuntimeStageTest  )

◆ OpenFixtureAsSkData() [1/2]

static sk_sp<SkData> impeller::testing::OpenFixtureAsSkData ( const char *  fixture_name)
static

Definition at line 89 of file typographer_unittests.cc.

89  {
90  auto mapping = flutter::testing::OpenFixtureAsMapping(fixture_name);
91  if (!mapping) {
92  return nullptr;
93  }
94  auto data = SkData::MakeWithProc(
95  mapping->GetMapping(), mapping->GetSize(),
96  [](const void* ptr, void* context) {
97  delete reinterpret_cast<fml::Mapping*>(context);
98  },
99  mapping.get());
100  mapping.release();
101  return data;
102 }

◆ OpenFixtureAsSkData() [2/2]

static sk_sp<SkData> impeller::testing::OpenFixtureAsSkData ( const char *  fixture_name)
static

Definition at line 1282 of file aiks_unittests.cc.

1282  {
1283  auto mapping = flutter::testing::OpenFixtureAsMapping(fixture_name);
1284  if (!mapping) {
1285  return nullptr;
1286  }
1287  auto data = SkData::MakeWithProc(
1288  mapping->GetMapping(), mapping->GetSize(),
1289  [](const void* ptr, void* context) {
1290  delete reinterpret_cast<fml::Mapping*>(context);
1291  },
1292  mapping.get());
1293  mapping.release();
1294  return data;
1295 }

Referenced by TEST_P().

◆ RenderTextInCanvasSkia()

bool impeller::testing::RenderTextInCanvasSkia ( const std::shared_ptr< Context > &  context,
Canvas canvas,
const std::string &  text,
const std::string &  font_fixture,
TextRenderOptions  options = {} 
)

Definition at line 1303 of file aiks_unittests.cc.

1307  {}) {
1308  // Draw the baseline.
1309  canvas.DrawRect({options.position.x - 50, options.position.y, 900, 10},
1310  Paint{.color = Color::Aqua().WithAlpha(0.25)});
1311 
1312  // Mark the point at which the text is drawn.
1313  canvas.DrawCircle(options.position, 5.0,
1314  Paint{.color = Color::Red().WithAlpha(0.25)});
1315 
1316  // Construct the text blob.
1317  auto mapping = OpenFixtureAsSkData(font_fixture.c_str());
1318  if (!mapping) {
1319  return false;
1320  }
1321  SkFont sk_font(SkTypeface::MakeFromData(mapping), options.font_size);
1322  auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font);
1323  if (!blob) {
1324  return false;
1325  }
1326 
1327  // Create the Impeller text frame and draw it at the designated baseline.
1328  auto frame = MakeTextFrameFromTextBlobSkia(blob);
1329 
1330  Paint text_paint;
1331  text_paint.color = Color::Yellow().WithAlpha(options.alpha);
1332  canvas.DrawTextFrame(frame, options.position, text_paint);
1333  return true;
1334 }

Referenced by TEST_P().

◆ RenderTextInCanvasSTB()

bool impeller::testing::RenderTextInCanvasSTB ( const std::shared_ptr< Context > &  context,
Canvas canvas,
const std::string &  text,
const std::string &  font_fixture,
TextRenderOptions  options = {} 
)

Definition at line 1336 of file aiks_unittests.cc.

1340  {}) {
1341  // Draw the baseline.
1342  canvas.DrawRect({options.position.x - 50, options.position.y, 900, 10},
1343  Paint{.color = Color::Aqua().WithAlpha(0.25)});
1344 
1345  // Mark the point at which the text is drawn.
1346  canvas.DrawCircle(options.position, 5.0,
1347  Paint{.color = Color::Red().WithAlpha(0.25)});
1348 
1349  // Construct the text blob.
1350  auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str());
1351  if (!mapping) {
1352  return false;
1353  }
1354  auto typeface_stb = std::make_shared<TypefaceSTB>(std::move(mapping));
1355 
1356  auto frame = MakeTextFrameSTB(
1357  typeface_stb, Font::Metrics{.point_size = options.font_size}, text);
1358 
1359  Paint text_paint;
1360  text_paint.color = Color::Yellow().WithAlpha(options.alpha);
1361  canvas.DrawTextFrame(frame, options.position, text_paint);
1362  return true;
1363 }

Referenced by TEST_P().

◆ RGBToYUV()

static Vector3 impeller::testing::RGBToYUV ( Vector3  rgb,
YUVColorSpace  yuv_color_space 
)
static

Definition at line 2012 of file entity_unittests.cc.

2012  {
2013  Vector3 yuv;
2014  switch (yuv_color_space) {
2015  case YUVColorSpace::kBT601FullRange:
2016  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
2017  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
2018  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
2019  break;
2020  case YUVColorSpace::kBT601LimitedRange:
2021  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
2022  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
2023  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
2024  break;
2025  }
2026  return yuv;
2027 }

References impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

Referenced by CreateTestYUVTextures().

◆ TEST() [1/202]

impeller::testing::TEST ( AiksCanvasTest  ,
DisableLocalBoundsRectForFilteredSaveLayers   
)

Definition at line 340 of file canvas_unittests.cc.

340  {
341  Rect initial_cull = Rect::MakeXYWH(0, 0, 10, 10);
342 
343  Canvas canvas(initial_cull);
344  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
345 
346  canvas.Save();
347  canvas.SaveLayer(
348  Paint{.image_filter = ImageFilter::MakeBlur(
349  Sigma(10), Sigma(10), FilterContents::BlurStyle::kNormal,
350  Entity::TileMode::kDecal)});
351  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
352 
353  canvas.Restore();
354  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
355 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Paint::image_filter, impeller::Entity::kDecal, impeller::FilterContents::kNormal, impeller::ImageFilter::MakeBlur(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::SaveLayer().

◆ TEST() [2/202]

impeller::testing::TEST ( AiksCanvasTest  ,
EmptyCullRect   
)

Definition at line 18 of file canvas_unittests.cc.

18  {
19  Canvas canvas;
20 
21  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
22 }

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [3/202]

impeller::testing::TEST ( AiksCanvasTest  ,
InitialCullRect   
)

Definition at line 24 of file canvas_unittests.cc.

24  {
25  Rect initial_cull(0, 0, 10, 10);
26 
27  Canvas canvas(initial_cull);
28 
29  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
30  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), initial_cull);
31 }

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [4/202]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstEmptyCullRect   
)

Definition at line 277 of file canvas_unittests.cc.

277  {
278  PathBuilder builder;
279  builder.AddRect({5, 5, 1, 1});
280  builder.AddRect({5, 14, 1, 1});
281  builder.AddRect({14, 5, 1, 1});
282  builder.AddRect({14, 14, 1, 1});
283  Path path = builder.TakePath();
284 
285  Canvas canvas;
286  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
287 
288  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
289 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::PathBuilder::TakePath().

◆ TEST() [5/202]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstFullyCoveredCullRect   
)

Definition at line 325 of file canvas_unittests.cc.

325  {
326  Rect initial_cull(5, 5, 10, 10);
327  PathBuilder builder;
328  builder.AddRect({0, 0, 100, 100});
329  Path path = builder.TakePath();
330  // Diff clip of Paths is ignored due to complexity
331  Rect result_cull(5, 5, 10, 10);
332 
333  Canvas canvas(initial_cull);
334  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
335 
336  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
337  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
338 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::PathBuilder::TakePath().

◆ TEST() [6/202]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipDiffAgainstNonCoveredCullRect   
)

Definition at line 308 of file canvas_unittests.cc.

308  {
309  Rect initial_cull(0, 0, 10, 10);
310  PathBuilder builder;
311  builder.AddRect({5, 5, 1, 1});
312  builder.AddRect({5, 14, 1, 1});
313  builder.AddRect({14, 5, 1, 1});
314  builder.AddRect({14, 14, 1, 1});
315  Path path = builder.TakePath();
316  Rect result_cull(0, 0, 10, 10);
317 
318  Canvas canvas(initial_cull);
319  canvas.ClipPath(path, Entity::ClipOperation::kDifference);
320 
321  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
322  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
323 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kDifference, and impeller::PathBuilder::TakePath().

◆ TEST() [7/202]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstCullRect   
)

Definition at line 291 of file canvas_unittests.cc.

291  {
292  Rect initial_cull(0, 0, 10, 10);
293  PathBuilder builder;
294  builder.AddRect({5, 5, 1, 1});
295  builder.AddRect({5, 14, 1, 1});
296  builder.AddRect({14, 5, 1, 1});
297  builder.AddRect({14, 14, 1, 1});
298  Path path = builder.TakePath();
299  Rect result_cull(5, 5, 5, 5);
300 
301  Canvas canvas(initial_cull);
302  canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
303 
304  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
305  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
306 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::PathBuilder::TakePath().

◆ TEST() [8/202]

impeller::testing::TEST ( AiksCanvasTest  ,
PathClipIntersectAgainstEmptyCullRect   
)

Definition at line 261 of file canvas_unittests.cc.

261  {
262  PathBuilder builder;
263  builder.AddRect({5, 5, 1, 1});
264  builder.AddRect({5, 14, 1, 1});
265  builder.AddRect({14, 5, 1, 1});
266  builder.AddRect({14, 14, 1, 1});
267  Path path = builder.TakePath();
268  Rect rect_clip(5, 5, 10, 10);
269 
270  Canvas canvas;
271  canvas.ClipPath(path, Entity::ClipOperation::kIntersect);
272 
273  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
274  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
275 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::GetCurrentLocalCullingBounds(), impeller::Entity::kIntersect, and impeller::PathBuilder::TakePath().

◆ TEST() [9/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAboveCullRect   
)

Definition at line 98 of file canvas_unittests.cc.

98  {
99  Rect initial_cull(5, 5, 10, 10);
100  Rect rect_clip(0, 0, 20, 4);
101  Rect result_cull(5, 5, 10, 10);
102 
103  Canvas canvas(initial_cull);
104  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
105 
106  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
107  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
108 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [10/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstEmptyCullRect   
)

Definition at line 65 of file canvas_unittests.cc.

65  {
66  Rect rect_clip(5, 5, 10, 10);
67 
68  Canvas canvas;
69  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
70 
71  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
72 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [11/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstHCoveredCullRect   
)

Definition at line 158 of file canvas_unittests.cc.

158  {
159  Rect initial_cull(0, 0, 10, 10);
160  Rect rect_clip(0, 5, 10, 10);
161  Rect result_cull(0, 0, 10, 5);
162 
163  Canvas canvas(initial_cull);
164  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
165 
166  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
167  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
168 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [12/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 86 of file canvas_unittests.cc.

86  {
87  Rect initial_cull(0, 0, 10, 10);
88  Rect rect_clip(5, 5, 10, 10);
89  Rect result_cull(0, 0, 10, 10);
90 
91  Canvas canvas(initial_cull);
92  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
93 
94  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
95  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
96 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [13/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffAgainstVCoveredCullRect   
)

Definition at line 146 of file canvas_unittests.cc.

146  {
147  Rect initial_cull(0, 0, 10, 10);
148  Rect rect_clip(5, 0, 10, 10);
149  Rect result_cull(0, 0, 5, 10);
150 
151  Canvas canvas(initial_cull);
152  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
153 
154  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
155  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
156 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [14/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffBelowCullRect   
)

Definition at line 110 of file canvas_unittests.cc.

110  {
111  Rect initial_cull(5, 5, 10, 10);
112  Rect rect_clip(0, 16, 20, 4);
113  Rect result_cull(5, 5, 10, 10);
114 
115  Canvas canvas(initial_cull);
116  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
117 
118  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
119  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
120 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [15/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffLeftOfCullRect   
)

Definition at line 122 of file canvas_unittests.cc.

122  {
123  Rect initial_cull(5, 5, 10, 10);
124  Rect rect_clip(0, 0, 4, 20);
125  Rect result_cull(5, 5, 10, 10);
126 
127  Canvas canvas(initial_cull);
128  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
129 
130  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
131  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
132 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [16/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipDiffRightOfCullRect   
)

Definition at line 134 of file canvas_unittests.cc.

134  {
135  Rect initial_cull(5, 5, 10, 10);
136  Rect rect_clip(16, 0, 4, 20);
137  Rect result_cull(5, 5, 10, 10);
138 
139  Canvas canvas(initial_cull);
140  canvas.ClipRect(rect_clip, Entity::ClipOperation::kDifference);
141 
142  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
143  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
144 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [17/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstCullRect   
)

Definition at line 74 of file canvas_unittests.cc.

74  {
75  Rect initial_cull(0, 0, 10, 10);
76  Rect rect_clip(5, 5, 10, 10);
77  Rect result_cull(5, 5, 5, 5);
78 
79  Canvas canvas(initial_cull);
80  canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
81 
82  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
83  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
84 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kIntersect.

◆ TEST() [18/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RectClipIntersectAgainstEmptyCullRect   
)

Definition at line 55 of file canvas_unittests.cc.

55  {
56  Rect rect_clip(5, 5, 10, 10);
57 
58  Canvas canvas;
59  canvas.ClipRect(rect_clip, Entity::ClipOperation::kIntersect);
60 
61  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
62  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
63 }

References impeller::Canvas::ClipRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kIntersect.

◆ TEST() [19/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstEmptyCullRect   
)

Definition at line 180 of file canvas_unittests.cc.

180  {
181  Rect rect_clip(5, 5, 10, 10);
182 
183  Canvas canvas;
184  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
185 
186  ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value());
187 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [20/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHFullyCoveredCullRect   
)

Definition at line 249 of file canvas_unittests.cc.

249  {
250  Rect initial_cull(0, 0, 10, 10);
251  Rect rect_clip(-2, 5, 14, 10);
252  Rect result_cull(0, 0, 10, 5);
253 
254  Canvas canvas(initial_cull);
255  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
256 
257  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
258  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
259 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [21/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstHPartiallyCoveredCullRect   
)

Definition at line 237 of file canvas_unittests.cc.

237  {
238  Rect initial_cull(0, 0, 10, 10);
239  Rect rect_clip(0, 5, 10, 10);
240  Rect result_cull(0, 0, 10, 6);
241 
242  Canvas canvas(initial_cull);
243  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
244 
245  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
246  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
247 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [22/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstNonCoveredCullRect   
)

Definition at line 201 of file canvas_unittests.cc.

201  {
202  Rect initial_cull(0, 0, 10, 10);
203  Rect rect_clip(5, 5, 10, 10);
204  Rect result_cull(0, 0, 10, 10);
205 
206  Canvas canvas(initial_cull);
207  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
208 
209  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
210  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
211 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [23/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVFullyCoveredCullRect   
)

Definition at line 225 of file canvas_unittests.cc.

225  {
226  Rect initial_cull(0, 0, 10, 10);
227  Rect rect_clip(5, -2, 10, 14);
228  Rect result_cull(0, 0, 5, 10);
229 
230  Canvas canvas(initial_cull);
231  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
232 
233  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
234  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
235 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [24/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipDiffAgainstVPartiallyCoveredCullRect   
)

Definition at line 213 of file canvas_unittests.cc.

213  {
214  Rect initial_cull(0, 0, 10, 10);
215  Rect rect_clip(5, 0, 10, 10);
216  Rect result_cull(0, 0, 6, 10);
217 
218  Canvas canvas(initial_cull);
219  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference);
220 
221  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
222  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
223 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kDifference.

◆ TEST() [25/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstCullRect   
)

Definition at line 189 of file canvas_unittests.cc.

189  {
190  Rect initial_cull(0, 0, 10, 10);
191  Rect rect_clip(5, 5, 10, 10);
192  Rect result_cull(5, 5, 5, 5);
193 
194  Canvas canvas(initial_cull);
195  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect);
196 
197  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
198  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull);
199 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kIntersect.

◆ TEST() [26/202]

impeller::testing::TEST ( AiksCanvasTest  ,
RRectClipIntersectAgainstEmptyCullRect   
)

Definition at line 170 of file canvas_unittests.cc.

170  {
171  Rect rect_clip(5, 5, 10, 10);
172 
173  Canvas canvas;
174  canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect);
175 
176  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
177  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip);
178 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Entity::kIntersect.

◆ TEST() [27/202]

impeller::testing::TEST ( AiksCanvasTest  ,
ScaledCullRect   
)

Definition at line 44 of file canvas_unittests.cc.

44  {
45  Rect initial_cull(5, 5, 10, 10);
46  Rect scaled_cull(10, 10, 20, 20);
47 
48  Canvas canvas(initial_cull);
49  canvas.Scale(Vector2(0.5, 0.5));
50 
51  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
52  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), scaled_cull);
53 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Canvas::Scale().

◆ TEST() [28/202]

impeller::testing::TEST ( AiksCanvasTest  ,
TranslatedCullRect   
)

Definition at line 33 of file canvas_unittests.cc.

33  {
34  Rect initial_cull(5, 5, 10, 10);
35  Rect translated_cull(0, 0, 10, 10);
36 
37  Canvas canvas(initial_cull);
38  canvas.Translate(Vector3(5, 5, 0));
39 
40  ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value());
41  ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), translated_cull);
42 }

References impeller::Canvas::GetCurrentLocalCullingBounds(), and impeller::Canvas::Translate().

◆ TEST() [29/202]

impeller::testing::TEST ( AllocatorTest  ,
TextureDescriptorCompatibility   
)

Definition at line 16 of file allocator_unittests.cc.

16  {
17  // Size.
18  {
19  TextureDescriptor desc_a = {.size = ISize(100, 100)};
20  TextureDescriptor desc_b = {.size = ISize(100, 100)};
21  TextureDescriptor desc_c = {.size = ISize(101, 100)};
22 
23  ASSERT_EQ(desc_a, desc_b);
24  ASSERT_NE(desc_a, desc_c);
25  }
26  // Storage Mode.
27  {
28  TextureDescriptor desc_a = {.storage_mode = StorageMode::kDevicePrivate};
29  TextureDescriptor desc_b = {.storage_mode = StorageMode::kDevicePrivate};
30  TextureDescriptor desc_c = {.storage_mode = StorageMode::kHostVisible};
31 
32  ASSERT_EQ(desc_a, desc_b);
33  ASSERT_NE(desc_a, desc_c);
34  }
35  // Format.
36  {
37  TextureDescriptor desc_a = {.format = PixelFormat::kR8G8B8A8UNormInt};
38  TextureDescriptor desc_b = {.format = PixelFormat::kR8G8B8A8UNormInt};
39  TextureDescriptor desc_c = {.format = PixelFormat::kB10G10R10A10XR};
40 
41  ASSERT_EQ(desc_a, desc_b);
42  ASSERT_NE(desc_a, desc_c);
43  }
44  // Sample Count.
45  {
46  TextureDescriptor desc_a = {.sample_count = SampleCount::kCount4};
47  TextureDescriptor desc_b = {.sample_count = SampleCount::kCount4};
48  TextureDescriptor desc_c = {.sample_count = SampleCount::kCount1};
49 
50  ASSERT_EQ(desc_a, desc_b);
51  ASSERT_NE(desc_a, desc_c);
52  }
53  // Sample Count.
54  {
55  TextureDescriptor desc_a = {.type = TextureType::kTexture2DMultisample};
56  TextureDescriptor desc_b = {.type = TextureType::kTexture2DMultisample};
57  TextureDescriptor desc_c = {.type = TextureType::kTexture2D};
58 
59  ASSERT_EQ(desc_a, desc_b);
60  ASSERT_NE(desc_a, desc_c);
61  }
62  // Compression.
63  {
64  TextureDescriptor desc_a = {.compression_type = CompressionType::kLossless};
65  TextureDescriptor desc_b = {.compression_type = CompressionType::kLossless};
66  TextureDescriptor desc_c = {.compression_type = CompressionType::kLossy};
67 
68  ASSERT_EQ(desc_a, desc_b);
69  ASSERT_NE(desc_a, desc_c);
70  }
71  // Mip Count.
72  {
73  TextureDescriptor desc_a = {.mip_count = 1};
74  TextureDescriptor desc_b = {.mip_count = 1};
75  TextureDescriptor desc_c = {.mip_count = 4};
76 
77  ASSERT_EQ(desc_a, desc_b);
78  ASSERT_NE(desc_a, desc_c);
79  }
80 }

References impeller::TextureDescriptor::compression_type, impeller::TextureDescriptor::format, impeller::kB10G10R10A10XR, impeller::kCount1, impeller::kCount4, impeller::kDevicePrivate, impeller::kHostVisible, impeller::kLossless, impeller::kLossy, impeller::kR8G8B8A8UNormInt, impeller::kTexture2D, impeller::kTexture2DMultisample, impeller::TextureDescriptor::mip_count, impeller::TextureDescriptor::sample_count, impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::type.

◆ TEST() [30/202]

impeller::testing::TEST ( BlitCommandVkTest  ,
BlitCopyBufferToTextureCommandVK   
)

Definition at line 46 of file blit_command_vk_unittests.cc.

46  {
47  auto context = MockVulkanContextBuilder().Build();
48  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
49  BlitCopyBufferToTextureCommandVK cmd;
50  cmd.destination = context->GetResourceAllocator()->CreateTexture({
51  .size = ISize(100, 100),
52  });
53  cmd.source = context->GetResourceAllocator()
54  ->CreateBuffer({
55  .size = 1,
56  })
57  ->AsBufferView();
58  bool result = cmd.Encode(*encoder.get());
59  EXPECT_TRUE(result);
60  EXPECT_TRUE(encoder->IsTracking(cmd.source.buffer));
61  EXPECT_TRUE(encoder->IsTracking(cmd.destination));
62 }

References impeller::BufferView::buffer, impeller::BlitCopyBufferToTextureCommand::destination, impeller::BlitCopyBufferToTextureCommandVK::Encode(), and impeller::BlitCopyBufferToTextureCommand::source.

◆ TEST() [31/202]

impeller::testing::TEST ( BlitCommandVkTest  ,
BlitCopyTextureToBufferCommandVK   
)

Definition at line 30 of file blit_command_vk_unittests.cc.

30  {
31  auto context = MockVulkanContextBuilder().Build();
32  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
33  BlitCopyTextureToBufferCommandVK cmd;
34  cmd.source = context->GetResourceAllocator()->CreateTexture({
35  .size = ISize(100, 100),
36  });
37  cmd.destination = context->GetResourceAllocator()->CreateBuffer({
38  .size = 1,
39  });
40  bool result = cmd.Encode(*encoder.get());
41  EXPECT_TRUE(result);
42  EXPECT_TRUE(encoder->IsTracking(cmd.source));
43  EXPECT_TRUE(encoder->IsTracking(cmd.destination));
44 }

References impeller::BlitCopyTextureToBufferCommand::destination, impeller::BlitCopyTextureToBufferCommandVK::Encode(), and impeller::BlitCopyTextureToBufferCommand::source.

◆ TEST() [32/202]

impeller::testing::TEST ( BlitCommandVkTest  ,
BlitCopyTextureToTextureCommandVK   
)

Definition at line 13 of file blit_command_vk_unittests.cc.

13  {
14  auto context = MockVulkanContextBuilder().Build();
15  auto pool = context->GetCommandPoolRecycler()->Get();
16  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
17  BlitCopyTextureToTextureCommandVK cmd;
18  cmd.source = context->GetResourceAllocator()->CreateTexture({
19  .size = ISize(100, 100),
20  });
21  cmd.destination = context->GetResourceAllocator()->CreateTexture({
22  .size = ISize(100, 100),
23  });
24  bool result = cmd.Encode(*encoder.get());
25  EXPECT_TRUE(result);
26  EXPECT_TRUE(encoder->IsTracking(cmd.source));
27  EXPECT_TRUE(encoder->IsTracking(cmd.destination));
28 }

References impeller::BlitCopyTextureToTextureCommand::destination, impeller::BlitCopyTextureToTextureCommandVK::Encode(), and impeller::BlitCopyTextureToTextureCommand::source.

◆ TEST() [33/202]

impeller::testing::TEST ( BlitCommandVkTest  ,
BlitGenerateMipmapCommandVK   
)

Definition at line 64 of file blit_command_vk_unittests.cc.

64  {
65  auto context = MockVulkanContextBuilder().Build();
66  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
67  BlitGenerateMipmapCommandVK cmd;
68  cmd.texture = context->GetResourceAllocator()->CreateTexture({
69  .size = ISize(100, 100),
70  .mip_count = 2,
71  });
72  bool result = cmd.Encode(*encoder.get());
73  EXPECT_TRUE(result);
74  EXPECT_TRUE(encoder->IsTracking(cmd.texture));
75 }

References impeller::BlitGenerateMipmapCommandVK::Encode(), and impeller::BlitGenerateMipmapCommand::texture.

◆ TEST() [34/202]

impeller::testing::TEST ( BlobTest  ,
CanReadAndWriteBlobs   
)

Definition at line 28 of file blobcat_unittests.cc.

28  {
29  BlobWriter writer;
30  ASSERT_TRUE(writer.AddBlob(BlobShaderType::kVertex, "Hello",
31  CreateMappingFromString("World")));
32  ASSERT_TRUE(writer.AddBlob(BlobShaderType::kFragment, "Foo",
33  CreateMappingFromString("Bar")));
34  ASSERT_TRUE(writer.AddBlob(BlobShaderType::kVertex, "Baz",
35  CreateMappingFromString("Bang")));
36  ASSERT_TRUE(writer.AddBlob(BlobShaderType::kVertex, "Ping",
37  CreateMappingFromString("Pong")));
38  ASSERT_TRUE(writer.AddBlob(BlobShaderType::kFragment, "Pang",
39  CreateMappingFromString("World")));
40 
41  auto mapping = writer.CreateMapping();
42  ASSERT_NE(mapping, nullptr);
43 
44  BlobLibrary library(mapping);
45  ASSERT_TRUE(library.IsValid());
46  ASSERT_EQ(library.GetShaderCount(), 5u);
47 
48  // Wrong type.
49  ASSERT_EQ(library.GetMapping(BlobShaderType::kFragment, "Hello"), nullptr);
50 
51  auto hello_vtx = library.GetMapping(BlobShaderType::kVertex, "Hello");
52  ASSERT_NE(hello_vtx, nullptr);
53  ASSERT_EQ(CreateStringFromMapping(*hello_vtx), "World");
54 }

References impeller::BlobWriter::AddBlob(), impeller::BlobWriter::CreateMapping(), CreateMappingFromString(), CreateStringFromMapping(), impeller::BlobLibrary::GetMapping(), impeller::BlobLibrary::GetShaderCount(), impeller::BlobLibrary::IsValid(), impeller::kFragment, and impeller::kVertex.

◆ TEST() [35/202]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultColorFormat   
)

Definition at line 33 of file capabilities_unittests.cc.

33  {
34  auto defaults = CapabilitiesBuilder().Build();
35  ASSERT_EQ(defaults->GetDefaultColorFormat(), PixelFormat::kUnknown);
36  auto mutated = CapabilitiesBuilder()
37  .SetDefaultColorFormat(PixelFormat::kB10G10R10A10XR)
38  .Build();
39  ASSERT_EQ(mutated->GetDefaultColorFormat(), PixelFormat::kB10G10R10A10XR);
40 }

References impeller::CapabilitiesBuilder::Build(), impeller::kB10G10R10A10XR, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultColorFormat().

◆ TEST() [36/202]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultDepthStencilFormat   
)

Definition at line 51 of file capabilities_unittests.cc.

51  {
52  auto defaults = CapabilitiesBuilder().Build();
53  ASSERT_EQ(defaults->GetDefaultDepthStencilFormat(), PixelFormat::kUnknown);
54  auto mutated = CapabilitiesBuilder()
55  .SetDefaultDepthStencilFormat(PixelFormat::kD32FloatS8UInt)
56  .Build();
57  ASSERT_EQ(mutated->GetDefaultDepthStencilFormat(),
58  PixelFormat::kD32FloatS8UInt);
59 }

References impeller::CapabilitiesBuilder::Build(), impeller::kD32FloatS8UInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultDepthStencilFormat().

◆ TEST() [37/202]

impeller::testing::TEST ( CapabilitiesTest  ,
DefaultStencilFormat   
)

Definition at line 42 of file capabilities_unittests.cc.

42  {
43  auto defaults = CapabilitiesBuilder().Build();
44  ASSERT_EQ(defaults->GetDefaultStencilFormat(), PixelFormat::kUnknown);
45  auto mutated = CapabilitiesBuilder()
46  .SetDefaultStencilFormat(PixelFormat::kS8UInt)
47  .Build();
48  ASSERT_EQ(mutated->GetDefaultStencilFormat(), PixelFormat::kS8UInt);
49 }

References impeller::CapabilitiesBuilder::Build(), impeller::kS8UInt, impeller::kUnknown, and impeller::CapabilitiesBuilder::SetDefaultStencilFormat().

◆ TEST() [38/202]

impeller::testing::TEST ( CommandEncoderVKTest  ,
CleanupAfterSubmit   
)

Definition at line 41 of file command_encoder_vk_unittests.cc.

41  {
42  // This tests deleting the TrackedObjects where the thread is killed before
43  // the fence waiter has disposed of them, making sure the command buffer and
44  // its pools are deleted in that order.
45  std::shared_ptr<std::vector<std::string>> called_functions;
46  {
47  fml::AutoResetWaitableEvent wait_for_submit;
48  fml::AutoResetWaitableEvent wait_for_thread_join;
49  auto context = MockVulkanContextBuilder().Build();
50  std::thread thread([&] {
51  CommandEncoderFactoryVK factory(context);
52  std::shared_ptr<CommandEncoderVK> encoder = factory.Create();
53  encoder->Submit([&](bool success) {
54  ASSERT_TRUE(success);
55  wait_for_thread_join.Wait();
56  wait_for_submit.Signal();
57  });
58  });
59  thread.join();
60  wait_for_thread_join.Signal();
61  wait_for_submit.Wait();
62  called_functions = GetMockVulkanFunctions(context->GetDevice());
63  context->Shutdown();
64  }
65 
66  auto destroy_pool =
67  std::find(called_functions->begin(), called_functions->end(),
68  "vkDestroyCommandPool");
69  auto free_buffers =
70  std::find(called_functions->begin(), called_functions->end(),
71  "vkFreeCommandBuffers");
72  EXPECT_TRUE(destroy_pool != called_functions->end());
73  EXPECT_TRUE(free_buffers != called_functions->end());
74  EXPECT_TRUE(free_buffers < destroy_pool);
75 }

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [39/202]

impeller::testing::TEST ( CommandEncoderVKTest  ,
DeleteEncoderAfterThreadDies   
)

Definition at line 15 of file command_encoder_vk_unittests.cc.

15  {
16  // Tests that when a CommandEncoderVK is deleted that it will clean up its
17  // command buffers before it cleans up its command pool.
18  std::shared_ptr<std::vector<std::string>> called_functions;
19  {
20  auto context = MockVulkanContextBuilder().Build();
21  called_functions = GetMockVulkanFunctions(context->GetDevice());
22  std::shared_ptr<CommandEncoderVK> encoder;
23  std::thread thread([&] {
24  CommandEncoderFactoryVK factory(context);
25  encoder = factory.Create();
26  });
27  thread.join();
28  context->Shutdown();
29  }
30  auto destroy_pool =
31  std::find(called_functions->begin(), called_functions->end(),
32  "vkDestroyCommandPool");
33  auto free_buffers =
34  std::find(called_functions->begin(), called_functions->end(),
35  "vkFreeCommandBuffers");
36  EXPECT_TRUE(destroy_pool != called_functions->end());
37  EXPECT_TRUE(free_buffers != called_functions->end());
38  EXPECT_TRUE(free_buffers < destroy_pool);
39 }

References impeller::CommandEncoderFactoryVK::Create().

◆ TEST() [40/202]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsACommandPoolPerThread   
)

Definition at line 14 of file command_pool_vk_unittests.cc.

14  {
15  auto const context = MockVulkanContextBuilder().Build();
16 
17  {
18  // Record the memory location of each pointer to a command pool.
19  //
20  // These pools have to be held at this context, otherwise they will be
21  // dropped and recycled and potentially reused by another thread, causing
22  // flaky tests.
23  std::shared_ptr<CommandPoolVK> pool1;
24  std::shared_ptr<CommandPoolVK> pool2;
25 
26  // Create a command pool in two threads and record the memory location.
27  std::thread thread1(
28  [&]() { pool1 = context->GetCommandPoolRecycler()->Get(); });
29 
30  std::thread thread2(
31  [&]() { pool2 = context->GetCommandPoolRecycler()->Get(); });
32 
33  thread1.join();
34  thread2.join();
35 
36  // The two command pools should be different.
37  EXPECT_NE(pool1, pool2);
38  }
39 
40  context->Shutdown();
41 }

◆ TEST() [41/202]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
GetsTheSameCommandPoolOnSameThread   
)

Definition at line 43 of file command_pool_vk_unittests.cc.

43  {
44  auto const context = MockVulkanContextBuilder().Build();
45 
46  auto const pool1 = context->GetCommandPoolRecycler()->Get();
47  auto const pool2 = context->GetCommandPoolRecycler()->Get();
48 
49  // The two command pools should be the same.
50  EXPECT_EQ(pool1.get(), pool2.get());
51 
52  context->Shutdown();
53 }

◆ TEST() [42/202]

impeller::testing::TEST ( CommandPoolRecyclerVKTest  ,
ReclaimMakesCommandPoolAvailable   
)

Definition at line 76 of file command_pool_vk_unittests.cc.

76  {
77  auto const context = MockVulkanContextBuilder().Build();
78 
79  {
80  // Fetch a pool (which will be created).
81  auto const recycler = context->GetCommandPoolRecycler();
82  auto const pool = recycler->Get();
83 
84  // This normally is called at the end of a frame.
85  recycler->Dispose();
86  }
87 
88  // Add something to the resource manager and have it notify us when it's
89  // destroyed. That should give us a non-flaky signal that the pool has been
90  // reclaimed as well.
91  auto waiter = fml::AutoResetWaitableEvent();
92  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
93  {
94  UniqueResourceVKT<DeathRattle> resource(context->GetResourceManager(),
95  std::move(rattle));
96  }
97  waiter.Wait();
98 
99  // On another thread explicitly, request a new pool.
100  std::thread thread([&]() {
101  auto const pool = context->GetCommandPoolRecycler()->Get();
102  EXPECT_NE(pool.get(), nullptr);
103  });
104 
105  thread.join();
106 
107  // Now check that we only ever created one pool.
108  auto const called = GetMockVulkanFunctions(context->GetDevice());
109  EXPECT_EQ(std::count(called->begin(), called->end(), "vkCreateCommandPool"),
110  1u);
111 
112  context->Shutdown();
113 }

◆ TEST() [43/202]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextInAbsenceOfValidationLayers   
)

Definition at line 117 of file context_vk_unittests.cc.

117  {
118  // The mocked methods don't report the presence of a validation layer but we
119  // explicitly ask for validation. Context creation should continue anyway.
120  auto context = MockVulkanContextBuilder()
121  .SetSettingsCallback([](auto& settings) {
122  settings.enable_validation = true;
123  })
124  .Build();
125  ASSERT_NE(context, nullptr);
126  const CapabilitiesVK* capabilites_vk =
127  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
128  ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
129 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [44/202]

impeller::testing::TEST ( ContextVKTest  ,
CanCreateContextWithValidationLayers   
)

Definition at line 131 of file context_vk_unittests.cc.

131  {
132  auto context =
133  MockVulkanContextBuilder()
134  .SetSettingsCallback(
135  [](auto& settings) { settings.enable_validation = true; })
136  .SetInstanceExtensions(
137  {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
138  .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
139  .Build();
140  ASSERT_NE(context, nullptr);
141  const CapabilitiesVK* capabilites_vk =
142  reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
143  ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
144 }

References impeller::CapabilitiesVK::AreValidationsEnabled().

◆ TEST() [45/202]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineAfterContext   
)

Definition at line 60 of file context_vk_unittests.cc.

60  {
61  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
62  std::shared_ptr<std::vector<std::string>> functions;
63  {
64  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
65  PipelineDescriptor pipeline_desc;
66  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
67  PipelineFuture<PipelineDescriptor> pipeline_future =
68  context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
69  pipeline = pipeline_future.Get();
70  ASSERT_TRUE(pipeline);
71  functions = GetMockVulkanFunctions(context->GetDevice());
72  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
73  "vkCreateGraphicsPipelines") != functions->end());
74  }
75  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
76  "vkDestroyDevice") != functions->end());
77 }

References impeller::PipelineFuture< T >::Get(), and impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [46/202]

impeller::testing::TEST ( ContextVKTest  ,
DeletePipelineLibraryAfterContext   
)

Definition at line 101 of file context_vk_unittests.cc.

101  {
102  std::shared_ptr<PipelineLibrary> pipeline_library;
103  std::shared_ptr<std::vector<std::string>> functions;
104  {
105  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
106  PipelineDescriptor pipeline_desc;
107  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
108  pipeline_library = context->GetPipelineLibrary();
109  functions = GetMockVulkanFunctions(context->GetDevice());
110  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
111  "vkCreatePipelineCache") != functions->end());
112  }
113  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
114  "vkDestroyDevice") != functions->end());
115 }

References impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [47/202]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPools   
)

Definition at line 14 of file context_vk_unittests.cc.

14  {
15  std::weak_ptr<ContextVK> weak_context;
16  std::weak_ptr<CommandPoolVK> weak_pool;
17  {
18  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
19  auto const pool = context->GetCommandPoolRecycler()->Get();
20  weak_pool = pool;
21  weak_context = context;
22  ASSERT_TRUE(weak_pool.lock());
23  ASSERT_TRUE(weak_context.lock());
24  }
25  ASSERT_FALSE(weak_pool.lock());
26  ASSERT_FALSE(weak_context.lock());
27 }

◆ TEST() [48/202]

impeller::testing::TEST ( ContextVKTest  ,
DeletesCommandPoolsOnAllThreads   
)

Definition at line 29 of file context_vk_unittests.cc.

29  {
30  std::weak_ptr<ContextVK> weak_context;
31  std::weak_ptr<CommandPoolVK> weak_pool_main;
32 
33  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
34  weak_pool_main = context->GetCommandPoolRecycler()->Get();
35  weak_context = context;
36  ASSERT_TRUE(weak_pool_main.lock());
37  ASSERT_TRUE(weak_context.lock());
38 
39  // Start a second thread that obtains a command pool.
40  fml::AutoResetWaitableEvent latch1, latch2;
41  std::weak_ptr<CommandPoolVK> weak_pool_thread;
42  std::thread thread([&]() {
43  weak_pool_thread = context->GetCommandPoolRecycler()->Get();
44  latch1.Signal();
45  latch2.Wait();
46  });
47 
48  // Delete the ContextVK on the main thread.
49  latch1.Wait();
50  context.reset();
51  ASSERT_FALSE(weak_pool_main.lock());
52  ASSERT_FALSE(weak_context.lock());
53 
54  // Stop the second thread and check that its command pool has been deleted.
55  latch2.Signal();
56  thread.join();
57  ASSERT_FALSE(weak_pool_thread.lock());
58 }

◆ TEST() [49/202]

impeller::testing::TEST ( ContextVKTest  ,
DeleteShaderFunctionAfterContext   
)

Definition at line 79 of file context_vk_unittests.cc.

79  {
80  std::shared_ptr<const ShaderFunction> shader_function;
81  std::shared_ptr<std::vector<std::string>> functions;
82  {
83  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
84  PipelineDescriptor pipeline_desc;
85  pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
86  std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
87  context->GetShaderLibrary()->RegisterFunction(
88  "foobar", ShaderStage::kFragment,
89  std::make_shared<fml::DataMapping>(data), [](bool) {});
90  shader_function = context->GetShaderLibrary()->GetFunction(
91  "foobar_fragment_main", ShaderStage::kFragment);
92  ASSERT_TRUE(shader_function);
93  functions = GetMockVulkanFunctions(context->GetDevice());
94  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
95  "vkCreateShaderModule") != functions->end());
96  }
97  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
98  "vkDestroyDevice") != functions->end());
99 }

References impeller::kFragment, and impeller::PipelineDescriptor::SetVertexDescriptor().

◆ TEST() [50/202]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversArea   
)

Definition at line 20 of file geometry_unittests.cc.

20  {
21  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
22  auto geometry = Geometry::MakeFillPath(
23  path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
24  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
25  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
26  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
27  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
28 }

References impeller::PathBuilder::AddRect(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST() [51/202]

impeller::testing::TEST ( EntityGeometryTest  ,
FillPathGeometryCoversAreaNoInnerRect   
)

Definition at line 30 of file geometry_unittests.cc.

30  {
31  auto path = PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath();
32  auto geometry = Geometry::MakeFillPath(path);
33  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
34  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
35  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
36  ASSERT_FALSE(geometry->CoversArea({}, Rect()));
37 }

References impeller::PathBuilder::AddRect(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST() [52/202]

impeller::testing::TEST ( EntityGeometryTest  ,
RectGeometryCoversArea   
)

Definition at line 12 of file geometry_unittests.cc.

12  {
13  auto geometry = Geometry::MakeRect(Rect::MakeLTRB(0, 0, 100, 100));
14  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(0, 0, 100, 100)));
15  ASSERT_FALSE(geometry->CoversArea({}, Rect::MakeLTRB(-1, 0, 100, 100)));
16  ASSERT_TRUE(geometry->CoversArea({}, Rect::MakeLTRB(1, 1, 100, 100)));
17  ASSERT_TRUE(geometry->CoversArea({}, Rect()));
18 }

References impeller::TRect< Scalar >::MakeLTRB(), and impeller::Geometry::MakeRect().

◆ TEST() [53/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
AddFenceDoesNothingIfTerminating   
)

Definition at line 86 of file fence_waiter_vk_unittests.cc.

86  {
87  auto signal = fml::ManualResetWaitableEvent();
88 
89  {
90  auto const context = MockVulkanContextBuilder().Build();
91  auto const device = context->GetDevice();
92  auto const waiter = context->GetFenceWaiter();
93  waiter->Terminate();
94 
95  auto fence = device.createFenceUnique({}).value;
96  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
97  }
98 
99  // Ensure the fence did _not_ signal.
100  EXPECT_TRUE(signal.WaitWithTimeout(fml::TimeDelta::FromMilliseconds(100)));
101 }

◆ TEST() [54/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallback   
)

Definition at line 28 of file fence_waiter_vk_unittests.cc.

28  {
29  auto const context = MockVulkanContextBuilder().Build();
30  auto const device = context->GetDevice();
31  auto const waiter = context->GetFenceWaiter();
32 
33  auto signal = fml::ManualResetWaitableEvent();
34  auto fence = device.createFenceUnique({}).value;
35  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
36 
37  signal.Wait();
38 }

◆ TEST() [55/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesFenceCallbackX2   
)

Definition at line 40 of file fence_waiter_vk_unittests.cc.

40  {
41  auto const context = MockVulkanContextBuilder().Build();
42  auto const device = context->GetDevice();
43  auto const waiter = context->GetFenceWaiter();
44 
45  auto signal = fml::ManualResetWaitableEvent();
46  auto fence = device.createFenceUnique({}).value;
47  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
48 
49  auto signal2 = fml::ManualResetWaitableEvent();
50  auto fence2 = device.createFenceUnique({}).value;
51  waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
52 
53  signal.Wait();
54  signal2.Wait();
55 }

◆ TEST() [56/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
ExecutesNewFenceThenOldFence   
)

Definition at line 57 of file fence_waiter_vk_unittests.cc.

57  {
58  auto const context = MockVulkanContextBuilder().Build();
59  auto const device = context->GetDevice();
60  auto const waiter = context->GetFenceWaiter();
61 
62  auto signal = fml::ManualResetWaitableEvent();
63  auto fence = device.createFenceUnique({}).value;
64  MockFence::SetStatus(fence, vk::Result::eNotReady);
65  auto raw_fence = MockFence::GetRawPointer(fence);
66  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
67 
68  // The easiest way to verify that the callback was _not_ called is to wait
69  // for a timeout, but that could introduce flakiness. Instead, we'll add a
70  // second fence that will signal immediately, and wait for that one instead.
71  {
72  auto signal2 = fml::ManualResetWaitableEvent();
73  auto fence2 = device.createFenceUnique({}).value;
74  MockFence::SetStatus(fence2, vk::Result::eSuccess);
75  waiter->AddFence(std::move(fence2), [&signal2]() { signal2.Signal(); });
76  signal2.Wait();
77  }
78 
79  // Now, we'll signal the first fence, and wait for the callback to be called.
80  raw_fence->SetStatus(vk::Result::eSuccess);
81 
82  // Now, we'll signal the first fence, and wait for the callback to be called.
83  signal.Wait();
84 }

◆ TEST() [57/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullCallback   
)

Definition at line 19 of file fence_waiter_vk_unittests.cc.

19  {
20  auto const context = MockVulkanContextBuilder().Build();
21  auto const device = context->GetDevice();
22  auto const waiter = context->GetFenceWaiter();
23 
24  auto fence = device.createFenceUnique({}).value;
25  EXPECT_FALSE(waiter->AddFence(std::move(fence), nullptr));
26 }

◆ TEST() [58/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
IgnoresNullFence   
)

Definition at line 13 of file fence_waiter_vk_unittests.cc.

13  {
14  auto const context = MockVulkanContextBuilder().Build();
15  auto const waiter = context->GetFenceWaiter();
16  EXPECT_FALSE(waiter->AddFence(vk::UniqueFence(), []() {}));
17 }

◆ TEST() [59/202]

impeller::testing::TEST ( FenceWaiterVKTest  ,
InProgressFencesStillWaitIfTerminated   
)

Definition at line 103 of file fence_waiter_vk_unittests.cc.

103  {
104  MockFence* raw_fence = nullptr;
105  auto signal = fml::ManualResetWaitableEvent();
106 
107  auto const context = MockVulkanContextBuilder().Build();
108  auto const device = context->GetDevice();
109  auto const waiter = context->GetFenceWaiter();
110 
111  // Add a fence that isn't signalled yet.
112  auto fence = device.createFenceUnique({}).value;
113 
114  // Even if the fence is eSuccess, it's not guaranteed to be called in time.
115  MockFence::SetStatus(fence, vk::Result::eNotReady);
116  raw_fence = MockFence::GetRawPointer(fence);
117  waiter->AddFence(std::move(fence), [&signal]() { signal.Signal(); });
118 
119  // Terminate the waiter.
120  waiter->Terminate();
121 
122  // Signal the fence.
123  raw_fence->SetStatus(vk::Result::eSuccess);
124 
125  // This will hang if the fence was not signalled.
126  signal.Wait();
127 }

◆ TEST() [60/202]

impeller::testing::TEST ( FilterInputTest  ,
CanSetLocalTransformForTexture   
)

Definition at line 17 of file filter_input_unittests.cc.

17  {
18  std::shared_ptr<Texture> texture = nullptr;
19  auto input =
20  FilterInput::Make(texture, Matrix::MakeTranslation({1.0, 0.0, 0.0}));
21  Entity e;
22  e.SetTransformation(Matrix::MakeTranslation({0.0, 2.0, 0.0}));
23 
24  ASSERT_MATRIX_NEAR(input->GetLocalTransform(e),
25  Matrix::MakeTranslation({1.0, 0.0, 0.0}));
26  ASSERT_MATRIX_NEAR(input->GetTransform(e),
27  Matrix::MakeTranslation({1.0, 2.0, 0.0}));
28 }

References ASSERT_MATRIX_NEAR, impeller::FilterInput::Make(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransformation().

◆ TEST() [61/202]

impeller::testing::TEST ( FilterInputTest  ,
IsLeaf   
)

Definition at line 30 of file filter_input_unittests.cc.

30  {
31  std::shared_ptr<FilterContents> leaf =
32  ColorFilterContents::MakeBlend(BlendMode::kSource, {});
33  ASSERT_TRUE(leaf->IsLeaf());
34 
35  auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
36  Matrix(), {});
37 
38  ASSERT_TRUE(leaf->IsLeaf());
39  ASSERT_FALSE(base->IsLeaf());
40 }

References impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), and impeller::FilterContents::MakeMatrixFilter().

◆ TEST() [62/202]

impeller::testing::TEST ( FilterInputTest  ,
SetCoverageInputs   
)

Definition at line 42 of file filter_input_unittests.cc.

42  {
43  std::shared_ptr<FilterContents> leaf =
44  ColorFilterContents::MakeBlend(BlendMode::kSource, {});
45  ASSERT_TRUE(leaf->IsLeaf());
46 
47  auto base = ColorFilterContents::MakeMatrixFilter(FilterInput::Make(leaf),
48  Matrix(), {});
49 
50  {
51  auto result = base->GetCoverage({});
52  ASSERT_FALSE(result.has_value());
53  }
54 
55  auto coverage_rect = Rect::MakeLTRB(100, 100, 200, 200);
56  base->SetLeafInputs(FilterInput::Make({coverage_rect}));
57 
58  {
59  auto result = base->GetCoverage({});
60  ASSERT_TRUE(result.has_value());
61  // NOLINTNEXTLINE(bugprone-unchecked-optional-access)
62  ASSERT_RECT_NEAR(result.value(), coverage_rect);
63  }
64 }

References ASSERT_RECT_NEAR, impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::FilterContents::MakeMatrixFilter().

◆ TEST() [63/202]

impeller::testing::TEST ( GeometryTest  ,
BlendModeToString   
)

Definition at line 1566 of file geometry_unittests.cc.

1566  {
1567  using BlendT = std::underlying_type_t<BlendMode>;
1568  for (BlendT i = 0; i <= static_cast<BlendT>(BlendMode::kLast); i++) {
1569  auto mode = static_cast<BlendMode>(i);
1570  auto result = BlendModeToString(mode);
1572  }
1573 }

References _BLEND_MODE_NAME_CHECK, impeller::BlendModeToString(), IMPELLER_FOR_EACH_BLEND_MODE, and impeller::kLast.

◆ TEST() [64/202]

impeller::testing::TEST ( GeometryTest  ,
BoundingBoxCubic   
)

Definition at line 667 of file geometry_unittests.cc.

667  {
668  PathBuilder builder;
669  auto path =
670  builder.AddCubicCurve({120, 160}, {25, 200}, {220, 260}, {220, 40})
671  .TakePath();
672  auto box = path.GetBoundingBox();
673  Rect expected(93.9101, 40, 126.09, 158.862);
674  ASSERT_TRUE(box.has_value());
675  ASSERT_RECT_NEAR(box.value(), expected);
676 }

References impeller::PathBuilder::AddCubicCurve(), and ASSERT_RECT_NEAR.

◆ TEST() [65/202]

impeller::testing::TEST ( GeometryTest  ,
BoundingBoxOfCompositePathIsCorrect   
)

Definition at line 678 of file geometry_unittests.cc.

678  {
679  PathBuilder builder;
680  builder.AddRoundedRect({{10, 10}, {300, 300}}, {50, 50, 50, 50});
681  auto path = builder.TakePath();
682  auto actual = path.GetBoundingBox();
683  Rect expected(10, 10, 300, 300);
684  ASSERT_TRUE(actual.has_value());
685  ASSERT_RECT_NEAR(actual.value(), expected);
686 }

References impeller::PathBuilder::AddRoundedRect(), ASSERT_RECT_NEAR, impeller::Path::GetBoundingBox(), and impeller::PathBuilder::TakePath().

◆ TEST() [66/202]

impeller::testing::TEST ( GeometryTest  ,
CanConvertBetweenDegressAndRadians   
)

Definition at line 1575 of file geometry_unittests.cc.

1575  {
1576  {
1577  auto deg = Degrees{90.0};
1578  Radians rad = deg;
1579  ASSERT_FLOAT_EQ(rad.radians, kPiOver2);
1580  }
1581 }

References impeller::kPiOver2, and impeller::Radians::radians.

◆ TEST() [67/202]

impeller::testing::TEST ( GeometryTest  ,
CanConvertTTypesExplicitly   
)

Definition at line 722 of file geometry_unittests.cc.

722  {
723  {
724  Point p1(1.0, 2.0);
725  IPoint p2 = static_cast<IPoint>(p1);
726  ASSERT_EQ(p2.x, 1u);
727  ASSERT_EQ(p2.y, 2u);
728  }
729 
730  {
731  Size s1(1.0, 2.0);
732  ISize s2 = static_cast<ISize>(s1);
733  ASSERT_EQ(s2.width, 1u);
734  ASSERT_EQ(s2.height, 2u);
735  }
736 
737  {
738  Size s1(1.0, 2.0);
739  Point p1 = static_cast<Point>(s1);
740  ASSERT_EQ(p1.x, 1u);
741  ASSERT_EQ(p1.y, 2u);
742  }
743 
744  {
745  Rect r1(1.0, 2.0, 3.0, 4.0);
746  IRect r2 = static_cast<IRect>(r1);
747  ASSERT_EQ(r2.origin.x, 1u);
748  ASSERT_EQ(r2.origin.y, 2u);
749  ASSERT_EQ(r2.size.width, 3u);
750  ASSERT_EQ(r2.size.height, 4u);
751  }
752 }

References impeller::TSize< T >::height, impeller::TRect< T >::origin, impeller::TRect< T >::size, impeller::TSize< T >::width, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [68/202]

impeller::testing::TEST ( GeometryTest  ,
CanGenerateMipCounts   
)

Definition at line 709 of file geometry_unittests.cc.

709  {
710  ASSERT_EQ((Size{128, 128}.MipCount()), 7u);
711  ASSERT_EQ((Size{128, 256}.MipCount()), 8u);
712  ASSERT_EQ((Size{128, 130}.MipCount()), 8u);
713  ASSERT_EQ((Size{128, 257}.MipCount()), 9u);
714  ASSERT_EQ((Size{257, 128}.MipCount()), 9u);
715  ASSERT_EQ((Size{128, 0}.MipCount()), 1u);
716  ASSERT_EQ((Size{128, -25}.MipCount()), 1u);
717  ASSERT_EQ((Size{-128, 25}.MipCount()), 1u);
718  ASSERT_EQ((Size{1, 1}.MipCount()), 1u);
719  ASSERT_EQ((Size{0, 0}.MipCount()), 1u);
720 }

References impeller::TSize< T >::MipCount().

◆ TEST() [69/202]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOps   
)

Definition at line 754 of file geometry_unittests.cc.

754  {
755  {
756  IPoint p1(1, 2);
757  IPoint p2 = p1 + IPoint(1, 2);
758  ASSERT_EQ(p2.x, 2u);
759  ASSERT_EQ(p2.y, 4u);
760  }
761 
762  {
763  IPoint p1(3, 6);
764  IPoint p2 = p1 - IPoint(1, 2);
765  ASSERT_EQ(p2.x, 2u);
766  ASSERT_EQ(p2.y, 4u);
767  }
768 
769  {
770  IPoint p1(1, 2);
771  IPoint p2 = p1 * IPoint(2, 3);
772  ASSERT_EQ(p2.x, 2u);
773  ASSERT_EQ(p2.y, 6u);
774  }
775 
776  {
777  IPoint p1(2, 6);
778  IPoint p2 = p1 / IPoint(2, 3);
779  ASSERT_EQ(p2.x, 1u);
780  ASSERT_EQ(p2.y, 2u);
781  }
782 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [70/202]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicPointOpsWithArithmeticTypes   
)

Definition at line 784 of file geometry_unittests.cc.

784  {
785  // LHS
786  {
787  IPoint p1(1, 2);
788  IPoint p2 = p1 * 2.0f;
789  ASSERT_EQ(p2.x, 2u);
790  ASSERT_EQ(p2.y, 4u);
791  }
792 
793  {
794  IPoint p1(2, 6);
795  IPoint p2 = p1 / 2.0f;
796  ASSERT_EQ(p2.x, 1u);
797  ASSERT_EQ(p2.y, 3u);
798  }
799 
800  // RHS
801  {
802  IPoint p1(1, 2);
803  IPoint p2 = 2.0f * p1;
804  ASSERT_EQ(p2.x, 2u);
805  ASSERT_EQ(p2.y, 4u);
806  }
807 
808  {
809  IPoint p1(2, 6);
810  IPoint p2 = 12.0f / p1;
811  ASSERT_EQ(p2.x, 6u);
812  ASSERT_EQ(p2.y, 2u);
813  }
814 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [71/202]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3Ops   
)

Definition at line 1288 of file geometry_unittests.cc.

1288  {
1289  {
1290  Vector3 p1(1, 2, 3);
1291  Vector3 p2 = p1 + Vector3(1, 2, 3);
1292  ASSERT_EQ(p2.x, 2u);
1293  ASSERT_EQ(p2.y, 4u);
1294  ASSERT_EQ(p2.z, 6u);
1295  }
1296 
1297  {
1298  Vector3 p1(3, 6, 9);
1299  Vector3 p2 = p1 - Vector3(1, 2, 3);
1300  ASSERT_EQ(p2.x, 2u);
1301  ASSERT_EQ(p2.y, 4u);
1302  ASSERT_EQ(p2.z, 6u);
1303  }
1304 
1305  {
1306  Vector3 p1(1, 2, 3);
1307  Vector3 p2 = p1 * Vector3(2, 3, 4);
1308  ASSERT_EQ(p2.x, 2u);
1309  ASSERT_EQ(p2.y, 6u);
1310  ASSERT_EQ(p2.z, 12u);
1311  }
1312 
1313  {
1314  Vector3 p1(2, 6, 12);
1315  Vector3 p2 = p1 / Vector3(2, 3, 4);
1316  ASSERT_EQ(p2.x, 1u);
1317  ASSERT_EQ(p2.y, 2u);
1318  ASSERT_EQ(p2.z, 3u);
1319  }
1320 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [72/202]

impeller::testing::TEST ( GeometryTest  ,
CanPerformAlgebraicVector3OpsWithArithmeticTypes   
)

Definition at line 1322 of file geometry_unittests.cc.

1322  {
1323  // LHS
1324  {
1325  Vector3 p1(1, 2, 3);
1326  Vector3 p2 = p1 + 2.0f;
1327  ASSERT_EQ(p2.x, 3);
1328  ASSERT_EQ(p2.y, 4);
1329  ASSERT_EQ(p2.z, 5);
1330  }
1331 
1332  {
1333  Vector3 p1(1, 2, 3);
1334  Vector3 p2 = p1 - 2.0f;
1335  ASSERT_EQ(p2.x, -1);
1336  ASSERT_EQ(p2.y, 0);
1337  ASSERT_EQ(p2.z, 1);
1338  }
1339 
1340  {
1341  Vector3 p1(1, 2, 3);
1342  Vector3 p2 = p1 * 2.0f;
1343  ASSERT_EQ(p2.x, 2);
1344  ASSERT_EQ(p2.y, 4);
1345  ASSERT_EQ(p2.z, 6);
1346  }
1347 
1348  {
1349  Vector3 p1(2, 6, 12);
1350  Vector3 p2 = p1 / 2.0f;
1351  ASSERT_EQ(p2.x, 1);
1352  ASSERT_EQ(p2.y, 3);
1353  ASSERT_EQ(p2.z, 6);
1354  }
1355 
1356  // RHS
1357  {
1358  Vector3 p1(1, 2, 3);
1359  Vector3 p2 = 2.0f + p1;
1360  ASSERT_EQ(p2.x, 3);
1361  ASSERT_EQ(p2.y, 4);
1362  ASSERT_EQ(p2.z, 5);
1363  }
1364 
1365  {
1366  Vector3 p1(1, 2, 3);
1367  Vector3 p2 = 2.0f - p1;
1368  ASSERT_EQ(p2.x, 1);
1369  ASSERT_EQ(p2.y, 0);
1370  ASSERT_EQ(p2.z, -1);
1371  }
1372 
1373  {
1374  Vector3 p1(1, 2, 3);
1375  Vector3 p2 = 2.0f * p1;
1376  ASSERT_EQ(p2.x, 2);
1377  ASSERT_EQ(p2.y, 4);
1378  ASSERT_EQ(p2.z, 6);
1379  }
1380 
1381  {
1382  Vector3 p1(2, 6, 12);
1383  Vector3 p2 = 12.0f / p1;
1384  ASSERT_EQ(p2.x, 6);
1385  ASSERT_EQ(p2.y, 2);
1386  ASSERT_EQ(p2.z, 1);
1387  }
1388 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [73/202]

impeller::testing::TEST ( GeometryTest  ,
CanUsePointAssignmentOperators   
)

Definition at line 936 of file geometry_unittests.cc.

936  {
937  // Point on RHS
938  {
939  IPoint p(1, 2);
940  p += IPoint(1, 2);
941  ASSERT_EQ(p.x, 2u);
942  ASSERT_EQ(p.y, 4u);
943  }
944 
945  {
946  IPoint p(3, 6);
947  p -= IPoint(1, 2);
948  ASSERT_EQ(p.x, 2u);
949  ASSERT_EQ(p.y, 4u);
950  }
951 
952  {
953  IPoint p(1, 2);
954  p *= IPoint(2, 3);
955  ASSERT_EQ(p.x, 2u);
956  ASSERT_EQ(p.y, 6u);
957  }
958 
959  {
960  IPoint p(2, 6);
961  p /= IPoint(2, 3);
962  ASSERT_EQ(p.x, 1u);
963  ASSERT_EQ(p.y, 2u);
964  }
965 
966  // Size on RHS
967  {
968  IPoint p(1, 2);
969  p += ISize(1, 2);
970  ASSERT_EQ(p.x, 2u);
971  ASSERT_EQ(p.y, 4u);
972  }
973 
974  {
975  IPoint p(3, 6);
976  p -= ISize(1, 2);
977  ASSERT_EQ(p.x, 2u);
978  ASSERT_EQ(p.y, 4u);
979  }
980 
981  {
982  IPoint p(1, 2);
983  p *= ISize(2, 3);
984  ASSERT_EQ(p.x, 2u);
985  ASSERT_EQ(p.y, 6u);
986  }
987 
988  {
989  IPoint p(2, 6);
990  p /= ISize(2, 3);
991  ASSERT_EQ(p.x, 1u);
992  ASSERT_EQ(p.y, 2u);
993  }
994 
995  // Arithmetic type on RHS
996  {
997  IPoint p(1, 2);
998  p *= 3;
999  ASSERT_EQ(p.x, 3u);
1000  ASSERT_EQ(p.y, 6u);
1001  }
1002 
1003  {
1004  IPoint p(3, 6);
1005  p /= 3;
1006  ASSERT_EQ(p.x, 1u);
1007  ASSERT_EQ(p.y, 2u);
1008  }
1009 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [74/202]

impeller::testing::TEST ( GeometryTest  ,
CanUseVector3AssignmentOperators   
)

Definition at line 1238 of file geometry_unittests.cc.

1238  {
1239  {
1240  Vector3 p(1, 2, 4);
1241  p += Vector3(1, 2, 4);
1242  ASSERT_EQ(p.x, 2u);
1243  ASSERT_EQ(p.y, 4u);
1244  ASSERT_EQ(p.z, 8u);
1245  }
1246 
1247  {
1248  Vector3 p(3, 6, 8);
1249  p -= Vector3(1, 2, 3);
1250  ASSERT_EQ(p.x, 2u);
1251  ASSERT_EQ(p.y, 4u);
1252  ASSERT_EQ(p.z, 5u);
1253  }
1254 
1255  {
1256  Vector3 p(1, 2, 3);
1257  p *= Vector3(2, 3, 4);
1258  ASSERT_EQ(p.x, 2u);
1259  ASSERT_EQ(p.y, 6u);
1260  ASSERT_EQ(p.z, 12u);
1261  }
1262 
1263  {
1264  Vector3 p(1, 2, 3);
1265  p *= 2;
1266  ASSERT_EQ(p.x, 2u);
1267  ASSERT_EQ(p.y, 4u);
1268  ASSERT_EQ(p.z, 6u);
1269  }
1270 
1271  {
1272  Vector3 p(2, 6, 12);
1273  p /= Vector3(2, 3, 4);
1274  ASSERT_EQ(p.x, 1u);
1275  ASSERT_EQ(p.y, 2u);
1276  ASSERT_EQ(p.z, 3u);
1277  }
1278 
1279  {
1280  Vector3 p(2, 6, 12);
1281  p /= 2;
1282  ASSERT_EQ(p.x, 1u);
1283  ASSERT_EQ(p.y, 3u);
1284  ASSERT_EQ(p.z, 6u);
1285  }
1286 }

References impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [75/202]

impeller::testing::TEST ( GeometryTest  ,
ColorApplyColorMatrix   
)

Definition at line 1495 of file geometry_unittests.cc.

1495  {
1496  {
1497  ColorMatrix color_matrix = {
1498  1, 1, 1, 1, 1, //
1499  1, 1, 1, 1, 1, //
1500  1, 1, 1, 1, 1, //
1501  1, 1, 1, 1, 1, //
1502  };
1503  auto result = Color::White().ApplyColorMatrix(color_matrix);
1504  auto expected = Color(1, 1, 1, 1);
1505  ASSERT_COLOR_NEAR(result, expected);
1506  }
1507 
1508  {
1509  ColorMatrix color_matrix = {
1510  0.1, 0, 0, 0, 0.01, //
1511  0, 0.2, 0, 0, 0.02, //
1512  0, 0, 0.3, 0, 0.03, //
1513  0, 0, 0, 0.4, 0.04, //
1514  };
1515  auto result = Color::White().ApplyColorMatrix(color_matrix);
1516  auto expected = Color(0.11, 0.22, 0.33, 0.44);
1517  ASSERT_COLOR_NEAR(result, expected);
1518  }
1519 }

References impeller::Color::ApplyColorMatrix(), ASSERT_COLOR_NEAR, and impeller::Color::White().

◆ TEST() [76/202]

impeller::testing::TEST ( GeometryTest  ,
ColorClamp01   
)

Definition at line 1455 of file geometry_unittests.cc.

1455  {
1456  {
1457  Color result = Color(0.5, 0.5, 0.5, 0.5).Clamp01();
1458  Color expected = Color(0.5, 0.5, 0.5, 0.5);
1459  ASSERT_COLOR_NEAR(result, expected);
1460  }
1461 
1462  {
1463  Color result = Color(-1, -1, -1, -1).Clamp01();
1464  Color expected = Color(0, 0, 0, 0);
1465  ASSERT_COLOR_NEAR(result, expected);
1466  }
1467 
1468  {
1469  Color result = Color(2, 2, 2, 2).Clamp01();
1470  Color expected = Color(1, 1, 1, 1);
1471  ASSERT_COLOR_NEAR(result, expected);
1472  }
1473 }

References ASSERT_COLOR_NEAR, and impeller::Color::Clamp01().

◆ TEST() [77/202]

impeller::testing::TEST ( GeometryTest  ,
ColorLerp   
)

Definition at line 1433 of file geometry_unittests.cc.

1433  {
1434  {
1435  Color a(0.0, 0.0, 0.0, 0.0);
1436  Color b(1.0, 1.0, 1.0, 1.0);
1437 
1438  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.5, 0.5, 0.5, 0.5));
1439  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1440  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1441  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.2, 0.2, 0.2, 0.2));
1442  }
1443 
1444  {
1445  Color a(0.2, 0.4, 1.0, 0.5);
1446  Color b(0.4, 1.0, 0.2, 0.3);
1447 
1448  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.5), Color(0.3, 0.7, 0.6, 0.4));
1449  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.0), a);
1450  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 1.0), b);
1451  ASSERT_COLOR_NEAR(Color::Lerp(a, b, 0.2), Color(0.24, 0.52, 0.84, 0.46));
1452  }
1453 }

References ASSERT_COLOR_NEAR, and impeller::Color::Lerp().

◆ TEST() [78/202]

impeller::testing::TEST ( GeometryTest  ,
ColorLinearToSRGB   
)

Definition at line 1521 of file geometry_unittests.cc.

1521  {
1522  {
1523  auto result = Color::White().LinearToSRGB();
1524  auto expected = Color(1, 1, 1, 1);
1525  ASSERT_COLOR_NEAR(result, expected);
1526  }
1527 
1528  {
1529  auto result = Color::BlackTransparent().LinearToSRGB();
1530  auto expected = Color(0, 0, 0, 0);
1531  ASSERT_COLOR_NEAR(result, expected);
1532  }
1533 
1534  {
1535  auto result = Color(0.2, 0.4, 0.6, 0.8).LinearToSRGB();
1536  auto expected = Color(0.484529, 0.665185, 0.797738, 0.8);
1537  ASSERT_COLOR_NEAR(result, expected);
1538  }
1539 }

References ASSERT_COLOR_NEAR, impeller::Color::BlackTransparent(), impeller::Color::LinearToSRGB(), and impeller::Color::White().

◆ TEST() [79/202]

impeller::testing::TEST ( GeometryTest  ,
ColorMakeRGBA8   
)

Definition at line 1475 of file geometry_unittests.cc.

1475  {
1476  {
1477  Color a = Color::MakeRGBA8(0, 0, 0, 0);
1478  Color b = Color::BlackTransparent();
1479  ASSERT_COLOR_NEAR(a, b);
1480  }
1481 
1482  {
1483  Color a = Color::MakeRGBA8(255, 255, 255, 255);
1484  Color b = Color::White();
1485  ASSERT_COLOR_NEAR(a, b);
1486  }
1487 
1488  {
1489  Color a = Color::MakeRGBA8(63, 127, 191, 127);
1490  Color b(0.247059, 0.498039, 0.74902, 0.498039);
1491  ASSERT_COLOR_NEAR(a, b);
1492  }
1493 }

References ASSERT_COLOR_NEAR, impeller::Color::BlackTransparent(), impeller::Color::MakeRGBA8(), and impeller::Color::White().

◆ TEST() [80/202]

impeller::testing::TEST ( GeometryTest  ,
ColorPremultiply   
)

Definition at line 1390 of file geometry_unittests.cc.

1390  {
1391  {
1392  Color a(1.0, 0.5, 0.2, 0.5);
1393  Color premultiplied = a.Premultiply();
1394  Color expected = Color(0.5, 0.25, 0.1, 0.5);
1395  ASSERT_COLOR_NEAR(premultiplied, expected);
1396  }
1397 
1398  {
1399  Color a(0.5, 0.25, 0.1, 0.5);
1400  Color unpremultiplied = a.Unpremultiply();
1401  Color expected = Color(1.0, 0.5, 0.2, 0.5);
1402  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1403  }
1404 
1405  {
1406  Color a(0.5, 0.25, 0.1, 0.0);
1407  Color unpremultiplied = a.Unpremultiply();
1408  Color expected = Color(0.0, 0.0, 0.0, 0.0);
1409  ASSERT_COLOR_NEAR(unpremultiplied, expected);
1410  }
1411 }

References ASSERT_COLOR_NEAR, impeller::Color::Premultiply(), and impeller::Color::Unpremultiply().

◆ TEST() [81/202]

impeller::testing::TEST ( GeometryTest  ,
ColorPrinting   
)

Definition at line 2263 of file geometry_unittests.cc.

2263  {
2264  {
2265  std::stringstream stream;
2266  Color m;
2267  stream << m;
2268  ASSERT_EQ(stream.str(), "(0, 0, 0, 0)");
2269  }
2270 
2271  {
2272  std::stringstream stream;
2273  Color m(1, 2, 3, 4);
2274  stream << m;
2275  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
2276  }
2277 }

◆ TEST() [82/202]

impeller::testing::TEST ( GeometryTest  ,
ColorR8G8B8A8   
)

Definition at line 1413 of file geometry_unittests.cc.

1413  {
1414  {
1415  Color a(1.0, 0.5, 0.2, 0.5);
1416  std::array<uint8_t, 4> expected = {255, 128, 51, 128};
1417  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1418  }
1419 
1420  {
1421  Color a(0.0, 0.0, 0.0, 0.0);
1422  std::array<uint8_t, 4> expected = {0, 0, 0, 0};
1423  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1424  }
1425 
1426  {
1427  Color a(1.0, 1.0, 1.0, 1.0);
1428  std::array<uint8_t, 4> expected = {255, 255, 255, 255};
1429  ASSERT_ARRAY_4_NEAR(a.ToR8G8B8A8(), expected);
1430  }
1431 }

References ASSERT_ARRAY_4_NEAR, and impeller::Color::ToR8G8B8A8().

◆ TEST() [83/202]

impeller::testing::TEST ( GeometryTest  ,
ColorSRGBToLinear   
)

Definition at line 1541 of file geometry_unittests.cc.

1541  {
1542  {
1543  auto result = Color::White().SRGBToLinear();
1544  auto expected = Color(1, 1, 1, 1);
1545  ASSERT_COLOR_NEAR(result, expected);
1546  }
1547 
1548  {
1549  auto result = Color::BlackTransparent().SRGBToLinear();
1550  auto expected = Color(0, 0, 0, 0);
1551  ASSERT_COLOR_NEAR(result, expected);
1552  }
1553 
1554  {
1555  auto result = Color(0.2, 0.4, 0.6, 0.8).SRGBToLinear();
1556  auto expected = Color(0.0331048, 0.132868, 0.318547, 0.8);
1557  ASSERT_COLOR_NEAR(result, expected);
1558  }
1559 }

References ASSERT_COLOR_NEAR, impeller::Color::BlackTransparent(), impeller::Color::SRGBToLinear(), and impeller::Color::White().

◆ TEST() [84/202]

impeller::testing::TEST ( GeometryTest  ,
CubicPathComponentPolylineDoesNotIncludePointOne   
)

Definition at line 2013 of file geometry_unittests.cc.

2013  {
2014  CubicPathComponent component({10, 10}, {20, 35}, {35, 20}, {40, 40});
2015  auto polyline = component.CreatePolyline(1.0f);
2016  ASSERT_NE(polyline.front().x, 10);
2017  ASSERT_NE(polyline.front().y, 10);
2018  ASSERT_EQ(polyline.back().x, 40);
2019  ASSERT_EQ(polyline.back().y, 40);
2020 }

References impeller::CubicPathComponent::CreatePolyline().

◆ TEST() [85/202]

impeller::testing::TEST ( GeometryTest  ,
DeterminantTest   
)

Definition at line 118 of file geometry_unittests.cc.

118  {
119  auto matrix = Matrix{3, 4, 14, 155, 2, 1, 3, 4, 2, 3, 2, 1, 1, 2, 4, 2};
120  ASSERT_EQ(matrix.GetDeterminant(), -1889);
121 }

◆ TEST() [86/202]

impeller::testing::TEST ( GeometryTest  ,
EmptyPath   
)

Definition at line 594 of file geometry_unittests.cc.

594  {
595  auto path = PathBuilder{}.TakePath();
596  ASSERT_EQ(path.GetComponentCount(), 1u);
597 
598  ContourComponent c;
599  path.GetContourComponentAtIndex(0, c);
600  ASSERT_POINT_NEAR(c.destination, Point());
601 
602  Path::Polyline polyline = path.CreatePolyline(1.0f);
603  ASSERT_TRUE(polyline.points.empty());
604  ASSERT_TRUE(polyline.contours.empty());
605 }

References ASSERT_POINT_NEAR, impeller::Path::Polyline::contours, impeller::ContourComponent::destination, impeller::Path::Polyline::points, and impeller::PathBuilder::TakePath().

◆ TEST() [87/202]

impeller::testing::TEST ( GeometryTest  ,
ExtremaOfCubicPathComponentIsCorrect   
)

Definition at line 688 of file geometry_unittests.cc.

688  {
689  CubicPathComponent cubic{{11.769268, 252.883148},
690  {-6.2857933, 204.356461},
691  {-4.53997231, 156.552902},
692  {17.0067291, 109.472488}};
693  auto points = cubic.Extrema();
694  ASSERT_EQ(points.size(), static_cast<size_t>(3));
695  ASSERT_POINT_NEAR(points[2], cubic.Solve(0.455916));
696 }

References ASSERT_POINT_NEAR, and impeller::CubicPathComponent::Extrema().

◆ TEST() [88/202]

impeller::testing::TEST ( GeometryTest  ,
Gradient   
)

Definition at line 2285 of file geometry_unittests.cc.

2285  {
2286  {
2287  // Simple 2 color gradient produces color buffer containing exactly those
2288  // values.
2289  std::vector<Color> colors = {Color::Red(), Color::Blue()};
2290  std::vector<Scalar> stops = {0.0, 1.0};
2291 
2292  auto gradient = CreateGradientBuffer(colors, stops);
2293 
2294  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
2295  ASSERT_EQ(gradient.texture_size, 2u);
2296  }
2297 
2298  {
2299  // Gradient with duplicate stops does not create an empty texture.
2300  std::vector<Color> colors = {Color::Red(), Color::Yellow(), Color::Black(),
2301  Color::Blue()};
2302  std::vector<Scalar> stops = {0.0, 0.25, 0.25, 1.0};
2303 
2304  auto gradient = CreateGradientBuffer(colors, stops);
2305  ASSERT_EQ(gradient.texture_size, 5u);
2306  }
2307 
2308  {
2309  // Simple N color gradient produces color buffer containing exactly those
2310  // values.
2311  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green(),
2312  Color::White()};
2313  std::vector<Scalar> stops = {0.0, 0.33, 0.66, 1.0};
2314 
2315  auto gradient = CreateGradientBuffer(colors, stops);
2316 
2317  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, colors);
2318  ASSERT_EQ(gradient.texture_size, 4u);
2319  }
2320 
2321  {
2322  // Gradient with color stops will lerp and scale buffer.
2323  std::vector<Color> colors = {Color::Red(), Color::Blue(), Color::Green()};
2324  std::vector<Scalar> stops = {0.0, 0.25, 1.0};
2325 
2326  auto gradient = CreateGradientBuffer(colors, stops);
2327 
2328  std::vector<Color> lerped_colors = {
2329  Color::Red(),
2330  Color::Blue(),
2331  Color::Lerp(Color::Blue(), Color::Green(), 0.3333),
2332  Color::Lerp(Color::Blue(), Color::Green(), 0.6666),
2333  Color::Green(),
2334  };
2335  ASSERT_COLOR_BUFFER_NEAR(gradient.color_bytes, lerped_colors);
2336  ASSERT_EQ(gradient.texture_size, 5u);
2337  }
2338 
2339  {
2340  // Gradient size is capped at 1024.
2341  std::vector<Color> colors = {};
2342  std::vector<Scalar> stops = {};
2343  for (auto i = 0u; i < 1025; i++) {
2344  colors.push_back(Color::Blue());
2345  stops.push_back(i / 1025.0);
2346  }
2347 
2348  auto gradient = CreateGradientBuffer(colors, stops);
2349 
2350  ASSERT_EQ(gradient.texture_size, 1024u);
2351  ASSERT_EQ(gradient.color_bytes.size(), 1024u * 4);
2352  }
2353 }

References ASSERT_COLOR_BUFFER_NEAR, impeller::Color::Black(), impeller::Color::Blue(), impeller::CreateGradientBuffer(), impeller::Color::Green(), impeller::Color::Lerp(), impeller::Color::Red(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST() [89/202]

impeller::testing::TEST ( GeometryTest  ,
HalfConversions   
)

Definition at line 2355 of file geometry_unittests.cc.

2355  {
2356 #ifdef FML_OS_WIN
2357  GTEST_SKIP() << "Half-precision floats (IEEE 754) are not portable and "
2358  "unavailable on Windows.";
2359 #else
2360  ASSERT_EQ(ScalarToHalf(0.0), 0.0f16);
2361  ASSERT_EQ(ScalarToHalf(0.05), 0.05f16);
2362  ASSERT_EQ(ScalarToHalf(2.43), 2.43f16);
2363  ASSERT_EQ(ScalarToHalf(-1.45), -1.45f16);
2364 
2365  // 65504 is the largest possible half.
2366  ASSERT_EQ(ScalarToHalf(65504.0f), 65504.0f16);
2367  ASSERT_EQ(ScalarToHalf(65504.0f + 1), 65504.0f16);
2368 
2369  // Colors
2370  ASSERT_EQ(HalfVector4(Color::Red()),
2371  HalfVector4(1.0f16, 0.0f16, 0.0f16, 1.0f16));
2372  ASSERT_EQ(HalfVector4(Color::Green()),
2373  HalfVector4(0.0f16, 1.0f16, 0.0f16, 1.0f16));
2374  ASSERT_EQ(HalfVector4(Color::Blue()),
2375  HalfVector4(0.0f16, 0.0f16, 1.0f16, 1.0f16));
2376  ASSERT_EQ(HalfVector4(Color::Black().WithAlpha(0)),
2377  HalfVector4(0.0f16, 0.0f16, 0.0f16, 0.0f16));
2378 
2379  ASSERT_EQ(HalfVector3(Vector3(4.0, 6.0, -1.0)),
2380  HalfVector3(4.0f16, 6.0f16, -1.0f16));
2381  ASSERT_EQ(HalfVector2(Vector2(4.0, 6.0)), HalfVector2(4.0f16, 6.0f16));
2382 
2383  ASSERT_EQ(Half(0.5f), Half(0.5f16));
2384  ASSERT_EQ(Half(0.5), Half(0.5f16));
2385  ASSERT_EQ(Half(5), Half(5.0f16));
2386 #endif // FML_OS_WIN
2387 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Color::Green(), impeller::Color::Red(), and impeller::ScalarToHalf().

◆ TEST() [90/202]

impeller::testing::TEST ( GeometryTest  ,
InvertMatrix   
)

Definition at line 123 of file geometry_unittests.cc.

123  {
124  auto inverted = Matrix{10, -9, -12, 8, //
125  7, -12, 11, 22, //
126  -10, 10, 3, 6, //
127  -2, 22, 2, 1}
128  .Invert();
129 
130  auto result = Matrix{
131  438.0 / 85123.0, 1751.0 / 85123.0, -7783.0 / 85123.0, 4672.0 / 85123.0,
132  393.0 / 85123.0, -178.0 / 85123.0, -570.0 / 85123.0, 4192 / 85123.0,
133  -5230.0 / 85123.0, 2802.0 / 85123.0, -3461.0 / 85123.0, 962.0 / 85123.0,
134  2690.0 / 85123.0, 1814.0 / 85123.0, 3896.0 / 85123.0, 319.0 / 85123.0};
135 
136  ASSERT_MATRIX_NEAR(inverted, result);
137 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::Invert().

◆ TEST() [91/202]

impeller::testing::TEST ( GeometryTest  ,
InvertMultMatrix   
)

Definition at line 78 of file geometry_unittests.cc.

78  {
79  {
80  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
81  auto invert = rotation.Invert();
82  auto expect = Matrix{0.707, -0.707, 0, 0, //
83  0.707, 0.707, 0, 0, //
84  0, 0, 1, 0, //
85  0, 0, 0, 1};
86  ASSERT_MATRIX_NEAR(invert, expect);
87  }
88  {
89  auto scale = Matrix::MakeScale(Vector2{2, 4});
90  auto invert = scale.Invert();
91  auto expect = Matrix{0.5, 0, 0, 0, //
92  0, 0.25, 0, 0, //
93  0, 0, 1, 0, //
94  0, 0, 0, 1};
95  ASSERT_MATRIX_NEAR(invert, expect);
96  }
97 }

References ASSERT_MATRIX_NEAR, impeller::Matrix::Invert(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [92/202]

impeller::testing::TEST ( GeometryTest  ,
MakeColumn   
)

Definition at line 41 of file geometry_unittests.cc.

41  {
42  auto matrix = Matrix::MakeColumn(1, 2, 3, 4, //
43  5, 6, 7, 8, //
44  9, 10, 11, 12, //
45  13, 14, 15, 16);
46 
47  auto expect = Matrix{1, 2, 3, 4, //
48  5, 6, 7, 8, //
49  9, 10, 11, 12, //
50  13, 14, 15, 16};
51 
52  ASSERT_TRUE(matrix == expect);
53 }

References impeller::Matrix::MakeColumn().

◆ TEST() [93/202]

impeller::testing::TEST ( GeometryTest  ,
MakeRow   
)

Definition at line 55 of file geometry_unittests.cc.

55  {
56  auto matrix = Matrix::MakeRow(1, 2, 3, 4, //
57  5, 6, 7, 8, //
58  9, 10, 11, 12, //
59  13, 14, 15, 16);
60 
61  auto expect = Matrix{1, 5, 9, 13, //
62  2, 6, 10, 14, //
63  3, 7, 11, 15, //
64  4, 8, 12, 16};
65 
66  ASSERT_TRUE(matrix == expect);
67 }

References impeller::Matrix::MakeRow().

◆ TEST() [94/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixBasis   
)

Definition at line 99 of file geometry_unittests.cc.

99  {
100  auto matrix = Matrix{1, 2, 3, 4, //
101  5, 6, 7, 8, //
102  9, 10, 11, 12, //
103  13, 14, 15, 16};
104  auto basis = matrix.Basis();
105  auto expect = Matrix{1, 2, 3, 0, //
106  5, 6, 7, 0, //
107  9, 10, 11, 0, //
108  0, 0, 0, 1};
109  ASSERT_MATRIX_NEAR(basis, expect);
110 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::Basis().

◆ TEST() [95/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetBasisVectors   
)

Definition at line 408 of file geometry_unittests.cc.

408  {
409  {
410  auto m = Matrix();
411  Vector3 x = m.GetBasisX();
412  Vector3 y = m.GetBasisY();
413  Vector3 z = m.GetBasisZ();
414  ASSERT_VECTOR3_NEAR(x, Vector3(1, 0, 0));
415  ASSERT_VECTOR3_NEAR(y, Vector3(0, 1, 0));
416  ASSERT_VECTOR3_NEAR(z, Vector3(0, 0, 1));
417  }
418 
419  {
420  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
421  Matrix::MakeRotationX(Radians{kPiOver2}) *
422  Matrix::MakeScale(Vector3(2, 3, 4));
423  Vector3 x = m.GetBasisX();
424  Vector3 y = m.GetBasisY();
425  Vector3 z = m.GetBasisZ();
426  ASSERT_VECTOR3_NEAR(x, Vector3(0, 2, 0));
427  ASSERT_VECTOR3_NEAR(y, Vector3(0, 0, 3));
428  ASSERT_VECTOR3_NEAR(z, Vector3(4, 0, 0));
429  }
430 }

References ASSERT_VECTOR3_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [96/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetDirectionScale   
)

Definition at line 432 of file geometry_unittests.cc.

432  {
433  {
434  auto m = Matrix();
435  Scalar result = m.GetDirectionScale(Vector3{1, 0, 0});
436  ASSERT_FLOAT_EQ(result, 1);
437  }
438 
439  {
440  auto m = Matrix::MakeRotationX(Degrees{10}) *
441  Matrix::MakeRotationY(Degrees{83}) *
442  Matrix::MakeRotationZ(Degrees{172});
443  Scalar result = m.GetDirectionScale(Vector3{0, 1, 0});
444  ASSERT_FLOAT_EQ(result, 1);
445  }
446 
447  {
448  auto m = Matrix::MakeRotationZ(Radians{kPiOver2}) *
449  Matrix::MakeScale(Vector3(3, 4, 5));
450  Scalar result = m.GetDirectionScale(Vector3{2, 0, 0});
451  ASSERT_FLOAT_EQ(result, 8);
452  }
453 }

References impeller::Matrix::GetDirectionScale(), impeller::kPiOver2, impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeScale().

◆ TEST() [97/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetMaxBasisLength   
)

Definition at line 330 of file geometry_unittests.cc.

330  {
331  {
332  auto m = Matrix::MakeScale({3, 1, 1});
333  ASSERT_EQ(m.GetMaxBasisLength(), 3);
334 
335  m = m * Matrix::MakeSkew(0, 4);
336  ASSERT_EQ(m.GetMaxBasisLength(), 5);
337  }
338 
339  {
340  auto m = Matrix::MakeScale({-3, 4, 2});
341  ASSERT_EQ(m.GetMaxBasisLength(), 4);
342  }
343 }

References impeller::Matrix::MakeScale(), and impeller::Matrix::MakeSkew().

◆ TEST() [98/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixGetMaxBasisLengthXY   
)

Definition at line 345 of file geometry_unittests.cc.

345  {
346  {
347  auto m = Matrix::MakeScale({3, 1, 1});
348  ASSERT_EQ(m.GetMaxBasisLengthXY(), 3);
349 
350  m = m * Matrix::MakeSkew(0, 4);
351  ASSERT_EQ(m.GetMaxBasisLengthXY(), 5);
352  }
353 
354  {
355  auto m = Matrix::MakeScale({-3, 4, 7});
356  ASSERT_EQ(m.GetMaxBasisLengthXY(), 4);
357  }
358 }

References impeller::Matrix::MakeScale(), and impeller::Matrix::MakeSkew().

◆ TEST() [99/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixIsAligned   
)

Definition at line 455 of file geometry_unittests.cc.

455  {
456  {
457  auto m = Matrix::MakeTranslation({1, 2, 3});
458  bool result = m.IsAligned();
459  ASSERT_TRUE(result);
460  }
461 
462  {
463  auto m = Matrix::MakeRotationZ(Degrees{123});
464  bool result = m.IsAligned();
465  ASSERT_FALSE(result);
466  }
467 }

References impeller::Matrix::IsAligned(), impeller::Matrix::MakeRotationZ(), and impeller::Matrix::MakeTranslation().

◆ TEST() [100/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixLookAt   
)

Definition at line 495 of file geometry_unittests.cc.

495  {
496  {
497  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
498  Vector3(0, 1, 0));
499  auto expected = Matrix{
500  1, 0, 0, 0, //
501  0, 1, 0, 0, //
502  0, 0, 1, 0, //
503  0, 0, 1, 1, //
504  };
505  ASSERT_MATRIX_NEAR(m, expected);
506  }
507 
508  // Sideways tilt.
509  {
510  auto m = Matrix::MakeLookAt(Vector3(0, 0, -1), Vector3(0, 0, 1),
511  Vector3(1, 1, 0).Normalize());
512 
513  // clang-format off
514  auto expected = Matrix{
515  k1OverSqrt2, k1OverSqrt2, 0, 0,
516  -k1OverSqrt2, k1OverSqrt2, 0, 0,
517  0, 0, 1, 0,
518  0, 0, 1, 1,
519  };
520  // clang-format on
521  ASSERT_MATRIX_NEAR(m, expected);
522  }
523 
524  // Half way between +x and -y, yaw 90
525  {
526  auto m =
527  Matrix::MakeLookAt(Vector3(), Vector3(10, -10, 0), Vector3(0, 0, -1));
528 
529  // clang-format off
530  auto expected = Matrix{
531  -k1OverSqrt2, 0, k1OverSqrt2, 0,
532  -k1OverSqrt2, 0, -k1OverSqrt2, 0,
533  0, -1, 0, 0,
534  0, 0, 0, 1,
535  };
536  // clang-format on
537  ASSERT_MATRIX_NEAR(m, expected);
538  }
539 }

References ASSERT_MATRIX_NEAR, impeller::k1OverSqrt2, and impeller::Matrix::MakeLookAt().

◆ TEST() [101/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeOrthographic   
)

Definition at line 360 of file geometry_unittests.cc.

360  {
361  {
362  auto m = Matrix::MakeOrthographic(Size(100, 200));
363  auto expect = Matrix{
364  0.02, 0, 0, 0, //
365  0, -0.01, 0, 0, //
366  0, 0, 0, 0, //
367  -1, 1, 0.5, 1, //
368  };
369  ASSERT_MATRIX_NEAR(m, expect);
370  }
371 
372  {
373  auto m = Matrix::MakeOrthographic(Size(400, 100));
374  auto expect = Matrix{
375  0.005, 0, 0, 0, //
376  0, -0.02, 0, 0, //
377  0, 0, 0, 0, //
378  -1, 1, 0.5, 1, //
379  };
380  ASSERT_MATRIX_NEAR(m, expect);
381  }
382 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::MakeOrthographic().

◆ TEST() [102/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakePerspective   
)

Definition at line 384 of file geometry_unittests.cc.

384  {
385  {
386  auto m = Matrix::MakePerspective(Degrees(60), Size(100, 200), 1, 10);
387  auto expect = Matrix{
388  3.4641, 0, 0, 0, //
389  0, 1.73205, 0, 0, //
390  0, 0, 1.11111, 1, //
391  0, 0, -1.11111, 0, //
392  };
393  ASSERT_MATRIX_NEAR(m, expect);
394  }
395 
396  {
397  auto m = Matrix::MakePerspective(Radians(1), 2, 10, 20);
398  auto expect = Matrix{
399  0.915244, 0, 0, 0, //
400  0, 1.83049, 0, 0, //
401  0, 0, 2, 1, //
402  0, 0, -20, 0, //
403  };
404  ASSERT_MATRIX_NEAR(m, expect);
405  }
406 }

References ASSERT_MATRIX_NEAR, and impeller::Matrix::MakePerspective().

◆ TEST() [103/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixMakeRotationFromQuaternion   
)

Definition at line 275 of file geometry_unittests.cc.

275  {
276  {
277  auto matrix = Matrix::MakeRotation(Quaternion({1, 0, 0}, kPiOver2));
278  auto expected = Matrix::MakeRotationX(Radians(kPiOver2));
279  ASSERT_MATRIX_NEAR(matrix, expected);
280  }
281 
282  {
283  auto matrix = Matrix::MakeRotation(Quaternion({0, 1, 0}, kPiOver2));
284  auto expected = Matrix::MakeRotationY(Radians(kPiOver2));
285  ASSERT_MATRIX_NEAR(matrix, expected);
286  }
287 
288  {
289  auto matrix = Matrix::MakeRotation(Quaternion({0, 0, 1}, kPiOver2));
290  auto expected = Matrix::MakeRotationZ(Radians(kPiOver2));
291  ASSERT_MATRIX_NEAR(matrix, expected);
292  }
293 }

References ASSERT_MATRIX_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotation(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), and impeller::Matrix::MakeRotationZ().

◆ TEST() [104/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixPrinting   
)

Definition at line 2188 of file geometry_unittests.cc.

2188  {
2189  {
2190  std::stringstream stream;
2191  Matrix m;
2192  stream << m;
2193  ASSERT_EQ(stream.str(), R"((
2194  1.000000, 0.000000, 0.000000, 0.000000,
2195  0.000000, 1.000000, 0.000000, 0.000000,
2196  0.000000, 0.000000, 1.000000, 0.000000,
2197  0.000000, 0.000000, 0.000000, 1.000000,
2198 ))");
2199  }
2200 
2201  {
2202  std::stringstream stream;
2203  Matrix m = Matrix::MakeTranslation(Vector3(10, 20, 30));
2204  stream << m;
2205 
2206  ASSERT_EQ(stream.str(), R"((
2207  1.000000, 0.000000, 0.000000, 10.000000,
2208  0.000000, 1.000000, 0.000000, 20.000000,
2209  0.000000, 0.000000, 1.000000, 30.000000,
2210  0.000000, 0.000000, 0.000000, 1.000000,
2211 ))");
2212  }
2213 }

References impeller::Matrix::MakeTranslation().

◆ TEST() [105/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixTransformDirection   
)

Definition at line 295 of file geometry_unittests.cc.

295  {
296  {
297  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
298  Matrix::MakeRotationZ(Radians{kPiOver2}) *
299  Matrix::MakeScale({2.0, 2.0, 2.0});
300  auto vector = Vector4(10, 20, 30, 2);
301 
302  Vector4 result = matrix.TransformDirection(vector);
303  auto expected = Vector4(-40, 20, 60, 2);
304  ASSERT_VECTOR4_NEAR(result, expected);
305  }
306 
307  {
308  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
309  Matrix::MakeRotationZ(Radians{kPiOver2}) *
310  Matrix::MakeScale({2.0, 2.0, 2.0});
311  auto vector = Vector3(10, 20, 30);
312 
313  Vector3 result = matrix.TransformDirection(vector);
314  auto expected = Vector3(-40, 20, 60);
315  ASSERT_VECTOR3_NEAR(result, expected);
316  }
317 
318  {
319  auto matrix = Matrix::MakeTranslation({0, -0.4, 100}) *
320  Matrix::MakeRotationZ(Radians{kPiOver2}) *
321  Matrix::MakeScale({2.0, 2.0, 2.0});
322  auto vector = Point(10, 20);
323 
324  Point result = matrix.TransformDirection(vector);
325  auto expected = Point(-40, 20);
326  ASSERT_POINT_NEAR(result, expected);
327  }
328 }

References ASSERT_POINT_NEAR, ASSERT_VECTOR3_NEAR, ASSERT_VECTOR4_NEAR, impeller::kPiOver2, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [106/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixTranslationScaleOnly   
)

Definition at line 469 of file geometry_unittests.cc.

469  {
470  {
471  auto m = Matrix();
472  bool result = m.IsTranslationScaleOnly();
473  ASSERT_TRUE(result);
474  }
475 
476  {
477  auto m = Matrix::MakeScale(Vector3(2, 3, 4));
478  bool result = m.IsTranslationScaleOnly();
479  ASSERT_TRUE(result);
480  }
481 
482  {
483  auto m = Matrix::MakeTranslation(Vector3(2, 3, 4));
484  bool result = m.IsTranslationScaleOnly();
485  ASSERT_TRUE(result);
486  }
487 
488  {
489  auto m = Matrix::MakeRotationZ(Degrees(10));
490  bool result = m.IsTranslationScaleOnly();
491  ASSERT_FALSE(result);
492  }
493 }

References impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [107/202]

impeller::testing::TEST ( GeometryTest  ,
MatrixVectorMultiplication   
)

Definition at line 210 of file geometry_unittests.cc.

210  {
211  {
212  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
213  Matrix::MakeRotationZ(Radians{kPiOver2}) *
214  Matrix::MakeScale({2.0, 2.0, 2.0});
215  auto vector = Vector4(10, 20, 30, 2);
216 
217  Vector4 result = matrix * vector;
218  auto expected = Vector4(160, 220, 260, 2);
219  ASSERT_VECTOR4_NEAR(result, expected);
220  }
221 
222  {
223  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
224  Matrix::MakeRotationZ(Radians{kPiOver2}) *
225  Matrix::MakeScale({2.0, 2.0, 2.0});
226  auto vector = Vector3(10, 20, 30);
227 
228  Vector3 result = matrix * vector;
229  auto expected = Vector3(60, 120, 160);
230  ASSERT_VECTOR3_NEAR(result, expected);
231  }
232 
233  {
234  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
235  Matrix::MakeRotationZ(Radians{kPiOver2}) *
236  Matrix::MakeScale({2.0, 2.0, 2.0});
237  auto vector = Point(10, 20);
238 
239  Point result = matrix * vector;
240  auto expected = Point(60, 120);
241  ASSERT_POINT_NEAR(result, expected);
242  }
243 
244  // Matrix Vector ops should respect perspective transforms.
245  {
246  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
247  auto vector = Vector3(3, 3, -3);
248 
249  Vector3 result = matrix * vector;
250  auto expected = Vector3(-1, -1, 1.3468);
251  ASSERT_VECTOR3_NEAR(result, expected);
252  }
253 
254  {
255  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100) *
256  Matrix::MakeTranslation(Vector3(0, 0, -3));
257  auto point = Point(3, 3);
258 
259  Point result = matrix * point;
260  auto expected = Point(-1, -1);
261  ASSERT_POINT_NEAR(result, expected);
262  }
263 
264  // Resolves to 0 on perspective singularity.
265  {
266  auto matrix = Matrix::MakePerspective(Radians(kPiOver2), 1, 1, 100);
267  auto point = Point(3, 3);
268 
269  Point result = matrix * point;
270  auto expected = Point(0, 0);
271  ASSERT_POINT_NEAR(result, expected);
272  }
273 }

References ASSERT_POINT_NEAR, ASSERT_VECTOR3_NEAR, ASSERT_VECTOR4_NEAR, impeller::kPiOver2, impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [108/202]

impeller::testing::TEST ( GeometryTest  ,
MutliplicationMatrix   
)

Definition at line 112 of file geometry_unittests.cc.

112  {
113  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
114  auto invert = rotation.Invert();
115  ASSERT_MATRIX_NEAR(rotation * invert, Matrix{});
116 }

References ASSERT_MATRIX_NEAR, impeller::Matrix::Invert(), impeller::kPiOver4, and impeller::Matrix::MakeRotationZ().

◆ TEST() [109/202]

impeller::testing::TEST ( GeometryTest  ,
PathAddRectPolylineHasCorrectContourData   
)

Definition at line 2143 of file geometry_unittests.cc.

2143  {
2144  Path::Polyline polyline = PathBuilder{}
2145  .AddRect(Rect::MakeLTRB(50, 60, 70, 80))
2146  .TakePath()
2147  .CreatePolyline(1.0f);
2148  ASSERT_EQ(polyline.contours.size(), 1u);
2149  ASSERT_TRUE(polyline.contours[0].is_closed);
2150  ASSERT_EQ(polyline.contours[0].start_index, 0u);
2151  ASSERT_EQ(polyline.points.size(), 5u);
2152  ASSERT_EQ(polyline.points[0], Point(50, 60));
2153  ASSERT_EQ(polyline.points[1], Point(70, 60));
2154  ASSERT_EQ(polyline.points[2], Point(70, 80));
2155  ASSERT_EQ(polyline.points[3], Point(50, 80));
2156  ASSERT_EQ(polyline.points[4], Point(50, 60));
2157 }

References impeller::PathBuilder::AddRect(), impeller::Path::Polyline::contours, impeller::Path::CreatePolyline(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Path::Polyline::points, and impeller::PathBuilder::TakePath().

◆ TEST() [110/202]

impeller::testing::TEST ( GeometryTest  ,
PathBuilderSetsCorrectContourPropertiesForAddCommands   
)

Definition at line 2041 of file geometry_unittests.cc.

2041  {
2042  // Closed shapes.
2043  {
2044  Path path = PathBuilder{}.AddCircle({100, 100}, 50).TakePath();
2045  ContourComponent contour;
2046  path.GetContourComponentAtIndex(0, contour);
2047  ASSERT_POINT_NEAR(contour.destination, Point(100, 50));
2048  ASSERT_TRUE(contour.is_closed);
2049  }
2050 
2051  {
2052  Path path = PathBuilder{}.AddOval(Rect(100, 100, 100, 100)).TakePath();
2053  ContourComponent contour;
2054  path.GetContourComponentAtIndex(0, contour);
2055  ASSERT_POINT_NEAR(contour.destination, Point(150, 100));
2056  ASSERT_TRUE(contour.is_closed);
2057  }
2058 
2059  {
2060  Path path = PathBuilder{}.AddRect(Rect(100, 100, 100, 100)).TakePath();
2061  ContourComponent contour;
2062  path.GetContourComponentAtIndex(0, contour);
2063  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
2064  ASSERT_TRUE(contour.is_closed);
2065  }
2066 
2067  {
2068  Path path =
2069  PathBuilder{}.AddRoundedRect(Rect(100, 100, 100, 100), 10).TakePath();
2070  ContourComponent contour;
2071  path.GetContourComponentAtIndex(0, contour);
2072  ASSERT_POINT_NEAR(contour.destination, Point(110, 100));
2073  ASSERT_TRUE(contour.is_closed);
2074  }
2075 
2076  // Open shapes.
2077  {
2078  Point p(100, 100);
2079  Path path = PathBuilder{}.AddLine(p, {200, 100}).TakePath();
2080  ContourComponent contour;
2081  path.GetContourComponentAtIndex(0, contour);
2082  ASSERT_POINT_NEAR(contour.destination, p);
2083  ASSERT_FALSE(contour.is_closed);
2084  }
2085 
2086  {
2087  Path path =
2088  PathBuilder{}
2089  .AddCubicCurve({100, 100}, {100, 50}, {100, 150}, {200, 100})
2090  .TakePath();
2091  ContourComponent contour;
2092  path.GetContourComponentAtIndex(0, contour);
2093  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
2094  ASSERT_FALSE(contour.is_closed);
2095  }
2096 
2097  {
2098  Path path = PathBuilder{}
2099  .AddQuadraticCurve({100, 100}, {100, 50}, {200, 100})
2100  .TakePath();
2101  ContourComponent contour;
2102  path.GetContourComponentAtIndex(0, contour);
2103  ASSERT_POINT_NEAR(contour.destination, Point(100, 100));
2104  ASSERT_FALSE(contour.is_closed);
2105  }
2106 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddOval(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::AddRect(), impeller::PathBuilder::AddRoundedRect(), ASSERT_POINT_NEAR, impeller::ContourComponent::destination, impeller::Path::GetContourComponentAtIndex(), impeller::ContourComponent::is_closed, and impeller::PathBuilder::TakePath().

◆ TEST() [111/202]

impeller::testing::TEST ( GeometryTest  ,
PathBuilderWillComputeBounds   
)

Definition at line 2425 of file geometry_unittests.cc.

2425  {
2426  PathBuilder builder;
2427  auto path_1 = builder.AddLine({0, 0}, {1, 1}).TakePath();
2428 
2429  ASSERT_EQ(path_1.GetBoundingBox().value(), Rect::MakeLTRB(0, 0, 1, 1));
2430 
2431  auto path_2 = builder.AddLine({-1, -1}, {1, 1}).TakePath();
2432 
2433  // Verify that PathBuilder recomputes the bounds.
2434  ASSERT_EQ(path_2.GetBoundingBox().value(), Rect::MakeLTRB(-1, -1, 1, 1));
2435 
2436  // PathBuilder can set the bounds to whatever it wants
2437  auto path_3 = builder.AddLine({0, 0}, {1, 1})
2438  .SetBounds(Rect::MakeLTRB(0, 0, 100, 100))
2439  .TakePath();
2440 
2441  ASSERT_EQ(path_3.GetBoundingBox().value(), Rect::MakeLTRB(0, 0, 100, 100));
2442 }

References impeller::PathBuilder::AddLine(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST() [112/202]

impeller::testing::TEST ( GeometryTest  ,
PathCreatePolyLineDoesNotDuplicatePoints   
)

Definition at line 2022 of file geometry_unittests.cc.

2022  {
2023  PathBuilder builder;
2024  builder.MoveTo({10, 10});
2025  builder.LineTo({20, 20});
2026  builder.LineTo({30, 30});
2027  builder.MoveTo({40, 40});
2028  builder.LineTo({50, 50});
2029 
2030  auto polyline = builder.TakePath().CreatePolyline(1.0f);
2031 
2032  ASSERT_EQ(polyline.contours.size(), 2u);
2033  ASSERT_EQ(polyline.points.size(), 5u);
2034  ASSERT_EQ(polyline.points[0].x, 10);
2035  ASSERT_EQ(polyline.points[1].x, 20);
2036  ASSERT_EQ(polyline.points[2].x, 30);
2037  ASSERT_EQ(polyline.points[3].x, 40);
2038  ASSERT_EQ(polyline.points[4].x, 50);
2039 }

References impeller::Path::CreatePolyline(), impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), and impeller::PathBuilder::TakePath().

◆ TEST() [113/202]

impeller::testing::TEST ( GeometryTest  ,
PathCreatePolylineGeneratesCorrectContourData   
)

Definition at line 2108 of file geometry_unittests.cc.

2108  {
2109  Path::Polyline polyline = PathBuilder{}
2110  .AddLine({100, 100}, {200, 100})
2111  .MoveTo({100, 200})
2112  .LineTo({150, 250})
2113  .LineTo({200, 200})
2114  .Close()
2115  .TakePath()
2116  .CreatePolyline(1.0f);
2117  ASSERT_EQ(polyline.points.size(), 6u);
2118  ASSERT_EQ(polyline.contours.size(), 2u);
2119  ASSERT_EQ(polyline.contours[0].is_closed, false);
2120  ASSERT_EQ(polyline.contours[0].start_index, 0u);
2121  ASSERT_EQ(polyline.contours[1].is_closed, true);
2122  ASSERT_EQ(polyline.contours[1].start_index, 2u);
2123 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::Path::Polyline::contours, impeller::LineTo(), impeller::MoveTo(), and impeller::Path::Polyline::points.

◆ TEST() [114/202]

impeller::testing::TEST ( GeometryTest  ,
PathGetBoundingBoxForCubicWithNoDerivativeRootsIsCorrect   
)

Definition at line 698 of file geometry_unittests.cc.

698  {
699  PathBuilder builder;
700  // Straight diagonal line.
701  builder.AddCubicCurve({0, 1}, {2, 3}, {4, 5}, {6, 7});
702  auto path = builder.TakePath();
703  auto actual = path.GetBoundingBox();
704  auto expected = Rect::MakeLTRB(0, 1, 6, 7);
705  ASSERT_TRUE(actual.has_value());
706  ASSERT_RECT_NEAR(actual.value(), expected);
707 }

References impeller::PathBuilder::AddCubicCurve(), ASSERT_RECT_NEAR, impeller::Path::GetBoundingBox(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::PathBuilder::TakePath().

◆ TEST() [115/202]

impeller::testing::TEST ( GeometryTest  ,
PathPolylineDuplicatesAreRemovedForSameContour   
)

Definition at line 2159 of file geometry_unittests.cc.

2159  {
2160  Path::Polyline polyline =
2161  PathBuilder{}
2162  .MoveTo({50, 50})
2163  .LineTo({50, 50}) // Insert duplicate at beginning of contour.
2164  .LineTo({100, 50})
2165  .LineTo({100, 50}) // Insert duplicate at contour join.
2166  .LineTo({100, 100})
2167  .Close() // Implicitly insert duplicate {50, 50} across contours.
2168  .LineTo({0, 50})
2169  .LineTo({0, 100})
2170  .LineTo({0, 100}) // Insert duplicate at end of contour.
2171  .TakePath()
2172  .CreatePolyline(1.0f);
2173  ASSERT_EQ(polyline.contours.size(), 2u);
2174  ASSERT_EQ(polyline.contours[0].start_index, 0u);
2175  ASSERT_TRUE(polyline.contours[0].is_closed);
2176  ASSERT_EQ(polyline.contours[1].start_index, 4u);
2177  ASSERT_FALSE(polyline.contours[1].is_closed);
2178  ASSERT_EQ(polyline.points.size(), 7u);
2179  ASSERT_EQ(polyline.points[0], Point(50, 50));
2180  ASSERT_EQ(polyline.points[1], Point(100, 50));
2181  ASSERT_EQ(polyline.points[2], Point(100, 100));
2182  ASSERT_EQ(polyline.points[3], Point(50, 50));
2183  ASSERT_EQ(polyline.points[4], Point(50, 50));
2184  ASSERT_EQ(polyline.points[5], Point(0, 50));
2185  ASSERT_EQ(polyline.points[6], Point(0, 100));
2186 }

References impeller::Close(), impeller::Path::Polyline::contours, impeller::LineTo(), impeller::PathBuilder::MoveTo(), and impeller::Path::Polyline::points.

◆ TEST() [116/202]

impeller::testing::TEST ( GeometryTest  ,
PathShifting   
)

Definition at line 2389 of file geometry_unittests.cc.

2389  {
2390  PathBuilder builder{};
2391  auto path =
2392  builder.AddLine(Point(0, 0), Point(10, 10))
2393  .AddQuadraticCurve(Point(10, 10), Point(15, 15), Point(20, 20))
2394  .AddCubicCurve(Point(20, 20), Point(25, 25), Point(-5, -5),
2395  Point(30, 30))
2396  .Close()
2397  .Shift(Point(1, 1))
2398  .TakePath();
2399 
2400  ContourComponent contour;
2401  LinearPathComponent linear;
2402  QuadraticPathComponent quad;
2403  CubicPathComponent cubic;
2404 
2405  ASSERT_TRUE(path.GetContourComponentAtIndex(0, contour));
2406  ASSERT_TRUE(path.GetLinearComponentAtIndex(1, linear));
2407  ASSERT_TRUE(path.GetQuadraticComponentAtIndex(3, quad));
2408  ASSERT_TRUE(path.GetCubicComponentAtIndex(5, cubic));
2409 
2410  ASSERT_EQ(contour.destination, Point(1, 1));
2411 
2412  ASSERT_EQ(linear.p1, Point(1, 1));
2413  ASSERT_EQ(linear.p2, Point(11, 11));
2414 
2415  ASSERT_EQ(quad.cp, Point(16, 16));
2416  ASSERT_EQ(quad.p1, Point(11, 11));
2417  ASSERT_EQ(quad.p2, Point(21, 21));
2418 
2419  ASSERT_EQ(cubic.cp1, Point(26, 26));
2420  ASSERT_EQ(cubic.cp2, Point(-4, -4));
2421  ASSERT_EQ(cubic.p1, Point(21, 21));
2422  ASSERT_EQ(cubic.p2, Point(31, 31));
2423 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddLine(), impeller::PathBuilder::AddQuadraticCurve(), impeller::PathBuilder::Close(), impeller::QuadraticPathComponent::cp, impeller::CubicPathComponent::cp1, impeller::CubicPathComponent::cp2, impeller::ContourComponent::destination, impeller::LinearPathComponent::p1, impeller::QuadraticPathComponent::p1, impeller::CubicPathComponent::p1, impeller::LinearPathComponent::p2, impeller::QuadraticPathComponent::p2, impeller::CubicPathComponent::p2, impeller::PathBuilder::Shift(), and impeller::PathBuilder::TakePath().

◆ TEST() [117/202]

impeller::testing::TEST ( GeometryTest  ,
PointAbs   
)

Definition at line 1076 of file geometry_unittests.cc.

1076  {
1077  Point a(-1, -2);
1078  auto a_abs = a.Abs();
1079  auto expected = Point(1, 2);
1080  ASSERT_POINT_NEAR(a_abs, expected);
1081 }

References impeller::TPoint< T >::Abs(), and ASSERT_POINT_NEAR.

◆ TEST() [118/202]

impeller::testing::TEST ( GeometryTest  ,
PointAngleTo   
)

Definition at line 1083 of file geometry_unittests.cc.

1083  {
1084  // Negative result in the CCW (with up = -Y) direction.
1085  {
1086  Point a(1, 1);
1087  Point b(1, -1);
1088  Radians actual = a.AngleTo(b);
1089  Radians expected = Radians{-kPi / 2};
1090  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1091  }
1092 
1093  // Check the other direction to ensure the result is signed correctly.
1094  {
1095  Point a(1, -1);
1096  Point b(1, 1);
1097  Radians actual = a.AngleTo(b);
1098  Radians expected = Radians{kPi / 2};
1099  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1100  }
1101 
1102  // Differences in magnitude should have no impact on the result.
1103  {
1104  Point a(100, -100);
1105  Point b(0.01, 0.01);
1106  Radians actual = a.AngleTo(b);
1107  Radians expected = Radians{kPi / 2};
1108  ASSERT_FLOAT_EQ(actual.radians, expected.radians);
1109  }
1110 }

References impeller::TPoint< T >::AngleTo(), impeller::kPi, and impeller::Radians::radians.

◆ TEST() [119/202]

impeller::testing::TEST ( GeometryTest  ,
PointCeil   
)

Definition at line 1175 of file geometry_unittests.cc.

1175  {
1176  Point p(1.5, 2.3);
1177  Point result = p.Ceil();
1178  Point expected(2, 3);
1179  ASSERT_POINT_NEAR(result, expected);
1180 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Ceil().

◆ TEST() [120/202]

impeller::testing::TEST ( GeometryTest  ,
PointCrossProduct   
)

Definition at line 1031 of file geometry_unittests.cc.

1031  {
1032  {
1033  Point p(1, 0);
1034  Scalar s = p.Cross(Point(-1, 0));
1035  ASSERT_FLOAT_EQ(s, 0);
1036  }
1037 
1038  {
1039  Point p(0, -1);
1040  Scalar s = p.Cross(Point(-1, 0));
1041  ASSERT_FLOAT_EQ(s, -1);
1042  }
1043 
1044  {
1045  Point p(1, 2);
1046  Scalar s = p.Cross(Point(3, -4));
1047  ASSERT_FLOAT_EQ(s, -10);
1048  }
1049 }

References impeller::TPoint< T >::Cross().

◆ TEST() [121/202]

impeller::testing::TEST ( GeometryTest  ,
PointDotProduct   
)

Definition at line 1011 of file geometry_unittests.cc.

1011  {
1012  {
1013  Point p(1, 0);
1014  Scalar s = p.Dot(Point(-1, 0));
1015  ASSERT_FLOAT_EQ(s, -1);
1016  }
1017 
1018  {
1019  Point p(0, -1);
1020  Scalar s = p.Dot(Point(-1, 0));
1021  ASSERT_FLOAT_EQ(s, 0);
1022  }
1023 
1024  {
1025  Point p(1, 2);
1026  Scalar s = p.Dot(Point(3, -4));
1027  ASSERT_FLOAT_EQ(s, -5);
1028  }
1029 }

References impeller::TPoint< T >::Dot().

◆ TEST() [122/202]

impeller::testing::TEST ( GeometryTest  ,
PointFloor   
)

Definition at line 1154 of file geometry_unittests.cc.

1154  {
1155  Point p(1.5, 2.3);
1156  Point result = p.Floor();
1157  Point expected(1, 2);
1158  ASSERT_POINT_NEAR(result, expected);
1159 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Floor().

◆ TEST() [123/202]

impeller::testing::TEST ( GeometryTest  ,
PointIntegerCoercesToFloat   
)

Definition at line 816 of file geometry_unittests.cc.

816  {
817  // Integer on LHS, float on RHS
818  {
819  IPoint p1(1, 2);
820  Point p2 = p1 + Point(1, 2);
821  ASSERT_FLOAT_EQ(p2.x, 2u);
822  ASSERT_FLOAT_EQ(p2.y, 4u);
823  }
824 
825  {
826  IPoint p1(3, 6);
827  Point p2 = p1 - Point(1, 2);
828  ASSERT_FLOAT_EQ(p2.x, 2u);
829  ASSERT_FLOAT_EQ(p2.y, 4u);
830  }
831 
832  {
833  IPoint p1(1, 2);
834  Point p2 = p1 * Point(2, 3);
835  ASSERT_FLOAT_EQ(p2.x, 2u);
836  ASSERT_FLOAT_EQ(p2.y, 6u);
837  }
838 
839  {
840  IPoint p1(2, 6);
841  Point p2 = p1 / Point(2, 3);
842  ASSERT_FLOAT_EQ(p2.x, 1u);
843  ASSERT_FLOAT_EQ(p2.y, 2u);
844  }
845 
846  // Float on LHS, integer on RHS
847  {
848  Point p1(1, 2);
849  Point p2 = p1 + IPoint(1, 2);
850  ASSERT_FLOAT_EQ(p2.x, 2u);
851  ASSERT_FLOAT_EQ(p2.y, 4u);
852  }
853 
854  {
855  Point p1(3, 6);
856  Point p2 = p1 - IPoint(1, 2);
857  ASSERT_FLOAT_EQ(p2.x, 2u);
858  ASSERT_FLOAT_EQ(p2.y, 4u);
859  }
860 
861  {
862  Point p1(1, 2);
863  Point p2 = p1 * IPoint(2, 3);
864  ASSERT_FLOAT_EQ(p2.x, 2u);
865  ASSERT_FLOAT_EQ(p2.y, 6u);
866  }
867 
868  {
869  Point p1(2, 6);
870  Point p2 = p1 / IPoint(2, 3);
871  ASSERT_FLOAT_EQ(p2.x, 1u);
872  ASSERT_FLOAT_EQ(p2.y, 2u);
873  }
874 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [124/202]

impeller::testing::TEST ( GeometryTest  ,
PointLerp   
)

Definition at line 1217 of file geometry_unittests.cc.

1217  {
1218  Point p(1, 2);
1219  Point result = p.Lerp({5, 10}, 0.75);
1220  Point expected(4, 8);
1221  ASSERT_POINT_NEAR(result, expected);
1222 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Lerp().

◆ TEST() [125/202]

impeller::testing::TEST ( GeometryTest  ,
PointMax   
)

Definition at line 1133 of file geometry_unittests.cc.

1133  {
1134  Point p(1, 2);
1135  Point result = p.Max({0, 10});
1136  Point expected(1, 10);
1137  ASSERT_POINT_NEAR(result, expected);
1138 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Max().

◆ TEST() [126/202]

impeller::testing::TEST ( GeometryTest  ,
PointMin   
)

Definition at line 1112 of file geometry_unittests.cc.

1112  {
1113  Point p(1, 2);
1114  Point result = p.Min({0, 10});
1115  Point expected(0, 2);
1116  ASSERT_POINT_NEAR(result, expected);
1117 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Min().

◆ TEST() [127/202]

impeller::testing::TEST ( GeometryTest  ,
PointPrinting   
)

Definition at line 2215 of file geometry_unittests.cc.

2215  {
2216  {
2217  std::stringstream stream;
2218  Point m;
2219  stream << m;
2220  ASSERT_EQ(stream.str(), "(0, 0)");
2221  }
2222 
2223  {
2224  std::stringstream stream;
2225  Point m(13, 37);
2226  stream << m;
2227  ASSERT_EQ(stream.str(), "(13, 37)");
2228  }
2229 }

◆ TEST() [128/202]

impeller::testing::TEST ( GeometryTest  ,
PointReflect   
)

Definition at line 1051 of file geometry_unittests.cc.

1051  {
1052  {
1053  Point axis = Point(0, 1);
1054  Point a(2, 3);
1055  auto reflected = a.Reflect(axis);
1056  auto expected = Point(2, -3);
1057  ASSERT_POINT_NEAR(reflected, expected);
1058  }
1059 
1060  {
1061  Point axis = Point(1, 1).Normalize();
1062  Point a(1, 0);
1063  auto reflected = a.Reflect(axis);
1064  auto expected = Point(0, -1);
1065  ASSERT_POINT_NEAR(reflected, expected);
1066  }
1067 
1068  {
1069  Point axis = Point(1, 1).Normalize();
1070  Point a(-1, -1);
1071  auto reflected = a.Reflect(axis);
1072  ASSERT_POINT_NEAR(reflected, -a);
1073  }
1074 }

References ASSERT_POINT_NEAR, impeller::TPoint< T >::Normalize(), and impeller::TPoint< T >::Reflect().

◆ TEST() [129/202]

impeller::testing::TEST ( GeometryTest  ,
PointRound   
)

Definition at line 1196 of file geometry_unittests.cc.

1196  {
1197  Point p(1.5, 2.3);
1198  Point result = p.Round();
1199  Point expected(2, 2);
1200  ASSERT_POINT_NEAR(result, expected);
1201 }

References ASSERT_POINT_NEAR, and impeller::TPoint< T >::Round().

◆ TEST() [130/202]

impeller::testing::TEST ( GeometryTest  ,
PolylineGetContourPointBoundsReturnsCorrectRanges   
)

Definition at line 2125 of file geometry_unittests.cc.

2125  {
2126  Path::Polyline polyline = PathBuilder{}
2127  .AddLine({100, 100}, {200, 100})
2128  .MoveTo({100, 200})
2129  .LineTo({150, 250})
2130  .LineTo({200, 200})
2131  .Close()
2132  .TakePath()
2133  .CreatePolyline(1.0f);
2134  size_t a1, a2, b1, b2;
2135  std::tie(a1, a2) = polyline.GetContourPointBounds(0);
2136  std::tie(b1, b2) = polyline.GetContourPointBounds(1);
2137  ASSERT_EQ(a1, 0u);
2138  ASSERT_EQ(a2, 2u);
2139  ASSERT_EQ(b1, 2u);
2140  ASSERT_EQ(b2, 6u);
2141 }

References impeller::PathBuilder::AddLine(), impeller::Close(), impeller::Path::Polyline::GetContourPointBounds(), impeller::LineTo(), and impeller::MoveTo().

◆ TEST() [131/202]

impeller::testing::TEST ( GeometryTest  ,
QuaternionLerp   
)

Definition at line 541 of file geometry_unittests.cc.

541  {
542  auto q1 = Quaternion{{0.0, 0.0, 1.0}, 0.0};
543  auto q2 = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
544 
545  auto q3 = q1.Slerp(q2, 0.5);
546 
547  auto expected = Quaternion{{0.0, 0.0, 1.0}, kPiOver4 / 2.0};
548 
549  ASSERT_QUATERNION_NEAR(q3, expected);
550 }

References ASSERT_QUATERNION_NEAR, and impeller::kPiOver4.

◆ TEST() [132/202]

impeller::testing::TEST ( GeometryTest  ,
QuaternionVectorMultiply   
)

Definition at line 552 of file geometry_unittests.cc.

552  {
553  {
554  Quaternion q({0, 0, 1}, 0);
555  Vector3 v(0, 1, 0);
556 
557  Vector3 result = q * v;
558  Vector3 expected(0, 1, 0);
559 
560  ASSERT_VECTOR3_NEAR(result, expected);
561  }
562 
563  {
564  Quaternion q({0, 0, 1}, k2Pi);
565  Vector3 v(1, 0, 0);
566 
567  Vector3 result = q * v;
568  Vector3 expected(1, 0, 0);
569 
570  ASSERT_VECTOR3_NEAR(result, expected);
571  }
572 
573  {
574  Quaternion q({0, 0, 1}, kPiOver4);
575  Vector3 v(0, 1, 0);
576 
577  Vector3 result = q * v;
578  Vector3 expected(-k1OverSqrt2, k1OverSqrt2, 0);
579 
580  ASSERT_VECTOR3_NEAR(result, expected);
581  }
582 
583  {
584  Quaternion q(Vector3(1, 0, 1).Normalize(), kPi);
585  Vector3 v(0, 0, -1);
586 
587  Vector3 result = q * v;
588  Vector3 expected(-1, 0, 0);
589 
590  ASSERT_VECTOR3_NEAR(result, expected);
591  }
592 }

References ASSERT_VECTOR3_NEAR, impeller::k1OverSqrt2, impeller::k2Pi, impeller::kPi, and impeller::kPiOver4.

◆ TEST() [133/202]

impeller::testing::TEST ( GeometryTest  ,
RectContainsPoint   
)

Definition at line 1793 of file geometry_unittests.cc.

1793  {
1794  {
1795  // Origin is inclusive
1796  Rect r(100, 100, 100, 100);
1797  Point p(100, 100);
1798  ASSERT_TRUE(r.Contains(p));
1799  }
1800  {
1801  // Size is exclusive
1802  Rect r(100, 100, 100, 100);
1803  Point p(200, 200);
1804  ASSERT_FALSE(r.Contains(p));
1805  }
1806  {
1807  Rect r(100, 100, 100, 100);
1808  Point p(99, 99);
1809  ASSERT_FALSE(r.Contains(p));
1810  }
1811  {
1812  Rect r(100, 100, 100, 100);
1813  Point p(199, 199);
1814  ASSERT_TRUE(r.Contains(p));
1815  }
1816 
1817  {
1818  Rect r = Rect::MakeMaximum();
1819  Point p(199, 199);
1820  ASSERT_TRUE(r.Contains(p));
1821  }
1822 }

References impeller::TRect< T >::Contains(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [134/202]

impeller::testing::TEST ( GeometryTest  ,
RectContainsRect   
)

Definition at line 1824 of file geometry_unittests.cc.

1824  {
1825  {
1826  Rect a(100, 100, 100, 100);
1827  ASSERT_TRUE(a.Contains(a));
1828  }
1829  {
1830  Rect a(100, 100, 100, 100);
1831  Rect b(0, 0, 0, 0);
1832  ASSERT_FALSE(a.Contains(b));
1833  }
1834  {
1835  Rect a(100, 100, 100, 100);
1836  Rect b(150, 150, 20, 20);
1837  ASSERT_TRUE(a.Contains(b));
1838  }
1839  {
1840  Rect a(100, 100, 100, 100);
1841  Rect b(150, 150, 100, 100);
1842  ASSERT_FALSE(a.Contains(b));
1843  }
1844  {
1845  Rect a(100, 100, 100, 100);
1846  Rect b(50, 50, 100, 100);
1847  ASSERT_FALSE(a.Contains(b));
1848  }
1849  {
1850  Rect a(100, 100, 100, 100);
1851  Rect b(0, 0, 300, 300);
1852  ASSERT_FALSE(a.Contains(b));
1853  }
1854  {
1855  Rect a = Rect::MakeMaximum();
1856  Rect b(0, 0, 300, 300);
1857  ASSERT_TRUE(a.Contains(b));
1858  }
1859 }

References impeller::TRect< T >::Contains(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [135/202]

impeller::testing::TEST ( GeometryTest  ,
RectCutout   
)

Definition at line 1734 of file geometry_unittests.cc.

1734  {
1735  // No cutout.
1736  {
1737  Rect a(0, 0, 100, 100);
1738  Rect b(0, 0, 50, 50);
1739  auto u = a.Cutout(b);
1740  ASSERT_TRUE(u.has_value());
1741  ASSERT_RECT_NEAR(u.value(), a);
1742  }
1743 
1744  // Full cutout.
1745  {
1746  Rect a(0, 0, 100, 100);
1747  Rect b(-10, -10, 120, 120);
1748  auto u = a.Cutout(b);
1749  ASSERT_FALSE(u.has_value());
1750  }
1751 
1752  // Cutout from top.
1753  {
1754  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1755  auto b = Rect::MakeLTRB(-10, -10, 110, 90);
1756  auto u = a.Cutout(b);
1757  auto expected = Rect::MakeLTRB(0, 90, 100, 100);
1758  ASSERT_TRUE(u.has_value());
1759  ASSERT_RECT_NEAR(u.value(), expected);
1760  }
1761 
1762  // Cutout from bottom.
1763  {
1764  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1765  auto b = Rect::MakeLTRB(-10, 10, 110, 110);
1766  auto u = a.Cutout(b);
1767  auto expected = Rect::MakeLTRB(0, 0, 100, 10);
1768  ASSERT_TRUE(u.has_value());
1769  ASSERT_RECT_NEAR(u.value(), expected);
1770  }
1771 
1772  // Cutout from left.
1773  {
1774  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1775  auto b = Rect::MakeLTRB(-10, -10, 90, 110);
1776  auto u = a.Cutout(b);
1777  auto expected = Rect::MakeLTRB(90, 0, 100, 100);
1778  ASSERT_TRUE(u.has_value());
1779  ASSERT_RECT_NEAR(u.value(), expected);
1780  }
1781 
1782  // Cutout from right.
1783  {
1784  auto a = Rect::MakeLTRB(0, 0, 100, 100);
1785  auto b = Rect::MakeLTRB(10, -10, 110, 110);
1786  auto u = a.Cutout(b);
1787  auto expected = Rect::MakeLTRB(0, 0, 10, 100);
1788  ASSERT_TRUE(u.has_value());
1789  ASSERT_RECT_NEAR(u.value(), expected);
1790  }
1791 }

References ASSERT_RECT_NEAR, impeller::TRect< T >::Cutout(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [136/202]

impeller::testing::TEST ( GeometryTest  ,
RectDirections   
)

Definition at line 1984 of file geometry_unittests.cc.

1984  {
1985  auto r = Rect::MakeLTRB(1, 2, 3, 4);
1986 
1987  ASSERT_EQ(r.GetLeft(), 1);
1988  ASSERT_EQ(r.GetTop(), 2);
1989  ASSERT_EQ(r.GetRight(), 3);
1990  ASSERT_EQ(r.GetBottom(), 4);
1991 
1992  ASSERT_POINT_NEAR(r.GetLeftTop(), Point(1, 2));
1993  ASSERT_POINT_NEAR(r.GetRightTop(), Point(3, 2));
1994  ASSERT_POINT_NEAR(r.GetLeftBottom(), Point(1, 4));
1995  ASSERT_POINT_NEAR(r.GetRightBottom(), Point(3, 4));
1996 }

References ASSERT_POINT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [137/202]

impeller::testing::TEST ( GeometryTest  ,
RectExpand   
)

Definition at line 1915 of file geometry_unittests.cc.

1915  {
1916  {
1917  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1918  auto b = a.Expand(1);
1919  auto expected = Rect::MakeLTRB(99, 99, 201, 201);
1920  ASSERT_RECT_NEAR(b, expected);
1921  }
1922  {
1923  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1924  auto b = a.Expand(-1);
1925  auto expected = Rect::MakeLTRB(101, 101, 199, 199);
1926  ASSERT_RECT_NEAR(b, expected);
1927  }
1928 
1929  {
1930  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1931  auto b = a.Expand(1, 2, 3, 4);
1932  auto expected = Rect::MakeLTRB(99, 98, 203, 204);
1933  ASSERT_RECT_NEAR(b, expected);
1934  }
1935  {
1936  auto a = Rect::MakeLTRB(100, 100, 200, 200);
1937  auto b = a.Expand(-1, -2, -3, -4);
1938  auto expected = Rect::MakeLTRB(101, 102, 197, 196);
1939  ASSERT_RECT_NEAR(b, expected);
1940  }
1941 }

References ASSERT_RECT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [138/202]

impeller::testing::TEST ( GeometryTest  ,
RectGetPoints   
)

Definition at line 1861 of file geometry_unittests.cc.

1861  {
1862  {
1863  Rect r(100, 200, 300, 400);
1864  auto points = r.GetPoints();
1865  ASSERT_POINT_NEAR(points[0], Point(100, 200));
1866  ASSERT_POINT_NEAR(points[1], Point(400, 200));
1867  ASSERT_POINT_NEAR(points[2], Point(100, 600));
1868  ASSERT_POINT_NEAR(points[3], Point(400, 600));
1869  }
1870 
1871  {
1872  Rect r = Rect::MakeMaximum();
1873  auto points = r.GetPoints();
1874  ASSERT_EQ(points[0], Point(-std::numeric_limits<float>::infinity(),
1875  -std::numeric_limits<float>::infinity()));
1876  ASSERT_EQ(points[1], Point(std::numeric_limits<float>::infinity(),
1877  -std::numeric_limits<float>::infinity()));
1878  ASSERT_EQ(points[2], Point(-std::numeric_limits<float>::infinity(),
1879  std::numeric_limits<float>::infinity()));
1880  ASSERT_EQ(points[3], Point(std::numeric_limits<float>::infinity(),
1881  std::numeric_limits<float>::infinity()));
1882  }
1883 }

References ASSERT_POINT_NEAR, impeller::TRect< T >::GetPoints(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [139/202]

impeller::testing::TEST ( GeometryTest  ,
RectGetPositive   
)

Definition at line 1943 of file geometry_unittests.cc.

1943  {
1944  {
1945  Rect r{100, 200, 300, 400};
1946  auto actual = r.GetPositive();
1947  ASSERT_RECT_NEAR(r, actual);
1948  }
1949  {
1950  Rect r{100, 200, -100, -100};
1951  auto actual = r.GetPositive();
1952  Rect expected(0, 100, 100, 100);
1953  ASSERT_RECT_NEAR(expected, actual);
1954  }
1955 }

References ASSERT_RECT_NEAR, and impeller::TRect< T >::GetPositive().

◆ TEST() [140/202]

impeller::testing::TEST ( GeometryTest  ,
RectGetTransformedPoints   
)

Definition at line 1892 of file geometry_unittests.cc.

1892  {
1893  Rect r(100, 200, 300, 400);
1894  auto points = r.GetTransformedPoints(Matrix::MakeTranslation({10, 20}));
1895  ASSERT_POINT_NEAR(points[0], Point(110, 220));
1896  ASSERT_POINT_NEAR(points[1], Point(410, 220));
1897  ASSERT_POINT_NEAR(points[2], Point(110, 620));
1898  ASSERT_POINT_NEAR(points[3], Point(410, 620));
1899 }

References ASSERT_POINT_NEAR, impeller::TRect< T >::GetTransformedPoints(), and impeller::Matrix::MakeTranslation().

◆ TEST() [141/202]

impeller::testing::TEST ( GeometryTest  ,
RectIntersection   
)

Definition at line 1647 of file geometry_unittests.cc.

1647  {
1648  {
1649  Rect a(100, 100, 100, 100);
1650  Rect b(0, 0, 0, 0);
1651 
1652  auto u = a.Intersection(b);
1653  ASSERT_FALSE(u.has_value());
1654  }
1655 
1656  {
1657  Rect a(100, 100, 100, 100);
1658  Rect b(10, 10, 0, 0);
1659  auto u = a.Intersection(b);
1660  ASSERT_FALSE(u.has_value());
1661  }
1662 
1663  {
1664  Rect a(0, 0, 100, 100);
1665  Rect b(10, 10, 100, 100);
1666  auto u = a.Intersection(b);
1667  ASSERT_TRUE(u.has_value());
1668  auto expected = Rect(10, 10, 90, 90);
1669  ASSERT_RECT_NEAR(u.value(), expected);
1670  }
1671 
1672  {
1673  Rect a(0, 0, 100, 100);
1674  Rect b(100, 100, 100, 100);
1675  auto u = a.Intersection(b);
1676  ASSERT_FALSE(u.has_value());
1677  }
1678 
1679  {
1680  Rect a = Rect::MakeMaximum();
1681  Rect b(10, 10, 300, 300);
1682  auto u = a.Intersection(b);
1683  ASSERT_TRUE(u);
1684  ASSERT_RECT_NEAR(u.value(), b);
1685  }
1686 
1687  {
1688  Rect a = Rect::MakeMaximum();
1689  Rect b = Rect::MakeMaximum();
1690  auto u = a.Intersection(b);
1691  ASSERT_TRUE(u);
1692  ASSERT_EQ(u, Rect::MakeMaximum());
1693  }
1694 }

References ASSERT_RECT_NEAR, impeller::TRect< T >::Intersection(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [142/202]

impeller::testing::TEST ( GeometryTest  ,
RectIntersectsWithRect   
)

Definition at line 1696 of file geometry_unittests.cc.

1696  {
1697  {
1698  Rect a(100, 100, 100, 100);
1699  Rect b(0, 0, 0, 0);
1700  ASSERT_FALSE(a.IntersectsWithRect(b));
1701  }
1702 
1703  {
1704  Rect a(100, 100, 100, 100);
1705  Rect b(10, 10, 0, 0);
1706  ASSERT_FALSE(a.IntersectsWithRect(b));
1707  }
1708 
1709  {
1710  Rect a(0, 0, 100, 100);
1711  Rect b(10, 10, 100, 100);
1712  ASSERT_TRUE(a.IntersectsWithRect(b));
1713  }
1714 
1715  {
1716  Rect a(0, 0, 100, 100);
1717  Rect b(100, 100, 100, 100);
1718  ASSERT_FALSE(a.IntersectsWithRect(b));
1719  }
1720 
1721  {
1722  Rect a = Rect::MakeMaximum();
1723  Rect b(10, 10, 100, 100);
1724  ASSERT_TRUE(a.IntersectsWithRect(b));
1725  }
1726 
1727  {
1728  Rect a = Rect::MakeMaximum();
1729  Rect b = Rect::MakeMaximum();
1730  ASSERT_TRUE(a.IntersectsWithRect(b));
1731  }
1732 }

References impeller::TRect< T >::IntersectsWithRect(), and impeller::TRect< Scalar >::MakeMaximum().

◆ TEST() [143/202]

impeller::testing::TEST ( GeometryTest  ,
RectMakePointBounds   
)

Definition at line 1901 of file geometry_unittests.cc.

1901  {
1902  {
1903  std::vector<Point> points{{1, 5}, {4, -1}, {0, 6}};
1904  Rect r = Rect::MakePointBounds(points.begin(), points.end()).value();
1905  auto expected = Rect(0, -1, 4, 7);
1906  ASSERT_RECT_NEAR(r, expected);
1907  }
1908  {
1909  std::vector<Point> points;
1910  std::optional<Rect> r = Rect::MakePointBounds(points.begin(), points.end());
1911  ASSERT_FALSE(r.has_value());
1912  }
1913 }

References ASSERT_RECT_NEAR, and impeller::TRect< Scalar >::MakePointBounds().

◆ TEST() [144/202]

impeller::testing::TEST ( GeometryTest  ,
RectMakeSize   
)

Definition at line 1583 of file geometry_unittests.cc.

1583  {
1584  {
1585  Size s(100, 200);
1586  Rect r = Rect::MakeSize(s);
1587  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
1588  ASSERT_RECT_NEAR(r, expected);
1589  }
1590 
1591  {
1592  ISize s(100, 200);
1593  Rect r = Rect::MakeSize(s);
1594  Rect expected = Rect::MakeLTRB(0, 0, 100, 200);
1595  ASSERT_RECT_NEAR(r, expected);
1596  }
1597 
1598  {
1599  Size s(100, 200);
1600  IRect r = IRect::MakeSize(s);
1601  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
1602  ASSERT_EQ(r, expected);
1603  }
1604 
1605  {
1606  ISize s(100, 200);
1607  IRect r = IRect::MakeSize(s);
1608  IRect expected = IRect::MakeLTRB(0, 0, 100, 200);
1609  ASSERT_EQ(r, expected);
1610  }
1611 }

References ASSERT_RECT_NEAR, impeller::TRect< int64_t >::MakeLTRB(), impeller::TRect< Scalar >::MakeLTRB(), impeller::TRect< int64_t >::MakeSize(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST() [145/202]

impeller::testing::TEST ( GeometryTest  ,
RectProject   
)

Definition at line 1998 of file geometry_unittests.cc.

1998  {
1999  {
2000  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2001  auto actual = r.Project(r);
2002  auto expected = Rect::MakeLTRB(0, 0, 1, 1);
2003  ASSERT_RECT_NEAR(expected, actual);
2004  }
2005  {
2006  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
2007  auto actual = r.Project(Rect::MakeLTRB(0, 0, 100, 100));
2008  auto expected = Rect::MakeLTRB(0.5, 0.5, 1, 1);
2009  ASSERT_RECT_NEAR(expected, actual);
2010  }
2011 }

References ASSERT_RECT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [146/202]

impeller::testing::TEST ( GeometryTest  ,
RectScale   
)

Definition at line 1957 of file geometry_unittests.cc.

1957  {
1958  {
1959  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1960  auto actual = r.Scale(0);
1961  auto expected = Rect::MakeLTRB(0, 0, 0, 0);
1962  ASSERT_RECT_NEAR(expected, actual);
1963  }
1964  {
1965  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1966  auto actual = r.Scale(-2);
1967  auto expected = Rect::MakeLTRB(200, 200, -200, -200);
1968  ASSERT_RECT_NEAR(expected, actual);
1969  }
1970  {
1971  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1972  auto actual = r.Scale(Point{0, 0});
1973  auto expected = Rect::MakeLTRB(0, 0, 0, 0);
1974  ASSERT_RECT_NEAR(expected, actual);
1975  }
1976  {
1977  auto r = Rect::MakeLTRB(-100, -100, 100, 100);
1978  auto actual = r.Scale(Size{-1, -2});
1979  auto expected = Rect::MakeLTRB(100, 200, -100, -200);
1980  ASSERT_RECT_NEAR(expected, actual);
1981  }
1982 }

References ASSERT_RECT_NEAR, and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [147/202]

impeller::testing::TEST ( GeometryTest  ,
RectShift   
)

Definition at line 1885 of file geometry_unittests.cc.

1885  {
1886  auto r = Rect::MakeLTRB(0, 0, 100, 100);
1887 
1888  ASSERT_EQ(r.Shift(Point(10, 5)), Rect::MakeLTRB(10, 5, 110, 105));
1889  ASSERT_EQ(r.Shift(Point(-10, -5)), Rect::MakeLTRB(-10, -5, 90, 95));
1890 }

References impeller::TRect< Scalar >::MakeLTRB().

◆ TEST() [148/202]

impeller::testing::TEST ( GeometryTest  ,
RectUnion   
)

Definition at line 1613 of file geometry_unittests.cc.

1613  {
1614  {
1615  Rect a(100, 100, 100, 100);
1616  Rect b(0, 0, 0, 0);
1617  auto u = a.Union(b);
1618  auto expected = Rect(0, 0, 200, 200);
1619  ASSERT_RECT_NEAR(u, expected);
1620  }
1621 
1622  {
1623  Rect a(100, 100, 100, 100);
1624  Rect b(10, 10, 0, 0);
1625  auto u = a.Union(b);
1626  auto expected = Rect(10, 10, 190, 190);
1627  ASSERT_RECT_NEAR(u, expected);
1628  }
1629 
1630  {
1631  Rect a(0, 0, 100, 100);
1632  Rect b(10, 10, 100, 100);
1633  auto u = a.Union(b);
1634  auto expected = Rect(0, 0, 110, 110);
1635  ASSERT_RECT_NEAR(u, expected);
1636  }
1637 
1638  {
1639  Rect a(0, 0, 100, 100);
1640  Rect b(100, 100, 100, 100);
1641  auto u = a.Union(b);
1642  auto expected = Rect(0, 0, 200, 200);
1643  ASSERT_RECT_NEAR(u, expected);
1644  }
1645 }

References ASSERT_RECT_NEAR, and impeller::TRect< T >::Union().

◆ TEST() [149/202]

impeller::testing::TEST ( GeometryTest  ,
RotationMatrix   
)

Definition at line 69 of file geometry_unittests.cc.

69  {
70  auto rotation = Matrix::MakeRotationZ(Radians{kPiOver4});
71  auto expect = Matrix{0.707, 0.707, 0, 0, //
72  -0.707, 0.707, 0, 0, //
73  0, 0, 1, 0, //
74  0, 0, 0, 1};
75  ASSERT_MATRIX_NEAR(rotation, expect);
76 }

References ASSERT_MATRIX_NEAR, impeller::kPiOver4, and impeller::Matrix::MakeRotationZ().

◆ TEST() [150/202]

impeller::testing::TEST ( GeometryTest  ,
ScalarNearlyEqual   
)

Definition at line 32 of file geometry_unittests.cc.

32  {
33  ASSERT_FALSE(ScalarNearlyEqual(0.0021f, 0.001f));
34  ASSERT_TRUE(ScalarNearlyEqual(0.0019f, 0.001f));
35  ASSERT_TRUE(ScalarNearlyEqual(0.002f, 0.001f, 0.0011f));
36  ASSERT_FALSE(ScalarNearlyEqual(0.002f, 0.001f, 0.0009f));
37  ASSERT_TRUE(ScalarNearlyEqual(
38  1.0f, 1.0f + std::numeric_limits<float>::epsilon() * 4));
39 }

References impeller::ScalarNearlyEqual().

◆ TEST() [151/202]

impeller::testing::TEST ( GeometryTest  ,
SimplePath   
)

Definition at line 607 of file geometry_unittests.cc.

607  {
608  PathBuilder builder;
609 
610  auto path = builder.AddLine({0, 0}, {100, 100})
611  .AddQuadraticCurve({100, 100}, {200, 200}, {300, 300})
612  .AddCubicCurve({300, 300}, {400, 400}, {500, 500}, {600, 600})
613  .TakePath();
614 
615  ASSERT_EQ(path.GetComponentCount(), 6u);
616  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kLinear), 1u);
617  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kQuadratic), 1u);
618  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kCubic), 1u);
619  ASSERT_EQ(path.GetComponentCount(Path::ComponentType::kContour), 3u);
620 
621  path.EnumerateComponents(
622  [](size_t index, const LinearPathComponent& linear) {
623  Point p1(0, 0);
624  Point p2(100, 100);
625  ASSERT_EQ(index, 1u);
626  ASSERT_EQ(linear.p1, p1);
627  ASSERT_EQ(linear.p2, p2);
628  },
629  [](size_t index, const QuadraticPathComponent& quad) {
630  Point p1(100, 100);
631  Point cp(200, 200);
632  Point p2(300, 300);
633  ASSERT_EQ(index, 3u);
634  ASSERT_EQ(quad.p1, p1);
635  ASSERT_EQ(quad.cp, cp);
636  ASSERT_EQ(quad.p2, p2);
637  },
638  [](size_t index, const CubicPathComponent& cubic) {
639  Point p1(300, 300);
640  Point cp1(400, 400);
641  Point cp2(500, 500);
642  Point p2(600, 600);
643  ASSERT_EQ(index, 5u);
644  ASSERT_EQ(cubic.p1, p1);
645  ASSERT_EQ(cubic.cp1, cp1);
646  ASSERT_EQ(cubic.cp2, cp2);
647  ASSERT_EQ(cubic.p2, p2);
648  },
649  [](size_t index, const ContourComponent& contour) {
650  // There is an initial countour added for each curve.
651  if (index == 0u) {
652  Point p1(0, 0);
653  ASSERT_EQ(contour.destination, p1);
654  } else if (index == 2u) {
655  Point p1(100, 100);
656  ASSERT_EQ(contour.destination, p1);
657  } else if (index == 4u) {
658  Point p1(300, 300);
659  ASSERT_EQ(contour.destination, p1);
660  } else {
661  ASSERT_FALSE(true);
662  }
663  ASSERT_FALSE(contour.is_closed);
664  });
665 }

References impeller::PathBuilder::AddLine(), impeller::Path::kContour, impeller::Path::kCubic, impeller::Path::kLinear, impeller::Path::kQuadratic, impeller::LinearPathComponent::p1, and impeller::LinearPathComponent::p2.

◆ TEST() [152/202]

impeller::testing::TEST ( GeometryTest  ,
SizeCoercesToPoint   
)

Definition at line 876 of file geometry_unittests.cc.

876  {
877  // Point on LHS, Size on RHS
878  {
879  IPoint p1(1, 2);
880  IPoint p2 = p1 + ISize(1, 2);
881  ASSERT_EQ(p2.x, 2u);
882  ASSERT_EQ(p2.y, 4u);
883  }
884 
885  {
886  IPoint p1(3, 6);
887  IPoint p2 = p1 - ISize(1, 2);
888  ASSERT_EQ(p2.x, 2u);
889  ASSERT_EQ(p2.y, 4u);
890  }
891 
892  {
893  IPoint p1(1, 2);
894  IPoint p2 = p1 * ISize(2, 3);
895  ASSERT_EQ(p2.x, 2u);
896  ASSERT_EQ(p2.y, 6u);
897  }
898 
899  {
900  IPoint p1(2, 6);
901  IPoint p2 = p1 / ISize(2, 3);
902  ASSERT_EQ(p2.x, 1u);
903  ASSERT_EQ(p2.y, 2u);
904  }
905 
906  // Size on LHS, Point on RHS
907  {
908  ISize p1(1, 2);
909  IPoint p2 = p1 + IPoint(1, 2);
910  ASSERT_EQ(p2.x, 2u);
911  ASSERT_EQ(p2.y, 4u);
912  }
913 
914  {
915  ISize p1(3, 6);
916  IPoint p2 = p1 - IPoint(1, 2);
917  ASSERT_EQ(p2.x, 2u);
918  ASSERT_EQ(p2.y, 4u);
919  }
920 
921  {
922  ISize p1(1, 2);
923  IPoint p2 = p1 * IPoint(2, 3);
924  ASSERT_EQ(p2.x, 2u);
925  ASSERT_EQ(p2.y, 6u);
926  }
927 
928  {
929  ISize p1(2, 6);
930  IPoint p2 = p1 / IPoint(2, 3);
931  ASSERT_EQ(p2.x, 1u);
932  ASSERT_EQ(p2.y, 2u);
933  }
934 }

References impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST() [153/202]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition   
)

Definition at line 139 of file geometry_unittests.cc.

139  {
140  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
141 
142  auto result = rotated.Decompose();
143 
144  ASSERT_TRUE(result.has_value());
145 
146  MatrixDecomposition res = result.value();
147 
148  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
149  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
150 }

References ASSERT_QUATERNION_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::MatrixDecomposition::rotation.

◆ TEST() [154/202]

impeller::testing::TEST ( GeometryTest  ,
TestDecomposition2   
)

Definition at line 152 of file geometry_unittests.cc.

152  {
153  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
154  auto scaled = Matrix::MakeScale({2.0, 3.0, 1.0});
155  auto translated = Matrix::MakeTranslation({-200, 750, 20});
156 
157  auto result = (translated * rotated * scaled).Decompose();
158 
159  ASSERT_TRUE(result.has_value());
160 
161  MatrixDecomposition res = result.value();
162 
163  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
164 
165  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
166 
167  ASSERT_FLOAT_EQ(res.translation.x, -200);
168  ASSERT_FLOAT_EQ(res.translation.y, 750);
169  ASSERT_FLOAT_EQ(res.translation.z, 20);
170 
171  ASSERT_FLOAT_EQ(res.scale.x, 2);
172  ASSERT_FLOAT_EQ(res.scale.y, 3);
173  ASSERT_FLOAT_EQ(res.scale.z, 1);
174 }

References ASSERT_QUATERNION_NEAR, impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::MatrixDecomposition::rotation, impeller::MatrixDecomposition::scale, impeller::MatrixDecomposition::translation, impeller::Vector3::x, impeller::Vector3::y, and impeller::Vector3::z.

◆ TEST() [155/202]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition   
)

Definition at line 176 of file geometry_unittests.cc.

176  {
177  /*
178  * Decomposition.
179  */
180  auto rotated = Matrix::MakeRotationZ(Radians{kPiOver4});
181 
182  auto result = rotated.Decompose();
183 
184  ASSERT_TRUE(result.has_value());
185 
186  MatrixDecomposition res = result.value();
187 
188  auto quaternion = Quaternion{{0.0, 0.0, 1.0}, kPiOver4};
189 
190  ASSERT_QUATERNION_NEAR(res.rotation, quaternion);
191 
192  /*
193  * Recomposition.
194  */
195  ASSERT_MATRIX_NEAR(rotated, Matrix{res});
196 }

References ASSERT_MATRIX_NEAR, ASSERT_QUATERNION_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), and impeller::MatrixDecomposition::rotation.

◆ TEST() [156/202]

impeller::testing::TEST ( GeometryTest  ,
TestRecomposition2   
)

Definition at line 198 of file geometry_unittests.cc.

198  {
199  auto matrix = Matrix::MakeTranslation({100, 100, 100}) *
200  Matrix::MakeRotationZ(Radians{kPiOver4}) *
201  Matrix::MakeScale({2.0, 2.0, 2.0});
202 
203  auto result = matrix.Decompose();
204 
205  ASSERT_TRUE(result.has_value());
206 
207  ASSERT_MATRIX_NEAR(matrix, Matrix{result.value()});
208 }

References ASSERT_MATRIX_NEAR, impeller::Matrix::Decompose(), impeller::kPiOver4, impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), and impeller::Matrix::MakeTranslation().

◆ TEST() [157/202]

impeller::testing::TEST ( GeometryTest  ,
ToIColor   
)

Definition at line 2279 of file geometry_unittests.cc.

2279  {
2280  ASSERT_EQ(Color::ToIColor(Color(0, 0, 0, 0)), 0u);
2281  ASSERT_EQ(Color::ToIColor(Color(1.0, 1.0, 1.0, 1.0)), 0xFFFFFFFF);
2282  ASSERT_EQ(Color::ToIColor(Color(0.5, 0.5, 1.0, 1.0)), 0xFF8080FF);
2283 }

References impeller::Color::ToIColor().

◆ TEST() [158/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Ceil   
)

Definition at line 1182 of file geometry_unittests.cc.

1182  {
1183  Vector3 p(1.5, 2.3, 3.9);
1184  Vector3 result = p.Ceil();
1185  Vector3 expected(2, 3, 4);
1186  ASSERT_VECTOR3_NEAR(result, expected);
1187 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Ceil().

◆ TEST() [159/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Floor   
)

Definition at line 1161 of file geometry_unittests.cc.

1161  {
1162  Vector3 p(1.5, 2.3, 3.9);
1163  Vector3 result = p.Floor();
1164  Vector3 expected(1, 2, 3);
1165  ASSERT_VECTOR3_NEAR(result, expected);
1166 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Floor().

◆ TEST() [160/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Lerp   
)

Definition at line 1224 of file geometry_unittests.cc.

1224  {
1225  Vector3 p(1, 2, 3);
1226  Vector3 result = p.Lerp({5, 10, 15}, 0.75);
1227  Vector3 expected(4, 8, 12);
1228  ASSERT_VECTOR3_NEAR(result, expected);
1229 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Lerp().

◆ TEST() [161/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Max   
)

Definition at line 1140 of file geometry_unittests.cc.

1140  {
1141  Vector3 p(1, 2, 3);
1142  Vector3 result = p.Max({0, 10, 2});
1143  Vector3 expected(1, 10, 3);
1144  ASSERT_VECTOR3_NEAR(result, expected);
1145 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Max().

◆ TEST() [162/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Min   
)

Definition at line 1119 of file geometry_unittests.cc.

1119  {
1120  Vector3 p(1, 2, 3);
1121  Vector3 result = p.Min({0, 10, 2});
1122  Vector3 expected(0, 2, 2);
1123  ASSERT_VECTOR3_NEAR(result, expected);
1124 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Min().

◆ TEST() [163/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Printing   
)

Definition at line 2231 of file geometry_unittests.cc.

2231  {
2232  {
2233  std::stringstream stream;
2234  Vector3 m;
2235  stream << m;
2236  ASSERT_EQ(stream.str(), "(0, 0, 0)");
2237  }
2238 
2239  {
2240  std::stringstream stream;
2241  Vector3 m(1, 2, 3);
2242  stream << m;
2243  ASSERT_EQ(stream.str(), "(1, 2, 3)");
2244  }
2245 }

◆ TEST() [164/202]

impeller::testing::TEST ( GeometryTest  ,
Vector3Round   
)

Definition at line 1203 of file geometry_unittests.cc.

1203  {
1204  Vector3 p(1.5, 2.3, 3.9);
1205  Vector3 result = p.Round();
1206  Vector3 expected(2, 2, 4);
1207  ASSERT_VECTOR3_NEAR(result, expected);
1208 }

References ASSERT_VECTOR3_NEAR, and impeller::Vector3::Round().

◆ TEST() [165/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Ceil   
)

Definition at line 1189 of file geometry_unittests.cc.

1189  {
1190  Vector4 p(1.5, 2.3, 3.9, 4.0);
1191  Vector4 result = p.Ceil();
1192  Vector4 expected(2, 3, 4, 4);
1193  ASSERT_VECTOR4_NEAR(result, expected);
1194 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Ceil().

◆ TEST() [166/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Floor   
)

Definition at line 1168 of file geometry_unittests.cc.

1168  {
1169  Vector4 p(1.5, 2.3, 3.9, 4.0);
1170  Vector4 result = p.Floor();
1171  Vector4 expected(1, 2, 3, 4);
1172  ASSERT_VECTOR4_NEAR(result, expected);
1173 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Floor().

◆ TEST() [167/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Lerp   
)

Definition at line 1231 of file geometry_unittests.cc.

1231  {
1232  Vector4 p(1, 2, 3, 4);
1233  Vector4 result = p.Lerp({5, 10, 15, 20}, 0.75);
1234  Vector4 expected(4, 8, 12, 16);
1235  ASSERT_VECTOR4_NEAR(result, expected);
1236 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Lerp().

◆ TEST() [168/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Max   
)

Definition at line 1147 of file geometry_unittests.cc.

1147  {
1148  Vector4 p(1, 2, 3, 4);
1149  Vector4 result = p.Max({0, 10, 2, 1});
1150  Vector4 expected(1, 10, 3, 4);
1151  ASSERT_VECTOR4_NEAR(result, expected);
1152 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Max().

◆ TEST() [169/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Min   
)

Definition at line 1126 of file geometry_unittests.cc.

1126  {
1127  Vector4 p(1, 2, 3, 4);
1128  Vector4 result = p.Min({0, 10, 2, 1});
1129  Vector4 expected(0, 2, 2, 1);
1130  ASSERT_VECTOR4_NEAR(result, expected);
1131 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Min().

◆ TEST() [170/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Printing   
)

Definition at line 2247 of file geometry_unittests.cc.

2247  {
2248  {
2249  std::stringstream stream;
2250  Vector4 m;
2251  stream << m;
2252  ASSERT_EQ(stream.str(), "(0, 0, 0, 1)");
2253  }
2254 
2255  {
2256  std::stringstream stream;
2257  Vector4 m(1, 2, 3, 4);
2258  stream << m;
2259  ASSERT_EQ(stream.str(), "(1, 2, 3, 4)");
2260  }
2261 }

◆ TEST() [171/202]

impeller::testing::TEST ( GeometryTest  ,
Vector4Round   
)

Definition at line 1210 of file geometry_unittests.cc.

1210  {
1211  Vector4 p(1.5, 2.3, 3.9, 4.0);
1212  Vector4 result = p.Round();
1213  Vector4 expected(2, 2, 4, 4);
1214  ASSERT_VECTOR4_NEAR(result, expected);
1215 }

References ASSERT_VECTOR4_NEAR, and impeller::Vector4::Round().

◆ TEST() [172/202]

impeller::testing::TEST ( HostBufferTest  ,
CanEmplace   
)

Definition at line 18 of file host_buffer_unittests.cc.

18  {
19  struct Length2 {
20  uint8_t pad[2];
21  };
22  static_assert(sizeof(Length2) == 2u);
23 
24  auto buffer = HostBuffer::Create();
25 
26  for (size_t i = 0; i < 12500; i++) {
27  auto view = buffer->Emplace(Length2{});
28  ASSERT_TRUE(view);
29  ASSERT_EQ(buffer->GetLength(), (i + 1) * sizeof(Length2));
30  ASSERT_EQ(view.range, Range(i * sizeof(Length2), 2u));
31  }
32 }

References impeller::HostBuffer::Create().

◆ TEST() [173/202]

impeller::testing::TEST ( HostBufferTest  ,
CanEmplaceWithAlignment   
)

Definition at line 34 of file host_buffer_unittests.cc.

34  {
35  struct Length2 {
36  uint8_t pad[2];
37  };
38  static_assert(sizeof(Length2) == 2);
39  struct alignas(16) Align16 {
40  uint8_t pad[2];
41  };
42  static_assert(alignof(Align16) == 16);
43  static_assert(sizeof(Align16) == 16);
44 
45  auto buffer = HostBuffer::Create();
46  ASSERT_TRUE(buffer);
47 
48  {
49  auto view = buffer->Emplace(Length2{});
50  ASSERT_TRUE(view);
51  ASSERT_EQ(buffer->GetLength(), 2u);
52  ASSERT_EQ(view.range, Range(0u, 2u));
53  }
54 
55  {
56  auto view = buffer->Emplace(Align16{});
57  ASSERT_TRUE(view);
58  ASSERT_EQ(view.range.offset, 16u);
59  ASSERT_EQ(view.range.length, 16u);
60  ASSERT_EQ(buffer->GetLength(), 32u);
61  }
62  {
63  auto view = buffer->Emplace(Length2{});
64  ASSERT_TRUE(view);
65  ASSERT_EQ(buffer->GetLength(), 34u);
66  ASSERT_EQ(view.range, Range(32u, 2u));
67  }
68 
69  {
70  auto view = buffer->Emplace(Align16{});
71  ASSERT_TRUE(view);
72  ASSERT_EQ(view.range.offset, 48u);
73  ASSERT_EQ(view.range.length, 16u);
74  ASSERT_EQ(buffer->GetLength(), 64u);
75  }
76 }

References impeller::HostBuffer::Create().

◆ TEST() [174/202]

impeller::testing::TEST ( HostBufferTest  ,
TestInitialization   
)

Definition at line 11 of file host_buffer_unittests.cc.

11  {
12  ASSERT_TRUE(HostBuffer::Create());
13  // Newly allocated buffers don't touch the heap till they have to.
14  ASSERT_EQ(HostBuffer::Create()->GetLength(), 0u);
15  ASSERT_EQ(HostBuffer::Create()->GetReservedLength(), 0u);
16 }

References impeller::HostBuffer::Create().

◆ TEST() [175/202]

impeller::testing::TEST ( PassBindingsCacheTest  ,
bindPipeline   
)

Definition at line 26 of file pass_bindings_cache_unittests.cc.

26  {
27  auto context = MockVulkanContextBuilder().Build();
28  PassBindingsCache cache;
29  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
30  auto buffer = encoder->GetCommandBuffer();
31  VkPipeline vk_pipeline = reinterpret_cast<VkPipeline>(0xfeedface);
32  vk::Pipeline pipeline(vk_pipeline);
33  cache.BindPipeline(buffer, vk::PipelineBindPoint::eGraphics, pipeline);
34  cache.BindPipeline(buffer, vk::PipelineBindPoint::eGraphics, pipeline);
35  std::shared_ptr<std::vector<std::string>> functions =
36  GetMockVulkanFunctions(context->GetDevice());
37  EXPECT_EQ(CountStringViewInstances(*functions, "vkCmdBindPipeline"), 1);
38 }

References impeller::PassBindingsCache::BindPipeline().

◆ TEST() [176/202]

impeller::testing::TEST ( PassBindingsCacheTest  ,
setScissor   
)

Definition at line 55 of file pass_bindings_cache_unittests.cc.

55  {
56  auto context = MockVulkanContextBuilder().Build();
57  PassBindingsCache cache;
58  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
59  auto buffer = encoder->GetCommandBuffer();
60  vk::Rect2D scissors;
61  cache.SetScissor(buffer, 0, 1, &scissors);
62  cache.SetScissor(buffer, 0, 1, &scissors);
63  std::shared_ptr<std::vector<std::string>> functions =
64  GetMockVulkanFunctions(context->GetDevice());
65  EXPECT_EQ(CountStringViewInstances(*functions, "vkCmdSetScissor"), 1);
66 }

References impeller::PassBindingsCache::SetScissor().

◆ TEST() [177/202]

impeller::testing::TEST ( PassBindingsCacheTest  ,
setStencilReference   
)

Definition at line 40 of file pass_bindings_cache_unittests.cc.

40  {
41  auto context = MockVulkanContextBuilder().Build();
42  PassBindingsCache cache;
43  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
44  auto buffer = encoder->GetCommandBuffer();
45  cache.SetStencilReference(
46  buffer, vk::StencilFaceFlagBits::eVkStencilFrontAndBack, 123);
47  cache.SetStencilReference(
48  buffer, vk::StencilFaceFlagBits::eVkStencilFrontAndBack, 123);
49  std::shared_ptr<std::vector<std::string>> functions =
50  GetMockVulkanFunctions(context->GetDevice());
51  EXPECT_EQ(CountStringViewInstances(*functions, "vkCmdSetStencilReference"),
52  1);
53 }

References impeller::PassBindingsCache::SetStencilReference().

◆ TEST() [178/202]

impeller::testing::TEST ( PassBindingsCacheTest  ,
setViewport   
)

Definition at line 68 of file pass_bindings_cache_unittests.cc.

68  {
69  auto context = MockVulkanContextBuilder().Build();
70  PassBindingsCache cache;
71  auto encoder = std::make_unique<CommandEncoderFactoryVK>(context)->Create();
72  auto buffer = encoder->GetCommandBuffer();
73  vk::Viewport viewports;
74  cache.SetViewport(buffer, 0, 1, &viewports);
75  cache.SetViewport(buffer, 0, 1, &viewports);
76  std::shared_ptr<std::vector<std::string>> functions =
77  GetMockVulkanFunctions(context->GetDevice());
78  EXPECT_EQ(CountStringViewInstances(*functions, "vkCmdSetViewport"), 1);
79 }

References impeller::PassBindingsCache::SetViewport().

◆ TEST() [179/202]

impeller::testing::TEST ( PipelineDescriptorTest  ,
PrimitiveTypeHashEquality   
)

Definition at line 13 of file pipeline_descriptor_unittests.cc.

13  {
14  PipelineDescriptor descA;
15  PipelineDescriptor descB;
16 
17  ASSERT_TRUE(descA.IsEqual(descB));
18  ASSERT_EQ(descA.GetHash(), descB.GetHash());
19 
20  descA.SetPrimitiveType(PrimitiveType::kTriangleStrip);
21 
22  ASSERT_FALSE(descA.IsEqual(descB));
23  ASSERT_NE(descA.GetHash(), descB.GetHash());
24 }

References impeller::PipelineDescriptor::GetHash(), impeller::PipelineDescriptor::IsEqual(), impeller::kTriangleStrip, and impeller::PipelineDescriptor::SetPrimitiveType().

◆ TEST() [180/202]

impeller::testing::TEST ( PoolTest  ,
Overload   
)

Definition at line 47 of file pool_unittests.cc.

47  {
48  Pool<Foobar> pool(1'000);
49  {
50  std::vector<std::shared_ptr<Foobar>> values;
51  for (int i = 0; i < 20; i++) {
52  values.push_back(pool.Grab());
53  }
54  for (auto value : values) {
55  value->SetSize(100);
56  pool.Recycle(value);
57  }
58  }
59  EXPECT_EQ(pool.GetSize(), 1'000u);
60 }

◆ TEST() [181/202]

impeller::testing::TEST ( PoolTest  ,
Simple   
)

Definition at line 33 of file pool_unittests.cc.

33  {
34  Pool<Foobar> pool(1'000);
35  {
36  auto grabbed = pool.Grab();
37  grabbed->SetSize(123);
38  pool.Recycle(grabbed);
39  EXPECT_EQ(pool.GetSize(), 123u);
40  }
41  auto grabbed = pool.Grab();
42  EXPECT_EQ(grabbed->GetSize(), 123u);
43  EXPECT_TRUE(grabbed->GetIsReset());
44  EXPECT_EQ(pool.GetSize(), 0u);
45 }

◆ TEST() [182/202]

impeller::testing::TEST ( RenderTargetCacheTest  ,
CachesUsedTexturesAcrossFrames   
)

Definition at line 45 of file render_target_cache_unittests.cc.

45  {
46  auto allocator = std::make_shared<TestAllocator>();
47  auto render_target_cache = RenderTargetCache(allocator);
48  auto desc = TextureDescriptor{
49  .format = PixelFormat::kR8G8B8A8UNormInt,
50  .size = ISize(100, 100),
51  .usage = static_cast<TextureUsageMask>(TextureUsage::kRenderTarget)};
52 
53  render_target_cache.Start();
54  // Create two textures of the same exact size/shape. Both should be marked
55  // as used this frame, so the cached data set will contain two.
56  render_target_cache.CreateTexture(desc);
57  render_target_cache.CreateTexture(desc);
58 
59  ASSERT_EQ(render_target_cache.CachedTextureCount(), 2u);
60 
61  render_target_cache.End();
62  render_target_cache.Start();
63 
64  // Next frame, only create one texture. The set will still contain two,
65  // but one will be removed at the end of the frame.
66  render_target_cache.CreateTexture(desc);
67  ASSERT_EQ(render_target_cache.CachedTextureCount(), 2u);
68 
69  render_target_cache.End();
70  ASSERT_EQ(render_target_cache.CachedTextureCount(), 1u);
71 }

References impeller::TextureDescriptor::format, impeller::kR8G8B8A8UNormInt, and impeller::kRenderTarget.

◆ TEST() [183/202]

impeller::testing::TEST ( RenderTargetCacheTest  ,
DoesNotPersistFailedAllocations   
)

Definition at line 73 of file render_target_cache_unittests.cc.

73  {
74  auto allocator = std::make_shared<TestAllocator>();
75  auto render_target_cache = RenderTargetCache(allocator);
76  auto desc = TextureDescriptor{
77  .format = PixelFormat::kR8G8B8A8UNormInt,
78  .size = ISize(100, 100),
79  .usage = static_cast<TextureUsageMask>(TextureUsage::kRenderTarget)};
80 
81  render_target_cache.Start();
82  allocator->should_fail = true;
83 
84  ASSERT_EQ(render_target_cache.CreateTexture(desc), nullptr);
85  ASSERT_EQ(render_target_cache.CachedTextureCount(), 0u);
86 }

References impeller::TextureDescriptor::format, impeller::kR8G8B8A8UNormInt, and impeller::kRenderTarget.

◆ TEST() [184/202]

impeller::testing::TEST ( ResourceManagerVKTest  ,
CreatesANewInstance   
)

Definition at line 17 of file resource_manager_vk_unittests.cc.

17  {
18  auto const a = ResourceManagerVK::Create();
19  auto const b = ResourceManagerVK::Create();
20  EXPECT_NE(a, b);
21 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [185/202]

impeller::testing::TEST ( ResourceManagerVKTest  ,
IsThreadSafe   
)

Definition at line 77 of file resource_manager_vk_unittests.cc.

77  {
78  // In a typical app, there is a single ResourceManagerVK per app, shared b/w
79  // threads.
80  //
81  // This test ensures that the ResourceManagerVK is thread-safe.
82  std::weak_ptr<ResourceManagerVK> manager;
83 
84  {
85  auto const manager = ResourceManagerVK::Create();
86 
87  // Spawn two threads, and have them both put resources into the manager.
88  struct MockResource {};
89 
90  std::thread thread1([&manager]() {
91  UniqueResourceVKT<MockResource>(manager, MockResource{});
92  });
93 
94  std::thread thread2([&manager]() {
95  UniqueResourceVKT<MockResource>(manager, MockResource{});
96  });
97 
98  thread1.join();
99  thread2.join();
100  }
101 
102  // The thread should have terminated.
103  EXPECT_EQ(manager.lock(), nullptr);
104 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [186/202]

impeller::testing::TEST ( ResourceManagerVKTest  ,
ReclaimMovesAResourceAndDestroysIt   
)

Definition at line 44 of file resource_manager_vk_unittests.cc.

44  {
45  auto const manager = ResourceManagerVK::Create();
46 
47  auto waiter = fml::AutoResetWaitableEvent();
48  auto dead = false;
49  auto rattle = DeathRattle([&waiter]() { waiter.Signal(); });
50 
51  // Not killed immediately.
52  EXPECT_FALSE(waiter.IsSignaledForTest());
53 
54  {
55  auto resource = UniqueResourceVKT<DeathRattle>(manager, std::move(rattle));
56  }
57 
58  waiter.Wait();
59 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [187/202]

impeller::testing::TEST ( ResourceManagerVKTest  ,
TerminatesWhenOutOfScope   
)

Definition at line 62 of file resource_manager_vk_unittests.cc.

62  {
63  // Originally, this shared_ptr was never destroyed, and the thread never
64  // terminated. This test ensures that the thread terminates when the
65  // ResourceManagerVK is out of scope.
66  std::weak_ptr<ResourceManagerVK> manager;
67 
68  {
69  auto shared = ResourceManagerVK::Create();
70  manager = shared;
71  }
72 
73  // The thread should have terminated.
74  EXPECT_EQ(manager.lock(), nullptr);
75 }

References impeller::ResourceManagerVK::Create().

◆ TEST() [188/202]

impeller::testing::TEST ( RuntimeStageTest  ,
CanReadUniforms   
)

Definition at line 50 of file runtime_stage_unittests.cc.

50  {
51  auto fixture =
52  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
53  ASSERT_TRUE(fixture);
54  ASSERT_GT(fixture->GetSize(), 0u);
55  RuntimeStage stage(std::move(fixture));
56  ASSERT_TRUE(stage.IsValid());
57  ASSERT_EQ(stage.GetUniforms().size(), 17u);
58  {
59  auto uni = stage.GetUniform("u_color");
60  ASSERT_NE(uni, nullptr);
61  ASSERT_EQ(uni->dimensions.rows, 4u);
62  ASSERT_EQ(uni->dimensions.cols, 1u);
63  ASSERT_EQ(uni->location, 0u);
64  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
65  }
66  {
67  auto uni = stage.GetUniform("u_alpha");
68  ASSERT_NE(uni, nullptr);
69  ASSERT_EQ(uni->dimensions.rows, 1u);
70  ASSERT_EQ(uni->dimensions.cols, 1u);
71  ASSERT_EQ(uni->location, 1u);
72  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
73  }
74  {
75  auto uni = stage.GetUniform("u_sparkle_color");
76  ASSERT_NE(uni, nullptr);
77  ASSERT_EQ(uni->dimensions.rows, 4u);
78  ASSERT_EQ(uni->dimensions.cols, 1u);
79  ASSERT_EQ(uni->location, 2u);
80  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
81  }
82  {
83  auto uni = stage.GetUniform("u_sparkle_alpha");
84  ASSERT_NE(uni, nullptr);
85  ASSERT_EQ(uni->dimensions.rows, 1u);
86  ASSERT_EQ(uni->dimensions.cols, 1u);
87  ASSERT_EQ(uni->location, 3u);
88  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
89  }
90  {
91  auto uni = stage.GetUniform("u_blur");
92  ASSERT_NE(uni, nullptr);
93  ASSERT_EQ(uni->dimensions.rows, 1u);
94  ASSERT_EQ(uni->dimensions.cols, 1u);
95  ASSERT_EQ(uni->location, 4u);
96  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
97  }
98  {
99  auto uni = stage.GetUniform("u_radius_scale");
100  ASSERT_NE(uni, nullptr);
101  ASSERT_EQ(uni->dimensions.rows, 1u);
102  ASSERT_EQ(uni->dimensions.cols, 1u);
103  ASSERT_EQ(uni->location, 6u);
104  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
105  }
106  {
107  auto uni = stage.GetUniform("u_max_radius");
108  ASSERT_NE(uni, nullptr);
109  ASSERT_EQ(uni->dimensions.rows, 1u);
110  ASSERT_EQ(uni->dimensions.cols, 1u);
111  ASSERT_EQ(uni->location, 7u);
112  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
113  }
114  {
115  auto uni = stage.GetUniform("u_resolution_scale");
116  ASSERT_NE(uni, nullptr);
117  ASSERT_EQ(uni->dimensions.rows, 2u);
118  ASSERT_EQ(uni->dimensions.cols, 1u);
119  ASSERT_EQ(uni->location, 8u);
120  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
121  }
122  {
123  auto uni = stage.GetUniform("u_noise_scale");
124  ASSERT_NE(uni, nullptr);
125  ASSERT_EQ(uni->dimensions.rows, 2u);
126  ASSERT_EQ(uni->dimensions.cols, 1u);
127  ASSERT_EQ(uni->location, 9u);
128  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
129  }
130  {
131  auto uni = stage.GetUniform("u_noise_phase");
132  ASSERT_NE(uni, nullptr);
133  ASSERT_EQ(uni->dimensions.rows, 1u);
134  ASSERT_EQ(uni->dimensions.cols, 1u);
135  ASSERT_EQ(uni->location, 10u);
136  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
137  }
138 
139  {
140  auto uni = stage.GetUniform("u_circle1");
141  ASSERT_NE(uni, nullptr);
142  ASSERT_EQ(uni->dimensions.rows, 2u);
143  ASSERT_EQ(uni->dimensions.cols, 1u);
144  ASSERT_EQ(uni->location, 11u);
145  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
146  }
147  {
148  auto uni = stage.GetUniform("u_circle2");
149  ASSERT_NE(uni, nullptr);
150  ASSERT_EQ(uni->dimensions.rows, 2u);
151  ASSERT_EQ(uni->dimensions.cols, 1u);
152  ASSERT_EQ(uni->location, 12u);
153  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
154  }
155  {
156  auto uni = stage.GetUniform("u_circle3");
157  ASSERT_NE(uni, nullptr);
158  ASSERT_EQ(uni->dimensions.rows, 2u);
159  ASSERT_EQ(uni->dimensions.cols, 1u);
160  ASSERT_EQ(uni->location, 13u);
161  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
162  }
163  {
164  auto uni = stage.GetUniform("u_rotation1");
165  ASSERT_NE(uni, nullptr);
166  ASSERT_EQ(uni->dimensions.rows, 2u);
167  ASSERT_EQ(uni->dimensions.cols, 1u);
168  ASSERT_EQ(uni->location, 14u);
169  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
170  }
171  {
172  auto uni = stage.GetUniform("u_rotation2");
173  ASSERT_NE(uni, nullptr);
174  ASSERT_EQ(uni->dimensions.rows, 2u);
175  ASSERT_EQ(uni->dimensions.cols, 1u);
176  ASSERT_EQ(uni->location, 15u);
177  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
178  }
179  {
180  auto uni = stage.GetUniform("u_rotation3");
181  ASSERT_NE(uni, nullptr);
182  ASSERT_EQ(uni->dimensions.rows, 2u);
183  ASSERT_EQ(uni->dimensions.cols, 1u);
184  ASSERT_EQ(uni->location, 16u);
185  ASSERT_EQ(uni->type, RuntimeUniformType::kFloat);
186  }
187 }

References impeller::RuntimeStage::GetUniform(), impeller::RuntimeStage::GetUniforms(), impeller::RuntimeStage::IsValid(), and impeller::kFloat.

◆ TEST() [189/202]

impeller::testing::TEST ( RuntimeStageTest  ,
CanReadValidBlob   
)

Definition at line 26 of file runtime_stage_unittests.cc.

26  {
27  auto fixture =
28  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
29  ASSERT_TRUE(fixture);
30  ASSERT_GT(fixture->GetSize(), 0u);
31  RuntimeStage stage(std::move(fixture));
32  ASSERT_TRUE(stage.IsValid());
33  ASSERT_EQ(stage.GetShaderStage(), RuntimeShaderStage::kFragment);
34 }

References impeller::RuntimeStage::GetShaderStage(), impeller::RuntimeStage::IsValid(), and impeller::kFragment.

◆ TEST() [190/202]

impeller::testing::TEST ( RuntimeStageTest  ,
CanRejectInvalidBlob   
)

Definition at line 36 of file runtime_stage_unittests.cc.

36  {
37  ScopedValidationDisable disable_validation;
38  auto fixture =
39  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
40  ASSERT_TRUE(fixture);
41  auto junk_allocation = std::make_shared<Allocation>();
42  ASSERT_TRUE(junk_allocation->Truncate(fixture->GetSize(), false));
43  // Not meant to be secure. Just reject obviously bad blobs using magic
44  // numbers.
45  ::memset(junk_allocation->GetBuffer(), 127, junk_allocation->GetLength());
46  RuntimeStage stage(CreateMappingFromAllocation(junk_allocation));
47  ASSERT_FALSE(stage.IsValid());
48 }

References impeller::CreateMappingFromAllocation(), and impeller::RuntimeStage::IsValid().

◆ TEST() [191/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientConversionNonMonotonic   
)

Definition at line 132 of file skia_conversions_unittests.cc.

132  {
133  std::vector<flutter::DlColor> colors = {
134  flutter::DlColor::kBlue(), flutter::DlColor::kGreen(),
135  flutter::DlColor::kGreen(), flutter::DlColor::kRed()};
136  std::vector<float> stops = {0.0, 0.5, 0.4, 1.0};
137  const auto gradient =
138  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
139  SkPoint::Make(1.0, 1.0), //
140  4, //
141  colors.data(), //
142  stops.data(), //
143  flutter::DlTileMode::kClamp, //
144  nullptr //
145  );
146 
147  std::vector<Color> converted_colors;
148  std::vector<Scalar> converted_stops;
149  skia_conversions::ConvertStops(gradient.get(), converted_colors,
150  converted_stops);
151 
152  // Value is clamped to 0.5
153  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
154  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
155  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 0.5f));
156  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[3], 1.0f));
157 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [192/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissing0   
)

Definition at line 54 of file skia_conversions_unittests.cc.

54  {
55  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
56  flutter::DlColor::kRed()};
57  std::vector<float> stops = {0.5, 1.0};
58  const auto gradient =
59  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
60  SkPoint::Make(1.0, 1.0), //
61  2, //
62  colors.data(), //
63  stops.data(), //
64  flutter::DlTileMode::kClamp, //
65  nullptr //
66  );
67 
68  std::vector<Color> converted_colors;
69  std::vector<Scalar> converted_stops;
70  skia_conversions::ConvertStops(gradient.get(), converted_colors,
71  converted_stops);
72 
73  // First color is inserted as blue.
74  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[0].blue, 1.0f));
75  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
76  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
77  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
78 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [193/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientMissingLastValue   
)

Definition at line 80 of file skia_conversions_unittests.cc.

80  {
81  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
82  flutter::DlColor::kRed()};
83  std::vector<float> stops = {0.0, .5};
84  const auto gradient =
85  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
86  SkPoint::Make(1.0, 1.0), //
87  2, //
88  colors.data(), //
89  stops.data(), //
90  flutter::DlTileMode::kClamp, //
91  nullptr //
92  );
93 
94  std::vector<Color> converted_colors;
95  std::vector<Scalar> converted_stops;
96  skia_conversions::ConvertStops(gradient.get(), converted_colors,
97  converted_stops);
98 
99  // Last color is inserted as red.
100  ASSERT_TRUE(ScalarNearlyEqual(converted_colors[2].red, 1.0f));
101  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
102  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
103  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
104 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [194/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopConversion   
)

Definition at line 28 of file skia_conversions_unittests.cc.

28  {
29  // Typical gradient.
30  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
31  flutter::DlColor::kRed(),
32  flutter::DlColor::kGreen()};
33  std::vector<float> stops = {0.0, 0.5, 1.0};
34  const auto gradient =
35  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
36  SkPoint::Make(1.0, 1.0), //
37  3, //
38  colors.data(), //
39  stops.data(), //
40  flutter::DlTileMode::kClamp, //
41  nullptr //
42  );
43 
44  std::vector<Color> converted_colors;
45  std::vector<Scalar> converted_stops;
46  skia_conversions::ConvertStops(gradient.get(), converted_colors,
47  converted_stops);
48 
49  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
50  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 0.5f));
51  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
52 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [195/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
GradientStopGreaterThan1   
)

Definition at line 106 of file skia_conversions_unittests.cc.

106  {
107  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
108  flutter::DlColor::kGreen(),
109  flutter::DlColor::kRed()};
110  std::vector<float> stops = {0.0, 100, 1.0};
111  const auto gradient =
112  flutter::DlColorSource::MakeLinear(SkPoint::Make(0, 0), //
113  SkPoint::Make(1.0, 1.0), //
114  3, //
115  colors.data(), //
116  stops.data(), //
117  flutter::DlTileMode::kClamp, //
118  nullptr //
119  );
120 
121  std::vector<Color> converted_colors;
122  std::vector<Scalar> converted_stops;
123  skia_conversions::ConvertStops(gradient.get(), converted_colors,
124  converted_stops);
125 
126  // Value is clamped to 1.0
127  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[0], 0.0f));
128  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[1], 1.0f));
129  ASSERT_TRUE(ScalarNearlyEqual(converted_stops[2], 1.0f));
130 }

References impeller::skia_conversions::ConvertStops(), and impeller::ScalarNearlyEqual().

◆ TEST() [196/202]

impeller::testing::TEST ( SkiaConversionsTest  ,
ToColor   
)

Definition at line 14 of file skia_conversions_unittests.cc.

14  {
15  // Create a color with alpha, red, green, and blue values that are all
16  // trivially divisible by 255 so that we can test the conversion results in
17  // correct scalar values.
18  // AARRGGBB
19  const flutter::DlColor color = flutter::DlColor(0x8040C020);
20  auto converted_color = skia_conversions::ToColor(color);
21 
22  ASSERT_TRUE(ScalarNearlyEqual(converted_color.alpha, 0x80 * (1.0f / 255)));
23  ASSERT_TRUE(ScalarNearlyEqual(converted_color.red, 0x40 * (1.0f / 255)));
24  ASSERT_TRUE(ScalarNearlyEqual(converted_color.green, 0xC0 * (1.0f / 255)));
25  ASSERT_TRUE(ScalarNearlyEqual(converted_color.blue, 0x20 * (1.0f / 255)));
26 }

References impeller::ScalarNearlyEqual(), and impeller::skia_conversions::ToColor().

◆ TEST() [197/202]

impeller::testing::TEST ( StringsTest  ,
CanSPrintF   
)

Definition at line 72 of file base_unittests.cc.

72  {
73  ASSERT_EQ(SPrintF("%sx%d", "Hello", 12), "Hellox12");
74  ASSERT_EQ(SPrintF(""), "");
75  ASSERT_EQ(SPrintF("Hello"), "Hello");
76  ASSERT_EQ(SPrintF("%sx%.2f", "Hello", 12.122222), "Hellox12.12");
77 }

References impeller::SPrintF().

◆ TEST() [198/202]

impeller::testing::TEST ( TessellatorTest  ,
TessellatorBuilderReturnsCorrectResultStatus   
)

Definition at line 14 of file tessellator_unittests.cc.

14  {
15  // Zero points.
16  {
17  Tessellator t;
18  auto polyline = PathBuilder{}.TakePath().CreatePolyline(1.0f);
19  Tessellator::Result result = t.Tessellate(
20  FillType::kPositive, polyline,
21  [](const float* vertices, size_t vertices_count,
22  const uint16_t* indices, size_t indices_count) { return true; });
23 
24  ASSERT_EQ(polyline.points.size(), 0u);
25  ASSERT_EQ(result, Tessellator::Result::kInputError);
26  }
27 
28  // One point.
29  {
30  Tessellator t;
31  auto polyline =
32  PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline(1.0f);
33  Tessellator::Result result =
34  t.Tessellate(FillType::kPositive, polyline,
35  [](const float* vertices, size_t vertices_count,
36  const uint16_t* indices_count,
37  size_t indices_size) { return true; });
38  ASSERT_EQ(polyline.points.size(), 1u);
39  ASSERT_EQ(result, Tessellator::Result::kSuccess);
40  }
41 
42  // Two points.
43  {
44  Tessellator t;
45  auto polyline =
46  PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline(1.0f);
47  Tessellator::Result result =
48  t.Tessellate(FillType::kPositive, polyline,
49  [](const float* vertices, size_t vertices_count,
50  const uint16_t* indices_count,
51  size_t indices_size) { return true; });
52 
53  ASSERT_EQ(polyline.points.size(), 2u);
54  ASSERT_EQ(result, Tessellator::Result::kSuccess);
55  }
56 
57  // Many points.
58  {
59  Tessellator t;
60  PathBuilder builder;
61  for (int i = 0; i < 1000; i++) {
62  auto coord = i * 1.0f;
63  builder.AddLine({coord, coord}, {coord + 1, coord + 1});
64  }
65  auto polyline = builder.TakePath().CreatePolyline(1.0f);
66  Tessellator::Result result =
67  t.Tessellate(FillType::kPositive, polyline,
68  [](const float* vertices, size_t vertices_count,
69  const uint16_t* indices_count,
70  size_t indices_size) { return true; });
71 
72  ASSERT_EQ(polyline.points.size(), 2000u);
73  ASSERT_EQ(result, Tessellator::Result::kSuccess);
74  }
75 
76  // Closure fails.
77  {
78  Tessellator t;
79  auto polyline =
80  PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline(1.0f);
81  Tessellator::Result result =
82  t.Tessellate(FillType::kPositive, polyline,
83  [](const float* vertices, size_t vertices_count,
84  const uint16_t* indices_count,
85  size_t indices_size) { return false; });
86 
87  ASSERT_EQ(polyline.points.size(), 2u);
88  ASSERT_EQ(result, Tessellator::Result::kInputError);
89  }
90 
91  // More than uint16 points, odd fill mode.
92  {
93  Tessellator t;
94  PathBuilder builder = {};
95  for (auto i = 0; i < 1000; i++) {
96  builder.AddCircle(Point(i, i), 4);
97  }
98  auto polyline = builder.TakePath(FillType::kOdd).CreatePolyline(1.0f);
99  bool no_indices = false;
100  size_t count = 0u;
101  Tessellator::Result result = t.Tessellate(
102  FillType::kOdd, polyline,
103  [&no_indices, &count](const float* vertices, size_t vertices_count,
104  const uint16_t* indices, size_t indices_count) {
105  no_indices = indices == nullptr;
106  count = vertices_count;
107  return true;
108  });
109 
110  ASSERT_TRUE(no_indices);
111  ASSERT_TRUE(count >= USHRT_MAX);
112  ASSERT_EQ(result, Tessellator::Result::kSuccess);
113  }
114 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddLine(), impeller::Path::CreatePolyline(), impeller::Tessellator::kInputError, impeller::kOdd, impeller::kPositive, impeller::Tessellator::kSuccess, impeller::PathBuilder::LineTo(), impeller::PathBuilder::TakePath(), and impeller::Tessellator::Tessellate().

◆ TEST() [199/202]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutex   
)

Definition at line 22 of file base_unittests.cc.

22  {
23  Foo f = {};
24 
25  // f.a = 100; <--- Static analysis error.
26  f.mtx.Lock();
27  f.a = 100;
28  f.mtx.Unlock();
29 }

References impeller::testing::Foo::mtx.

◆ TEST() [200/202]

impeller::testing::TEST ( ThreadTest  ,
CanCreateMutexLock   
)

Definition at line 31 of file base_unittests.cc.

31  {
32  Foo f = {};
33 
34  // f.a = 100; <--- Static analysis error.
35  auto a = Lock(f.mtx);
36  f.a = 100;
37 }

References impeller::testing::Foo::mtx.

◆ TEST() [201/202]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutex   
)

Definition at line 39 of file base_unittests.cc.

39  {
40  RWFoo f = {};
41 
42  // f.a = 100; <--- Static analysis error.
43  f.mtx.LockWriter();
44  f.a = 100;
45  f.mtx.UnlockWriter();
46  // int b = f.a; <--- Static analysis error.
47  f.mtx.LockReader();
48  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
49  FML_ALLOW_UNUSED_LOCAL(b);
50  f.mtx.UnlockReader();
51 }

References impeller::testing::RWFoo::mtx.

◆ TEST() [202/202]

impeller::testing::TEST ( ThreadTest  ,
CanCreateRWMutexLock   
)

Definition at line 53 of file base_unittests.cc.

53  {
54  RWFoo f = {};
55 
56  // f.a = 100; <--- Static analysis error.
57  {
58  auto write_lock = WriterLock{f.mtx};
59  f.a = 100;
60  }
61 
62  // int b = f.a; <--- Static analysis error.
63  {
64  auto read_lock = ReaderLock(f.mtx);
65  int b = f.a; // NOLINT(clang-analyzer-deadcode.DeadStores)
66  FML_ALLOW_UNUSED_LOCAL(b);
67  }
68 
69  // f.mtx.UnlockReader(); <--- Static analysis error.
70 }

References impeller::testing::RWFoo::mtx.

◆ TEST_F() [1/8]

impeller::testing::TEST_F ( ArchiveTest  ,
AddData   
)

Definition at line 118 of file archivist_unittests.cc.

118  {
119  Archive archive(GetArchiveFileName().c_str());
120  ASSERT_TRUE(archive.IsValid());
121  Sample sample;
122  ASSERT_TRUE(archive.Write(sample));
123 }

References impeller::Archive::IsValid(), and impeller::Archive::Write().

◆ TEST_F() [2/8]

impeller::testing::TEST_F ( ArchiveTest  ,
AddDataMultiple   
)

Definition at line 125 of file archivist_unittests.cc.

125  {
126  Archive archive(GetArchiveFileName().c_str());
127  ASSERT_TRUE(archive.IsValid());
128 
129  for (size_t i = 0; i < 100; i++) {
130  Sample sample(i + 1);
131  ASSERT_TRUE(archive.Write(sample));
132  }
133 }

References impeller::Archive::IsValid(), and impeller::Archive::Write().

◆ TEST_F() [3/8]

impeller::testing::TEST_F ( ArchiveTest  ,
AddStorageClass   
)

Definition at line 113 of file archivist_unittests.cc.

113  {
114  Archive archive(GetArchiveFileName().c_str());
115  ASSERT_TRUE(archive.IsValid());
116 }

References impeller::Archive::IsValid().

◆ TEST_F() [4/8]

impeller::testing::TEST_F ( ArchiveTest  ,
CanReadWriteVectorOfArchivables   
)

Definition at line 185 of file archivist_unittests.cc.

185  {
186  Archive archive(GetArchiveFileName().c_str());
187  ASSERT_TRUE(archive.IsValid());
188 
189  SampleWithVector sample_with_vector;
190  ASSERT_TRUE(archive.Write(sample_with_vector));
191  bool read_success = false;
192  ASSERT_EQ(
193  archive.Read<SampleWithVector>([&](ArchiveLocation& location) -> bool {
194  SampleWithVector other_sample_with_vector;
195  read_success = other_sample_with_vector.Read(location);
196  return true; // Always keep continuing but assert that we only get one.
197  }),
198  1u);
199  ASSERT_TRUE(read_success);
200 }

References impeller::Archive::IsValid(), impeller::Archive::Read(), and impeller::Archive::Write().

◆ TEST_F() [5/8]

impeller::testing::TEST_F ( ArchiveTest  ,
ReadData   
)

Definition at line 135 of file archivist_unittests.cc.

135  {
136  Archive archive(GetArchiveFileName().c_str());
137  ASSERT_TRUE(archive.IsValid());
138 
139  size_t count = 50;
140 
141  std::vector<PrimaryKey::value_type> keys;
142  std::vector<uint64_t> values;
143 
144  for (size_t i = 0; i < count; i++) {
145  Sample sample(i + 1);
146  keys.push_back(sample.GetPrimaryKey().value());
147  values.push_back(sample.GetSomeData());
148  ASSERT_TRUE(archive.Write(sample));
149  }
150 
151  for (size_t i = 0; i < count; i++) {
152  Sample sample;
153  ASSERT_TRUE(archive.Read(keys[i], sample));
154  ASSERT_EQ(values[i], sample.GetSomeData());
155  }
156 }

References impeller::testing::Sample::GetPrimaryKey(), impeller::testing::Sample::GetSomeData(), impeller::Archive::IsValid(), impeller::Archive::Read(), and impeller::Archive::Write().

◆ TEST_F() [6/8]

impeller::testing::TEST_F ( ArchiveTest  ,
ReadDataWithNames   
)

Definition at line 158 of file archivist_unittests.cc.

158  {
159  Archive archive(GetArchiveFileName().c_str());
160  ASSERT_TRUE(archive.IsValid());
161 
162  size_t count = 8;
163 
164  std::vector<PrimaryKey::value_type> keys;
165  std::vector<uint64_t> values;
166 
167  keys.reserve(count);
168  values.reserve(count);
169 
170  for (size_t i = 0; i < count; i++) {
171  Sample sample(i + 1);
172  keys.push_back(sample.GetPrimaryKey().value());
173  values.push_back(sample.GetSomeData());
174  ASSERT_TRUE(archive.Write(sample));
175  }
176 
177  for (size_t i = 0; i < count; i++) {
178  Sample sample;
179  ASSERT_TRUE(archive.Read(keys[i], sample));
180  ASSERT_EQ(values[i], sample.GetSomeData());
181  ASSERT_EQ(keys[i], sample.GetPrimaryKey());
182  }
183 }

References impeller::testing::Sample::GetPrimaryKey(), impeller::testing::Sample::GetSomeData(), impeller::Archive::IsValid(), impeller::Archive::Read(), and impeller::Archive::Write().

◆ TEST_F() [7/8]

impeller::testing::TEST_F ( ArchiveTest  ,
SimpleInitialization   
)

Definition at line 108 of file archivist_unittests.cc.

108  {
109  Archive archive(GetArchiveFileName().c_str());
110  ASSERT_TRUE(archive.IsValid());
111 }

References impeller::Archive::IsValid().

◆ TEST_F() [8/8]

impeller::testing::TEST_F ( GoldenTests  ,
ConicalGradient   
)

Definition at line 71 of file golden_tests.cc.

71  {
72  Canvas canvas;
73  Paint paint;
74 
75  paint.color_source = ColorSource::MakeConicalGradient(
76  {125, 125}, 125, {Color(1.0, 0.0, 0.0, 1.0), Color(0.0, 0.0, 1.0, 1.0)},
77  {0, 1}, {180, 180}, 0, Entity::TileMode::kClamp, {});
78 
79  paint.stroke_width = 0.0;
80  paint.style = Paint::Style::kFill;
81  canvas.DrawRect(Rect(10, 10, 250, 250), paint);
82  Picture picture = canvas.EndRecordingAsPicture();
83 
84  auto aiks_context =
85  AiksContext(Screenshoter().GetPlayground().GetContext(), nullptr);
86  auto screenshot = Screenshoter().MakeScreenshot(aiks_context, picture);
87  ASSERT_TRUE(SaveScreenshot(std::move(screenshot)));
88 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Paint::kFill, impeller::ColorSource::MakeConicalGradient(), impeller::Paint::stroke_width, and impeller::Paint::style.

◆ TEST_P() [1/317]

impeller::testing::TEST_P ( AiksTest  ,
BlendModeShouldCoverWholeScreen   
)

Definition at line 1022 of file aiks_unittests.cc.

1022  {
1023  Canvas canvas;
1024  Paint paint;
1025 
1026  paint.color = Color::Red();
1027  canvas.DrawPaint(paint);
1028 
1029  paint.blend_mode = BlendMode::kSourceOver;
1030  canvas.SaveLayer(paint);
1031 
1032  paint.color = Color::White();
1033  canvas.DrawRect({100, 100, 400, 400}, paint);
1034 
1035  paint.blend_mode = BlendMode::kSource;
1036  canvas.SaveLayer(paint);
1037 
1038  paint.color = Color::Blue();
1039  canvas.DrawRect({200, 200, 200, 200}, paint);
1040 
1041  canvas.Restore();
1042  canvas.Restore();
1043 
1044  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1045 }

References impeller::Paint::blend_mode, impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kSource, impeller::kSourceOver, impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::White().

◆ TEST_P() [2/317]

impeller::testing::TEST_P ( AiksTest  ,
CanCanvasDrawPicture   
)

Definition at line 3203 of file aiks_unittests.cc.

3203  {
3204  Canvas subcanvas;
3205  subcanvas.DrawRect(Rect::MakeLTRB(-100, -50, 100, 50),
3206  {.color = Color::CornflowerBlue()});
3207  auto picture = subcanvas.EndRecordingAsPicture();
3208 
3209  Canvas canvas;
3210  canvas.Translate({200, 200});
3211  canvas.Rotate(Radians(kPi / 4));
3212  canvas.DrawPicture(picture);
3213 
3214  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3215 }

References impeller::Canvas::DrawPicture(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::Canvas::Rotate(), and impeller::Canvas::Translate().

◆ TEST_P() [3/317]

impeller::testing::TEST_P ( AiksTest  ,
CanCanvasDrawPictureWithAdvancedBlend   
)

Definition at line 3217 of file aiks_unittests.cc.

3217  {
3218  Canvas subcanvas;
3219  subcanvas.DrawRect(
3220  Rect::MakeLTRB(-100, -50, 100, 50),
3221  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kColorDodge});
3222  auto picture = subcanvas.EndRecordingAsPicture();
3223 
3224  Canvas canvas;
3225  canvas.DrawPaint({.color = Color::Black()});
3226  canvas.DrawCircle(Point::MakeXY(150, 150), 25, {.color = Color::Red()});
3227  canvas.DrawPicture(picture);
3228 
3229  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3230 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), impeller::Canvas::DrawRect(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [4/317]

impeller::testing::TEST_P ( AiksTest  ,
CanCanvasDrawPictureWithBackdropFilter   
)

Definition at line 3232 of file aiks_unittests.cc.

3232  {
3233  Canvas subcanvas;
3234  subcanvas.SaveLayer({}, {},
3235  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
3236  FilterContents::BlurStyle::kNormal,
3237  Entity::TileMode::kDecal));
3238  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
3239  Paint paint;
3240  paint.color = Color::Red().WithAlpha(0.5);
3241  subcanvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
3242 
3243  auto picture = subcanvas.EndRecordingAsPicture();
3244 
3245  Canvas canvas;
3246  canvas.DrawPaint({.color = Color::Black()});
3247  canvas.DrawCircle(Point::MakeXY(150, 150), 25, {.color = Color::Red()});
3248  canvas.DrawPicture(picture);
3249 
3250  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3251 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [5/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPath   
)

Definition at line 1237 of file aiks_unittests.cc.

1237  {
1238  Canvas canvas;
1239 
1240  // Starting at (50, 50), draw lines from:
1241  // 1. (50, height)
1242  // 2. (width, height)
1243  // 3. (width, 50)
1244  PathBuilder builder;
1245  builder.MoveTo({50, 50});
1246  builder.LineTo({50, 100});
1247  builder.LineTo({100, 100});
1248  builder.LineTo({100, 50});
1249 
1250  Paint paint;
1251  paint.color = Color::Red();
1252  paint.style = Paint::Style::kStroke;
1253  paint.stroke_width = 10;
1254 
1255  canvas.DrawPath(builder.TakePath(), paint);
1256 
1257  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1258 }

References impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::PathBuilder::TakePath().

◆ TEST_P() [6/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawAnOpenPathThatIsntARect   
)

Definition at line 1260 of file aiks_unittests.cc.

1260  {
1261  Canvas canvas;
1262 
1263  // Draw a stroked path that is explicitly closed to verify
1264  // It doesn't become a rectangle.
1265  PathBuilder builder;
1266  builder.MoveTo({50, 50});
1267  builder.LineTo({520, 120});
1268  builder.LineTo({300, 310});
1269  builder.LineTo({100, 50});
1270  builder.Close();
1271 
1272  Paint paint;
1273  paint.color = Color::Red();
1274  paint.style = Paint::Style::kStroke;
1275  paint.stroke_width = 10;
1276 
1277  canvas.DrawPath(builder.TakePath(), paint);
1278 
1279  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1280 }

References impeller::PathBuilder::Close(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::PathBuilder::LineTo(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::PathBuilder::TakePath().

◆ TEST_P() [7/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaint   
)

Definition at line 1542 of file aiks_unittests.cc.

1542  {
1543  Canvas canvas;
1544  canvas.Scale(Vector2(0.2, 0.2));
1545  canvas.DrawPaint({.color = Color::MediumTurquoise()});
1546  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1547 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [8/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimes   
)

Definition at line 1549 of file aiks_unittests.cc.

1549  {
1550  Canvas canvas;
1551  canvas.Scale(Vector2(0.2, 0.2));
1552  canvas.DrawPaint({.color = Color::MediumTurquoise()});
1553  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5)});
1554  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1555 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [9/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintMultipleTimesInteractive   
)

Definition at line 1627 of file aiks_unittests.cc.

1627  {
1628  auto modes = GetBlendModeSelection();
1629 
1630  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1631  static Color background = Color::MediumTurquoise();
1632  static Color foreground = Color::Color::OrangeRed().WithAlpha(0.5);
1633  static int current_blend_index = 3;
1634 
1635  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1636  {
1637  ImGui::ColorEdit4("Background", reinterpret_cast<float*>(&background));
1638  ImGui::ColorEdit4("Foreground", reinterpret_cast<float*>(&foreground));
1639  ImGui::ListBox("Blend mode", &current_blend_index,
1640  modes.blend_mode_names.data(),
1641  modes.blend_mode_names.size());
1642  }
1643  ImGui::End();
1644 
1645  Canvas canvas;
1646  canvas.Scale(Vector2(0.2, 0.2));
1647  canvas.DrawPaint({.color = background});
1648  canvas.DrawPaint(
1649  {.color = foreground,
1650  .blend_mode = static_cast<BlendMode>(current_blend_index)});
1651  return canvas.EndRecordingAsPicture();
1652  };
1653  ASSERT_TRUE(OpenPlaygroundHere(callback));
1654 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::Canvas::Scale(), and impeller::Color::WithAlpha().

◆ TEST_P() [10/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPaintWithAdvancedBlend   
)

Definition at line 1557 of file aiks_unittests.cc.

1557  {
1558  Canvas canvas;
1559  canvas.Scale(Vector2(0.2, 0.2));
1560  canvas.DrawPaint({.color = Color::MediumTurquoise()});
1561  canvas.DrawPaint({.color = Color::Color::OrangeRed().WithAlpha(0.5),
1562  .blend_mode = BlendMode::kHue});
1563  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1564 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [11/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPoints   
)

Definition at line 3044 of file aiks_unittests.cc.

3044  {
3045  std::vector<Point> points = {
3046  {0, 0}, //
3047  {100, 100}, //
3048  {100, 0}, //
3049  {0, 100}, //
3050  {0, 0}, //
3051  {48, 48}, //
3052  {52, 52}, //
3053  };
3054  std::vector<PointStyle> caps = {
3055  PointStyle::kRound,
3056  PointStyle::kSquare,
3057  };
3058  Paint paint;
3059  paint.color = Color::Yellow().WithAlpha(0.5);
3060 
3061  Paint background;
3062  background.color = Color::Black();
3063 
3064  Canvas canvas;
3065  canvas.DrawPaint(background);
3066  canvas.Translate({200, 200});
3067  canvas.DrawPoints(points, 10, paint, PointStyle::kRound);
3068  canvas.Translate({150, 0});
3069  canvas.DrawPoints(points, 10, paint, PointStyle::kSquare);
3070 
3071  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3072 }

References impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPoints(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [12/317]

impeller::testing::TEST_P ( AiksTest  ,
CanDrawPointsWithTextureMap   
)

Definition at line 3138 of file aiks_unittests.cc.

3138  {
3139  auto texture = CreateTextureForFixture("table_mountain_nx.png",
3140  /*enable_mipmapping=*/true);
3141 
3142  std::vector<Point> points = {
3143  {0, 0}, //
3144  {100, 100}, //
3145  {100, 0}, //
3146  {0, 100}, //
3147  {0, 0}, //
3148  {48, 48}, //
3149  {52, 52}, //
3150  };
3151  std::vector<PointStyle> caps = {
3152  PointStyle::kRound,
3153  PointStyle::kSquare,
3154  };
3155  Paint paint;
3156  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
3157  Entity::TileMode::kClamp, {}, {});
3158 
3159  Canvas canvas;
3160  canvas.Translate({200, 200});
3161  canvas.DrawPoints(points, 100, paint, PointStyle::kRound);
3162  canvas.Translate({150, 0});
3163  canvas.DrawPoints(points, 100, paint, PointStyle::kSquare);
3164 
3165  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3166 }

References impeller::Paint::color_source, and impeller::Canvas::Translate().

◆ TEST_P() [13/317]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformFullScreenMSAA   
)

Definition at line 1112 of file aiks_unittests.cc.

1112  {
1113  Canvas canvas;
1114 
1115  Paint red;
1116  red.color = Color::Red();
1117 
1118  canvas.DrawCircle({250, 250}, 125, red);
1119 
1120  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1121 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Color::Red().

◆ TEST_P() [14/317]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBounds   
)

Definition at line 1135 of file aiks_unittests.cc.

1135  {
1136  Canvas canvas;
1137 
1138  Paint red;
1139  red.color = Color::Red();
1140 
1141  Paint green;
1142  green.color = Color::Green();
1143 
1144  Paint blue;
1145  blue.color = Color::Blue();
1146 
1147  Paint save;
1148  save.color = Color::Black();
1149 
1150  canvas.SaveLayer(save, Rect{0, 0, 50, 50});
1151 
1152  canvas.DrawRect({0, 0, 100, 100}, red);
1153  canvas.DrawRect({10, 10, 100, 100}, green);
1154  canvas.DrawRect({20, 20, 100, 100}, blue);
1155 
1156  canvas.Restore();
1157 
1158  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1159 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Red(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [15/317]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated   
)

Definition at line 1161 of file aiks_unittests.cc.

1162  {
1163  Canvas canvas;
1164 
1165  Paint red;
1166  red.color = Color::Red();
1167 
1168  Paint green;
1169  green.color = Color::Green();
1170 
1171  Paint blue;
1172  blue.color = Color::Blue();
1173 
1174  Paint save;
1175  save.color = Color::Black().WithAlpha(0.5);
1176 
1177  canvas.SaveLayer(save, Rect{0, 0, 100000, 100000});
1178 
1179  canvas.DrawRect({0, 0, 100, 100}, red);
1180  canvas.DrawRect({10, 10, 100, 100}, green);
1181  canvas.DrawRect({20, 20, 100, 100}, blue);
1182 
1183  canvas.Restore();
1184 
1185  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1186 }

References impeller::Color::Black(), impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [16/317]

impeller::testing::TEST_P ( AiksTest  ,
CanPerformSkew   
)

Definition at line 1123 of file aiks_unittests.cc.

1123  {
1124  Canvas canvas;
1125 
1126  Paint red;
1127  red.color = Color::Red();
1128 
1129  canvas.Skew(2, 5);
1130  canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red);
1131 
1132  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1133 }

References impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), and impeller::Canvas::Skew().

◆ TEST_P() [17/317]

impeller::testing::TEST_P ( AiksTest  ,
CanPictureConvertToImage   
)

Definition at line 999 of file aiks_unittests.cc.

999  {
1000  Canvas recorder_canvas;
1001  Paint paint;
1002  paint.color = Color{0.9568, 0.2627, 0.2118, 1.0};
1003  recorder_canvas.DrawRect({100.0, 100.0, 600, 600}, paint);
1004  paint.color = Color{0.1294, 0.5882, 0.9529, 1.0};
1005  recorder_canvas.DrawRect({200.0, 200.0, 600, 600}, paint);
1006 
1007  Canvas canvas;
1008  AiksContext renderer(GetContext(), nullptr);
1009  paint.color = Color::BlackTransparent();
1010  canvas.DrawPaint(paint);
1011  Picture picture = recorder_canvas.EndRecordingAsPicture();
1012  auto image = picture.ToImage(renderer, ISize{1000, 1000});
1013  if (image) {
1014  canvas.DrawImage(image, Point(), Paint());
1015  paint.color = Color{0.1, 0.1, 0.1, 0.2};
1016  canvas.DrawRect(Rect::MakeSize(ISize{1000, 1000}), paint);
1017  }
1018 
1019  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1020 }

References impeller::Color::BlackTransparent(), impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeSize(), and impeller::Picture::ToImage().

◆ TEST_P() [18/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlur   
)

Definition at line 2894 of file aiks_unittests.cc.

2894  {
2895  Canvas canvas;
2896  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
2897  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
2898  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
2899  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
2900  canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), 20);
2901  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2902  ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0),
2903  FilterContents::BlurStyle::kNormal,
2904  Entity::TileMode::kClamp));
2905  canvas.Restore();
2906 
2907  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2908 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [19/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurHugeSigma   
)

Definition at line 2910 of file aiks_unittests.cc.

2910  {
2911  Canvas canvas;
2912  canvas.DrawCircle({400, 400}, 300, {.color = Color::Green()});
2913  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2914  ImageFilter::MakeBlur(Sigma(999999), Sigma(999999),
2915  FilterContents::BlurStyle::kNormal,
2916  Entity::TileMode::kClamp));
2917  canvas.Restore();
2918 
2919  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2920 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [20/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderBackdropBlurInteractive   
)

Definition at line 2871 of file aiks_unittests.cc.

2871  {
2872  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
2873  auto [a, b] = IMPELLER_PLAYGROUND_LINE(Point(50, 50), Point(300, 200), 30,
2874  Color::White(), Color::White());
2875 
2876  Canvas canvas;
2877  canvas.DrawCircle({100, 100}, 50, {.color = Color::CornflowerBlue()});
2878  canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()});
2879  canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()});
2880  canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()});
2881  canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), 20);
2882  canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt,
2883  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2884  FilterContents::BlurStyle::kNormal,
2885  Entity::TileMode::kClamp));
2886  canvas.Restore();
2887 
2888  return canvas.EndRecordingAsPicture();
2889  };
2890 
2891  ASSERT_TRUE(OpenPlaygroundHere(callback));
2892 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), IMPELLER_PLAYGROUND_LINE, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [21/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedBlur   
)

Definition at line 2922 of file aiks_unittests.cc.

2922  {
2923  Canvas canvas;
2924  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2925  canvas.DrawCircle(
2926  {400, 400}, 200,
2927  {
2928  .color = Color::Green(),
2929  .image_filter = ImageFilter::MakeBlur(
2930  Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal,
2931  Entity::TileMode::kClamp),
2932  });
2933  canvas.Restore();
2934 
2935  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2936 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Restore().

◆ TEST_P() [22/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedLayers   
)

Definition at line 2093 of file aiks_unittests.cc.

2093  {
2094  Canvas canvas;
2095 
2096  canvas.DrawPaint({.color = Color::White()});
2097 
2098  // Draw a green circle on the screen.
2099  {
2100  // Increase the clip depth for the savelayer to contend with.
2101  canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath());
2102 
2103  canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100));
2104 
2105  // Fill the layer with white.
2106  canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()});
2107  // Fill the layer with green, but do so with a color blend that can't be
2108  // collapsed into the parent pass.
2109  // TODO(jonahwilliams): this blend mode was changed from color burn to
2110  // hardlight to work around https://github.com/flutter/flutter/issues/136554
2111  // .
2112  canvas.DrawRect(
2113  Rect::MakeSize(Size{400, 400}),
2114  {.color = Color::Green(), .blend_mode = BlendMode::kHardLight});
2115  }
2116 
2117  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2118 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [23/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClippedRuntimeEffects   
)

Definition at line 2981 of file aiks_unittests.cc.

2981  {
2982  if (GetParam() != PlaygroundBackend::kMetal) {
2983  GTEST_SKIP_("This backend doesn't support runtime effects.");
2984  }
2985 
2986  auto runtime_stage =
2987  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2988  ASSERT_TRUE(runtime_stage->IsDirty());
2989 
2990  struct FragUniforms {
2991  Vector2 iResolution;
2992  Scalar iTime;
2993  } frag_uniforms = {.iResolution = Vector2(400, 400), .iTime = 100.0};
2994  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2995  uniform_data->resize(sizeof(FragUniforms));
2996  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2997 
2998  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
2999 
3000  Paint paint;
3001  paint.color_source = ColorSource::MakeRuntimeEffect(
3002  runtime_stage, uniform_data, texture_inputs);
3003 
3004  Canvas canvas;
3005  canvas.Save();
3006  canvas.ClipRRect(Rect{0, 0, 400, 400}, 10.0,
3007  Entity::ClipOperation::kIntersect);
3008  canvas.DrawRect(Rect{0, 0, 400, 400}, paint);
3009  canvas.Restore();
3010 
3011  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3012 }

References impeller::Canvas::ClipRRect(), impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::Save().

◆ TEST_P() [24/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderClips   
)

Definition at line 249 of file aiks_unittests.cc.

249  {
250  Canvas canvas;
251  Paint paint;
252  paint.color = Color::Fuchsia();
253  canvas.ClipPath(
254  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 500, 500)).TakePath());
255  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
256  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
257 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Fuchsia(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [25/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderColoredRect   
)

Definition at line 106 of file aiks_unittests.cc.

106  {
107  Canvas canvas;
108  Paint paint;
109  paint.color = Color::Blue();
110  canvas.DrawPath(PathBuilder{}
111  .AddRect(Rect::MakeXYWH(100.0, 100.0, 100.0, 100.0))
112  .TakePath(),
113  paint);
114  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
115 }

References impeller::PathBuilder::AddRect(), impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [26/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradient   
)

Definition at line 899 of file aiks_unittests.cc.

899  {
900  Scalar size = 256;
901  Canvas canvas;
902  Paint paint;
903  paint.color = Color::White();
904  canvas.DrawRect({0, 0, size * 3, size * 3}, paint);
905  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
906  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
907  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
908  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
909  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
910  std::array<std::tuple<Point, float, Point, float>, 8> array{
911  std::make_tuple(Point{size / 2.f, size / 2.f}, 0.f,
912  Point{size / 2.f, size / 2.f}, size / 2.f),
913  std::make_tuple(Point{size / 2.f, size / 2.f}, size / 4.f,
914  Point{size / 2.f, size / 2.f}, size / 2.f),
915  std::make_tuple(Point{size / 4.f, size / 4.f}, 0.f,
916  Point{size / 2.f, size / 2.f}, size / 2.f),
917  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 2.f,
918  Point{size / 2.f, size / 2.f}, 0),
919  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 4.f,
920  Point{size / 2.f, size / 2.f}, size / 2.f),
921  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 16.f,
922  Point{size / 2.f, size / 2.f}, size / 8.f),
923  std::make_tuple(Point{size / 4.f, size / 4.f}, size / 8.f,
924  Point{size / 2.f, size / 2.f}, size / 16.f),
925  std::make_tuple(Point{size / 8.f, size / 8.f}, size / 8.f,
926  Point{size / 2.f, size / 2.f}, size / 8.f),
927  };
928  for (int i = 0; i < 8; i++) {
929  canvas.Save();
930  canvas.Translate({(i % 3) * size, i / 3 * size, 0});
931  paint.color_source = ColorSource::MakeConicalGradient(
932  std::get<0>(array[i]), std::get<1>(array[i]), colors, stops,
933  std::get<2>(array[i]), std::get<3>(array[i]), Entity::TileMode::kClamp,
934  {});
935  canvas.DrawRect({0, 0, size, size}, paint);
936  canvas.Restore();
937  }
938  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
939 }

References impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::ColorSource::MakeConicalGradient(), impeller::Color::MakeRGBA8(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [27/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithDitheringDisabled   
)

Definition at line 530 of file aiks_unittests.cc.

530  {
532 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [28/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderConicalGradientWithDitheringEnabled   
)

Definition at line 534 of file aiks_unittests.cc.

534  {
536 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [29/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderCurvedStrokes   
)

Definition at line 239 of file aiks_unittests.cc.

239  {
240  Canvas canvas;
241  Paint paint;
242  paint.color = Color::Red();
243  paint.stroke_width = 25.0;
244  paint.style = Paint::Style::kStroke;
245  canvas.DrawPath(PathBuilder{}.AddCircle({500, 500}, 250).TakePath(), paint);
246  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
247 }

References impeller::PathBuilder::AddCircle(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::Color::Red(), impeller::Paint::stroke_width, and impeller::Paint::style.

◆ TEST_P() [30/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDestructiveSaveLayer   
)

Definition at line 2844 of file aiks_unittests.cc.

2844  {
2845  Canvas canvas;
2846 
2847  canvas.DrawPaint({.color = Color::Red()});
2848  // Draw an empty savelayer with a destructive blend mode, which will replace
2849  // the entire red screen with fully transparent black, except for the green
2850  // circle drawn within the layer.
2851  canvas.SaveLayer({.blend_mode = BlendMode::kSource});
2852  canvas.DrawCircle({300, 300}, 100, {.color = Color::Green()});
2853  canvas.Restore();
2854 
2855  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2856 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [31/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferenceClips   
)

Definition at line 272 of file aiks_unittests.cc.

272  {
273  Paint paint;
274  Canvas canvas;
275  canvas.Translate({400, 400});
276 
277  // Limit drawing to face circle with a clip.
278  canvas.ClipPath(PathBuilder{}.AddCircle(Point(), 200).TakePath());
279  canvas.Save();
280 
281  // Cut away eyes/mouth using difference clips.
282  canvas.ClipPath(PathBuilder{}.AddCircle({-100, -50}, 30).TakePath(),
283  Entity::ClipOperation::kDifference);
284  canvas.ClipPath(PathBuilder{}.AddCircle({100, -50}, 30).TakePath(),
285  Entity::ClipOperation::kDifference);
286  canvas.ClipPath(PathBuilder{}
287  .AddQuadraticCurve({-100, 50}, {0, 150}, {100, 50})
288  .TakePath(),
289  Entity::ClipOperation::kDifference);
290 
291  // Draw a huge yellow rectangle to prove the clipping works.
292  paint.color = Color::Yellow();
293  canvas.DrawRect(Rect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
294 
295  // Remove the difference clips and draw hair that partially covers the eyes.
296  canvas.Restore();
297  paint.color = Color::Maroon();
298  canvas.DrawPath(PathBuilder{}
299  .MoveTo({200, -200})
300  .HorizontalLineTo(-200)
301  .VerticalLineTo(-40)
302  .CubicCurveTo({0, -40}, {0, -80}, {200, -80})
303  .TakePath(),
304  paint);
305 
306  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
307 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddQuadraticCurve(), impeller::Canvas::ClipPath(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDifference, impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Maroon(), impeller::PathBuilder::MoveTo(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::Yellow().

◆ TEST_P() [32/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferencePaths   
)

Definition at line 1208 of file aiks_unittests.cc.

1208  {
1209  Canvas canvas;
1210 
1211  Paint paint;
1212  paint.color = Color::Red();
1213 
1214  PathBuilder builder;
1215 
1216  PathBuilder::RoundingRadii radii;
1217  radii.top_left = {50, 25};
1218  radii.top_right = {25, 50};
1219  radii.bottom_right = {50, 25};
1220  radii.bottom_left = {25, 50};
1221 
1222  builder.AddRoundedRect({100, 100, 200, 200}, radii);
1223  builder.AddCircle({200, 200}, 50);
1224  auto path = builder.TakePath(FillType::kOdd);
1225 
1226  canvas.DrawImage(
1227  std::make_shared<Image>(CreateTextureForFixture("boston.jpg")), {10, 10},
1228  Paint{});
1229  canvas.DrawPath(path, paint);
1230 
1231  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1232 }

References impeller::PathBuilder::AddCircle(), impeller::PathBuilder::AddRoundedRect(), impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kOdd, impeller::Color::Red(), impeller::PathBuilder::TakePath(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [33/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderDifferentShapesWithSameColorSource   
)

Definition at line 972 of file aiks_unittests.cc.

972  {
973  Canvas canvas;
974  Paint paint;
975 
976  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
977  Color{0.1294, 0.5882, 0.9529, 1.0}};
978  std::vector<Scalar> stops = {
979  0.0,
980  1.0,
981  };
982 
983  paint.color_source = ColorSource::MakeLinearGradient(
984  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
985  Entity::TileMode::kRepeat, {});
986 
987  canvas.Save();
988  canvas.Translate({100, 100, 0});
989  canvas.DrawRect({0, 0, 200, 200}, paint);
990  canvas.Restore();
991 
992  canvas.Save();
993  canvas.Translate({100, 400, 0});
994  canvas.DrawCircle({100, 100}, 100, paint);
995  canvas.Restore();
996  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
997 }

References impeller::Paint::color_source, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Translate().

◆ TEST_P() [34/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrame   
)

Definition at line 1438 of file aiks_unittests.cc.

1438  {
1439  Canvas canvas;
1440  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1441 
1442  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas,
1443  "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
1444 #if FML_OS_MACOSX
1445  "Apple Color Emoji.ttc"));
1446 #else
1447  "NotoColorEmoji.ttf"));
1448 #endif
1449  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1450 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [35/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderEmojiTextFrameWithAlpha   
)

Definition at line 1452 of file aiks_unittests.cc.

1452  {
1453  Canvas canvas;
1454  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1455 
1456  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas,
1457  "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊",
1458 #if FML_OS_MACOSX
1459  "Apple Color Emoji.ttc", { .alpha = 0.5 }
1460 #else
1461  "NotoColorEmoji.ttf", {.alpha = 0.5}
1462 #endif
1463  ));
1464  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1465 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [36/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundAdvancedBlendWithMaskBlur   
)

Definition at line 2959 of file aiks_unittests.cc.

2959  {
2960  // This case triggers the ForegroundAdvancedBlend path. The color filter
2961  // should apply to the color only, and respect the alpha mask.
2962  Canvas canvas;
2963  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2964  canvas.DrawCircle({400, 400}, 200,
2965  {
2966  .color = Color::Grey(),
2967  .color_filter = ColorFilter::MakeBlend(
2968  BlendMode::kColor, Color::Green()),
2969  .mask_blur_descriptor =
2970  Paint::MaskBlurDescriptor{
2971  .style = FilterContents::BlurStyle::kNormal,
2972  .sigma = Radius(20),
2973  },
2974  });
2975  canvas.Restore();
2976 
2977  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2978 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::kColor, impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [37/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderForegroundBlendWithMaskBlur   
)

Definition at line 2938 of file aiks_unittests.cc.

2938  {
2939  // This case triggers the ForegroundPorterDuffBlend path. The color filter
2940  // should apply to the color only, and respect the alpha mask.
2941  Canvas canvas;
2942  canvas.ClipRect(Rect::MakeXYWH(100, 150, 400, 400));
2943  canvas.DrawCircle({400, 400}, 200,
2944  {
2945  .color = Color::White(),
2946  .color_filter = ColorFilter::MakeBlend(
2947  BlendMode::kSource, Color::Green()),
2948  .mask_blur_descriptor =
2949  Paint::MaskBlurDescriptor{
2950  .style = FilterContents::BlurStyle::kNormal,
2951  .sigma = Radius(20),
2952  },
2953  });
2954  canvas.Restore();
2955 
2956  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2957 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [38/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGradientDecalWithBackground   
)

Definition at line 941 of file aiks_unittests.cc.

941  {
942  std::vector<Color> colors = {Color::MakeRGBA8(0xF4, 0x43, 0x36, 0xFF),
943  Color::MakeRGBA8(0xFF, 0xEB, 0x3B, 0xFF),
944  Color::MakeRGBA8(0x4c, 0xAF, 0x50, 0xFF),
945  Color::MakeRGBA8(0x21, 0x96, 0xF3, 0xFF)};
946  std::vector<Scalar> stops = {0.0, 1.f / 3.f, 2.f / 3.f, 1.0};
947 
948  std::array<ColorSource, 3> color_sources = {
949  ColorSource::MakeLinearGradient({0, 0}, {100, 100}, colors, stops,
950  Entity::TileMode::kDecal, {}),
951  ColorSource::MakeRadialGradient({100, 100}, 100, colors, stops,
952  Entity::TileMode::kDecal, {}),
953  ColorSource::MakeSweepGradient({100, 100}, Degrees(45), Degrees(135),
954  colors, stops, Entity::TileMode::kDecal,
955  {}),
956  };
957 
958  Canvas canvas;
959  Paint paint;
960  paint.color = Color::White();
961  canvas.DrawRect(Rect::MakeLTRB(0, 0, 605, 205), paint);
962  for (int i = 0; i < 3; i++) {
963  canvas.Save();
964  canvas.Translate({i * 200.0f, 0, 0});
965  paint.color_source = color_sources[i];
966  canvas.DrawRect(Rect::MakeLTRB(0, 0, 200, 200), paint);
967  canvas.Restore();
968  }
969  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
970 }

References impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kDecal, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), impeller::ColorSource::MakeRadialGradient(), impeller::Color::MakeRGBA8(), impeller::ColorSource::MakeSweepGradient(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::White().

◆ TEST_P() [39/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderGroupOpacity   
)

Definition at line 1047 of file aiks_unittests.cc.

1047  {
1048  Canvas canvas;
1049 
1050  Paint red;
1051  red.color = Color::Red();
1052  Paint green;
1053  green.color = Color::Green().WithAlpha(0.5);
1054  Paint blue;
1055  blue.color = Color::Blue();
1056 
1057  Paint alpha;
1058  alpha.color = Color::Red().WithAlpha(0.5);
1059 
1060  canvas.SaveLayer(alpha);
1061 
1062  canvas.DrawRect({000, 000, 100, 100}, red);
1063  canvas.DrawRect({020, 020, 100, 100}, green);
1064  canvas.DrawRect({040, 040, 100, 100}, blue);
1065 
1066  canvas.Restore();
1067 
1068  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1069 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [40/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImage   
)

Definition at line 117 of file aiks_unittests.cc.

117  {
118  Canvas canvas;
119  Paint paint;
120  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
121  paint.color = Color::Red();
122  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
123  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
124 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::TPoint< Scalar >::MakeXY(), and impeller::Color::Red().

◆ TEST_P() [41/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderImageRect   
)

Definition at line 212 of file aiks_unittests.cc.

212  {
213  Canvas canvas;
214  Paint paint;
215  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
216  auto source_rect = Rect::MakeSize(Size(image->GetSize()));
217 
218  // Render the bottom right quarter of the source image in a stretched rect.
219  source_rect.size.width /= 2;
220  source_rect.size.height /= 2;
221  source_rect.origin.x += source_rect.size.width;
222  source_rect.origin.y += source_rect.size.height;
223  canvas.DrawImageRect(image, source_rect, Rect::MakeXYWH(100, 100, 600, 600),
224  paint);
225  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
226 }

References impeller::Canvas::DrawImageRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::TRect< Scalar >::MakeSize(), and impeller::TRect< Scalar >::MakeXYWH().

◆ TEST_P() [42/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderInvertedImage   
)

Definition at line 126 of file aiks_unittests.cc.

126  {
127  Canvas canvas;
128  Paint paint;
129  auto image = std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
130  paint.color = Color::Red();
131  paint.invert_colors = true;
132  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
133  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
134 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::invert_colors, impeller::TPoint< Scalar >::MakeXY(), and impeller::Color::Red().

◆ TEST_P() [43/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderItalicizedText   
)

Definition at line 1428 of file aiks_unittests.cc.

1428  {
1429  Canvas canvas;
1430  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1431 
1432  ASSERT_TRUE(RenderTextInCanvasSkia(
1433  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1434  "HomemadeApple.ttf"));
1435  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1436 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [44/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientClamp   
)

Definition at line 388 of file aiks_unittests.cc.

388  {
389  CanRenderLinearGradient(this, Entity::TileMode::kClamp);
390 }

References impeller::Entity::kClamp.

◆ TEST_P() [45/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecal   
)

Definition at line 397 of file aiks_unittests.cc.

397  {
398  CanRenderLinearGradient(this, Entity::TileMode::kDecal);
399 }

References impeller::Entity::kDecal.

◆ TEST_P() [46/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientDecalWithColorFilter   
)

Definition at line 401 of file aiks_unittests.cc.

401  {
402  Canvas canvas;
403  canvas.Scale(GetContentScale());
404  Paint paint;
405  canvas.Translate({100.0f, 0, 0});
406 
407  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
408  Color{0.1294, 0.5882, 0.9529, 0.0}};
409  std::vector<Scalar> stops = {0.0, 1.0};
410 
411  paint.color_source = ColorSource::MakeLinearGradient(
412  {0, 0}, {200, 200}, std::move(colors), std::move(stops),
413  Entity::TileMode::kDecal, {});
414  // Overlay the gradient with 25% green. This should appear as the entire
415  // rectangle being drawn with 25% green, including the border area outside the
416  // decal gradient.
417  paint.color_filter = ColorFilter::MakeBlend(BlendMode::kSourceOver,
418  Color::Green().WithAlpha(0.25));
419 
420  paint.color = Color(1.0, 1.0, 1.0, 1.0);
421  canvas.DrawRect({0, 0, 600, 600}, paint);
422  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
423 }

References impeller::Paint::color, impeller::Paint::color_filter, impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::Entity::kDecal, impeller::kSourceOver, impeller::ColorFilter::MakeBlend(), impeller::ColorSource::MakeLinearGradient(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [47/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsClamp   
)

Definition at line 600 of file aiks_unittests.cc.

600  {
601  CanRenderLinearGradientManyColors(this, Entity::TileMode::kClamp);
602 }

References impeller::Entity::kClamp.

◆ TEST_P() [48/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsDecal   
)

Definition at line 609 of file aiks_unittests.cc.

609  {
610  CanRenderLinearGradientManyColors(this, Entity::TileMode::kDecal);
611 }

References impeller::Entity::kDecal.

◆ TEST_P() [49/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsMirror   
)

Definition at line 606 of file aiks_unittests.cc.

606  {
607  CanRenderLinearGradientManyColors(this, Entity::TileMode::kMirror);
608 }

References impeller::Entity::kMirror.

◆ TEST_P() [50/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsRepeat   
)

Definition at line 603 of file aiks_unittests.cc.

603  {
604  CanRenderLinearGradientManyColors(this, Entity::TileMode::kRepeat);
605 }

References impeller::Entity::kRepeat.

◆ TEST_P() [51/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientManyColorsUnevenStops   
)

Definition at line 643 of file aiks_unittests.cc.

643  {
644  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
645  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
646  const Entity::TileMode tile_modes[] = {
647  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
648  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
649 
650  static int selected_tile_mode = 0;
651  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
652  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
653  sizeof(tile_mode_names) / sizeof(char*));
654  static Matrix matrix = {
655  1, 0, 0, 0, //
656  0, 1, 0, 0, //
657  0, 0, 1, 0, //
658  0, 0, 0, 1 //
659  };
660  std::string label = "##1";
661  for (int i = 0; i < 4; i++) {
662  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
663  4, NULL, NULL, "%.2f", 0);
664  label[2]++;
665  }
666  ImGui::End();
667 
668  Canvas canvas;
669  Paint paint;
670  canvas.Translate({100.0, 100.0, 0});
671  auto tile_mode = tile_modes[selected_tile_mode];
672 
673  std::vector<Color> colors = {
674  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
675  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
676  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
677  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
678  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
679  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
680  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
681  std::vector<Scalar> stops = {
682  0.0, 2.0 / 62.0, 4.0 / 62.0, 8.0 / 62.0, 16.0 / 62.0, 32.0 / 62.0, 1.0,
683  };
684 
685  paint.color_source = ColorSource::MakeLinearGradient(
686  {0, 0}, {200, 200}, std::move(colors), std::move(stops), tile_mode, {});
687 
688  canvas.DrawRect({0, 0, 600, 600}, paint);
689  return canvas.EndRecordingAsPicture();
690  };
691  ASSERT_TRUE(OpenPlaygroundHere(callback));
692 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeLinearGradient(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [52/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMaskBlur   
)

Definition at line 694 of file aiks_unittests.cc.

694  {
695  Canvas canvas;
696 
697  Paint paint = {
698  .color = Color::White(),
699  .color_source = ColorSource::MakeLinearGradient(
700  {200, 200}, {400, 400},
701  {Color::Red(), Color::White(), Color::Red(), Color::White(),
702  Color::Red(), Color::White(), Color::Red(), Color::White(),
703  Color::Red(), Color::White(), Color::Red()},
704  {0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0},
705  Entity::TileMode::kClamp, {}),
706  .mask_blur_descriptor =
707  Paint::MaskBlurDescriptor{
708  .style = FilterContents::BlurStyle::kNormal,
709  .sigma = Sigma(20),
710  },
711  };
712 
713  canvas.DrawCircle({300, 300}, 200, paint);
714  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
715 
716  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
717 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::FilterContents::kNormal, impeller::ColorSource::MakeLinearGradient(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Color::Red(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Color::White().

◆ TEST_P() [53/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientMirror   
)

Definition at line 394 of file aiks_unittests.cc.

394  {
395  CanRenderLinearGradient(this, Entity::TileMode::kMirror);
396 }

References impeller::Entity::kMirror.

◆ TEST_P() [54/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientRepeat   
)

Definition at line 391 of file aiks_unittests.cc.

391  {
392  CanRenderLinearGradient(this, Entity::TileMode::kRepeat);
393 }

References impeller::Entity::kRepeat.

◆ TEST_P() [55/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWayManyColorsClamp   
)

Definition at line 639 of file aiks_unittests.cc.

639  {
640  CanRenderLinearGradientWayManyColors(this, Entity::TileMode::kClamp);
641 }

References impeller::Entity::kClamp.

◆ TEST_P() [56/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithDitheringDisabled   
)

Definition at line 445 of file aiks_unittests.cc.

445  {
447 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [57/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithDitheringEnabled   
)

Definition at line 449 of file aiks_unittests.cc.

449  {
451 } // namespace

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [58/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderLinearGradientWithOverlappingStopsClamp   
)

Definition at line 560 of file aiks_unittests.cc.

560  {
561  CanRenderLinearGradientWithOverlappingStops(this, Entity::TileMode::kClamp);
562 }

References impeller::Entity::kClamp.

◆ TEST_P() [59/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderMaskBlurHugeSigma   
)

Definition at line 2858 of file aiks_unittests.cc.

2858  {
2859  Canvas canvas;
2860  canvas.DrawCircle({400, 400}, 300,
2861  {.color = Color::Green(),
2862  .mask_blur_descriptor = Paint::MaskBlurDescriptor{
2863  .style = FilterContents::BlurStyle::kNormal,
2864  .sigma = Sigma(99999),
2865  }});
2866  canvas.Restore();
2867 
2868  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2869 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [60/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderNestedClips   
)

Definition at line 259 of file aiks_unittests.cc.

259  {
260  Canvas canvas;
261  Paint paint;
262  paint.color = Color::Fuchsia();
263  canvas.Save();
264  canvas.ClipPath(PathBuilder{}.AddCircle({200, 400}, 300).TakePath());
265  canvas.Restore();
266  canvas.ClipPath(PathBuilder{}.AddCircle({600, 400}, 300).TakePath());
267  canvas.ClipPath(PathBuilder{}.AddCircle({400, 600}, 300).TakePath());
268  canvas.DrawRect(Rect::MakeXYWH(200, 200, 400, 400), paint);
269  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
270 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Fuchsia(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Canvas::Restore(), and impeller::Canvas::Save().

◆ TEST_P() [61/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderOffscreenCheckerboard   
)

Tests that the debug checkerboard displays for offscreen textures when enabled. Most of the complexity here is just to future proof by making pass collapsing hard.

Definition at line 2796 of file aiks_unittests.cc.

2796  {
2797  Canvas canvas;
2798  canvas.debug_options.offscreen_texture_checkerboard = true;
2799 
2800  canvas.DrawPaint({.color = Color::AntiqueWhite()});
2801  canvas.DrawCircle({400, 300}, 200,
2802  {.color = Color::CornflowerBlue().WithAlpha(0.75)});
2803 
2804  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2805  {
2806  canvas.DrawCircle({500, 400}, 200,
2807  {.color = Color::DarkBlue().WithAlpha(0.75)});
2808  canvas.DrawCircle({550, 450}, 200,
2809  {.color = Color::LightCoral().WithAlpha(0.75),
2810  .blend_mode = BlendMode::kLuminosity});
2811  }
2812  canvas.Restore();
2813 
2814  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2815 }

References impeller::Canvas::debug_options, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::DebugOptions::offscreen_texture_checkerboard, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [62/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradient   
)

Definition at line 719 of file aiks_unittests.cc.

719  {
720  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
721  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
722  const Entity::TileMode tile_modes[] = {
723  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
724  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
725 
726  static int selected_tile_mode = 0;
727  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
728  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
729  sizeof(tile_mode_names) / sizeof(char*));
730  static Matrix matrix = {
731  1, 0, 0, 0, //
732  0, 1, 0, 0, //
733  0, 0, 1, 0, //
734  0, 0, 0, 1 //
735  };
736  std::string label = "##1";
737  for (int i = 0; i < 4; i++) {
738  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
739  4, NULL, NULL, "%.2f", 0);
740  label[2]++;
741  }
742  ImGui::End();
743 
744  Canvas canvas;
745  Paint paint;
746  canvas.Translate({100.0, 100.0, 0});
747  auto tile_mode = tile_modes[selected_tile_mode];
748 
749  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
750  Color{0.1294, 0.5882, 0.9529, 1.0}};
751  std::vector<Scalar> stops = {0.0, 1.0};
752 
753  paint.color_source = ColorSource::MakeRadialGradient(
754  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
755 
756  canvas.DrawRect({0, 0, 600, 600}, paint);
757  return canvas.EndRecordingAsPicture();
758  };
759  ASSERT_TRUE(OpenPlaygroundHere(callback));
760 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [63/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientManyColors   
)

Definition at line 762 of file aiks_unittests.cc.

762  {
763  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
764  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
765  const Entity::TileMode tile_modes[] = {
766  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
767  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
768 
769  static int selected_tile_mode = 0;
770  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
771  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
772  sizeof(tile_mode_names) / sizeof(char*));
773  static Matrix matrix = {
774  1, 0, 0, 0, //
775  0, 1, 0, 0, //
776  0, 0, 1, 0, //
777  0, 0, 0, 1 //
778  };
779  std::string label = "##1";
780  for (int i = 0; i < 4; i++) {
781  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float, &(matrix.vec[i]),
782  4, NULL, NULL, "%.2f", 0);
783  label[2]++;
784  }
785  ImGui::End();
786 
787  Canvas canvas;
788  Paint paint;
789  canvas.Translate({100.0, 100.0, 0});
790  auto tile_mode = tile_modes[selected_tile_mode];
791 
792  std::vector<Color> colors = {
793  Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0},
794  Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0},
795  Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0},
796  Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0},
797  Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0},
798  Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0},
799  Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}};
800  std::vector<Scalar> stops = {
801  0.0,
802  (1.0 / 6.0) * 1,
803  (1.0 / 6.0) * 2,
804  (1.0 / 6.0) * 3,
805  (1.0 / 6.0) * 4,
806  (1.0 / 6.0) * 5,
807  1.0,
808  };
809 
810  paint.color_source = ColorSource::MakeRadialGradient(
811  {100, 100}, 100, std::move(colors), std::move(stops), tile_mode, {});
812 
813  canvas.DrawRect({0, 0, 600, 600}, paint);
814  return canvas.EndRecordingAsPicture();
815  };
816  ASSERT_TRUE(OpenPlaygroundHere(callback));
817 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::Entity::kMirror, impeller::Entity::kRepeat, impeller::ColorSource::MakeRadialGradient(), impeller::Canvas::Translate(), and impeller::Matrix::vec.

◆ TEST_P() [64/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithDitheringDisabled   
)

Definition at line 472 of file aiks_unittests.cc.

472  {
474 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [65/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRadialGradientWithDitheringEnabled   
)

Definition at line 476 of file aiks_unittests.cc.

476  {
478 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [66/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderRoundedRectWithNonUniformRadii   
)

Definition at line 1188 of file aiks_unittests.cc.

1188  {
1189  Canvas canvas;
1190 
1191  Paint paint;
1192  paint.color = Color::Red();
1193 
1194  PathBuilder::RoundingRadii radii;
1195  radii.top_left = {50, 25};
1196  radii.top_right = {25, 50};
1197  radii.bottom_right = {50, 25};
1198  radii.bottom_left = {25, 50};
1199 
1200  auto path =
1201  PathBuilder{}.AddRoundedRect(Rect{100, 100, 500, 500}, radii).TakePath();
1202 
1203  canvas.DrawPath(path, paint);
1204 
1205  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1206 }

References impeller::PathBuilder::AddRoundedRect(), impeller::PathBuilder::RoundingRadii::bottom_left, impeller::PathBuilder::RoundingRadii::bottom_right, impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Red(), impeller::PathBuilder::RoundingRadii::top_left, and impeller::PathBuilder::RoundingRadii::top_right.

◆ TEST_P() [67/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderStrokes   
)

Definition at line 228 of file aiks_unittests.cc.

228  {
229  Canvas canvas;
230  Paint paint;
231  paint.color = Color::Red();
232  paint.stroke_width = 20.0;
233  paint.style = Paint::Style::kStroke;
234  canvas.DrawPath(PathBuilder{}.AddLine({200, 100}, {800, 100}).TakePath(),
235  paint);
236  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
237 }

References impeller::PathBuilder::AddLine(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::kStroke, impeller::Color::Red(), impeller::Paint::stroke_width, and impeller::Paint::style.

◆ TEST_P() [68/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientClamp   
)

Definition at line 839 of file aiks_unittests.cc.

839  {
840  CanRenderSweepGradient(this, Entity::TileMode::kClamp);
841 }

References impeller::Entity::kClamp.

◆ TEST_P() [69/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientDecal   
)

Definition at line 848 of file aiks_unittests.cc.

848  {
849  CanRenderSweepGradient(this, Entity::TileMode::kDecal);
850 }

References impeller::Entity::kDecal.

◆ TEST_P() [70/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsClamp   
)

Definition at line 886 of file aiks_unittests.cc.

886  {
887  CanRenderSweepGradientManyColors(this, Entity::TileMode::kClamp);
888 }

References impeller::Entity::kClamp.

◆ TEST_P() [71/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsDecal   
)

Definition at line 895 of file aiks_unittests.cc.

895  {
896  CanRenderSweepGradientManyColors(this, Entity::TileMode::kDecal);
897 }

References impeller::Entity::kDecal.

◆ TEST_P() [72/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsMirror   
)

Definition at line 892 of file aiks_unittests.cc.

892  {
893  CanRenderSweepGradientManyColors(this, Entity::TileMode::kMirror);
894 }

References impeller::Entity::kMirror.

◆ TEST_P() [73/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientManyColorsRepeat   
)

Definition at line 889 of file aiks_unittests.cc.

889  {
890  CanRenderSweepGradientManyColors(this, Entity::TileMode::kRepeat);
891 }

References impeller::Entity::kRepeat.

◆ TEST_P() [74/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientMirror   
)

Definition at line 845 of file aiks_unittests.cc.

845  {
846  CanRenderSweepGradient(this, Entity::TileMode::kMirror);
847 }

References impeller::Entity::kMirror.

◆ TEST_P() [75/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientRepeat   
)

Definition at line 842 of file aiks_unittests.cc.

842  {
843  CanRenderSweepGradient(this, Entity::TileMode::kRepeat);
844 }

References impeller::Entity::kRepeat.

◆ TEST_P() [76/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithDitheringDisabled   
)

Definition at line 501 of file aiks_unittests.cc.

501  {
503 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [77/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderSweepGradientWithDitheringEnabled   
)

Definition at line 505 of file aiks_unittests.cc.

505  {
507 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [78/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrame   
)

Definition at line 1365 of file aiks_unittests.cc.

1365  {
1366  Canvas canvas;
1367  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1368  ASSERT_TRUE(RenderTextInCanvasSkia(
1369  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1370  "Roboto-Regular.ttf"));
1371  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1372 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSkia().

◆ TEST_P() [79/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextFrameSTB   
)

Definition at line 1374 of file aiks_unittests.cc.

1374  {
1375  Canvas canvas;
1376  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1377  ASSERT_TRUE(RenderTextInCanvasSTB(
1378  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1379  "Roboto-Regular.ttf"));
1380 
1381  SetTypographerContext(TypographerContextSTB::Make());
1382  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1383 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and RenderTextInCanvasSTB().

◆ TEST_P() [80/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextInSaveLayer   
)

Definition at line 1467 of file aiks_unittests.cc.

1467  {
1468  Canvas canvas;
1469  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1470 
1471  canvas.Translate({100, 100});
1472  canvas.Scale(Vector2{0.5, 0.5});
1473 
1474  // Blend the layer with the parent pass using kClear to expose the coverage.
1475  canvas.SaveLayer({.blend_mode = BlendMode::kClear});
1476  ASSERT_TRUE(RenderTextInCanvasSkia(
1477  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1478  "Roboto-Regular.ttf"));
1479  canvas.Restore();
1480 
1481  // Render the text again over the cleared coverage rect.
1482  ASSERT_TRUE(RenderTextInCanvasSkia(
1483  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1484  "Roboto-Regular.ttf"));
1485 
1486  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1487 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [81/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTextOutsideBoundaries   
)

Definition at line 1489 of file aiks_unittests.cc.

1489  {
1490  Canvas canvas;
1491  canvas.Translate({200, 150});
1492 
1493  // Construct the text blob.
1494  auto mapping = OpenFixtureAsSkData("wtf.otf");
1495  ASSERT_NE(mapping, nullptr);
1496 
1497  Scalar font_size = 80;
1498  SkFont sk_font(SkTypeface::MakeFromData(mapping), font_size);
1499 
1500  Paint text_paint;
1501  text_paint.color = Color::Blue().WithAlpha(0.8);
1502 
1503  struct {
1504  Point position;
1505  const char* text;
1506  } text[] = {{Point(0, 0), "0F0F0F0"},
1507  {Point(1, 2), "789"},
1508  {Point(1, 3), "456"},
1509  {Point(1, 4), "123"},
1510  {Point(0, 6), "0F0F0F0"}};
1511  for (auto& t : text) {
1512  canvas.Save();
1513  canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
1514  {
1515  auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
1516  ASSERT_NE(blob, nullptr);
1517  auto frame = MakeTextFrameFromTextBlobSkia(blob);
1518  canvas.DrawTextFrame(frame, Point(), text_paint);
1519  }
1520  canvas.Restore();
1521  }
1522 
1523  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1524 }

References impeller::Paint::color, impeller::Canvas::DrawTextFrame(), impeller::Canvas::EndRecordingAsPicture(), impeller::MakeTextFrameFromTextBlobSkia(), OpenFixtureAsSkData(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [82/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClamp   
)

Definition at line 191 of file aiks_unittests.cc.

191  {
192  CanRenderTiledTexture(this, Entity::TileMode::kClamp);
193 }

References impeller::Entity::kClamp.

◆ TEST_P() [83/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureClampWithTranslate   
)

Definition at line 207 of file aiks_unittests.cc.

207  {
208  CanRenderTiledTexture(this, Entity::TileMode::kClamp,
209  Matrix::MakeTranslation({172.f, 172.f, 0.f}));
210 }

References impeller::Entity::kClamp, and impeller::Matrix::MakeTranslation().

◆ TEST_P() [84/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureDecal   
)

Definition at line 203 of file aiks_unittests.cc.

203  {
204  CanRenderTiledTexture(this, Entity::TileMode::kDecal);
205 }

References impeller::Entity::kDecal.

◆ TEST_P() [85/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureMirror   
)

Definition at line 199 of file aiks_unittests.cc.

199  {
200  CanRenderTiledTexture(this, Entity::TileMode::kMirror);
201 }

References impeller::Entity::kMirror.

◆ TEST_P() [86/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTiledTextureRepeat   
)

Definition at line 195 of file aiks_unittests.cc.

195  {
196  CanRenderTiledTexture(this, Entity::TileMode::kRepeat);
197 }

References impeller::Entity::kRepeat.

◆ TEST_P() [87/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderTinyOverlappingSubpasses   
)

This is a regression check for https://github.com/flutter/engine/pull/41129 The entire screen is green if successful. If failing, no frames will render, or the entire screen will be transparent black.

Definition at line 2776 of file aiks_unittests.cc.

2776  {
2777  Canvas canvas;
2778  canvas.DrawPaint({.color = Color::Red()});
2779 
2780  // Draw two overlapping subpixel circles.
2781  canvas.SaveLayer({});
2782  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2783  canvas.Restore();
2784  canvas.SaveLayer({});
2785  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2786  canvas.Restore();
2787 
2788  canvas.DrawPaint({.color = Color::Green()});
2789 
2790  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2791 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [88/317]

impeller::testing::TEST_P ( AiksTest  ,
CanRenderWithContiguousClipRestores   
)

Definition at line 309 of file aiks_unittests.cc.

309  {
310  Canvas canvas;
311 
312  // Cover the whole canvas with red.
313  canvas.DrawPaint({.color = Color::Red()});
314 
315  canvas.Save();
316 
317  // Append two clips, the second resulting in empty coverage.
318  canvas.ClipPath(
319  PathBuilder{}.AddRect(Rect::MakeXYWH(100, 100, 100, 100)).TakePath());
320  canvas.ClipPath(
321  PathBuilder{}.AddRect(Rect::MakeXYWH(300, 300, 100, 100)).TakePath());
322 
323  // Restore to no clips.
324  canvas.Restore();
325 
326  // Replace the whole canvas with green.
327  canvas.DrawPaint({.color = Color::Green()});
328 
329  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
330 }

References impeller::PathBuilder::AddRect(), impeller::Canvas::ClipPath(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [89/317]

impeller::testing::TEST_P ( AiksTest  ,
CanSaveLayerStandalone   
)

Definition at line 350 of file aiks_unittests.cc.

350  {
351  Canvas canvas;
352 
353  Paint red;
354  red.color = Color::Red();
355 
356  Paint alpha;
357  alpha.color = Color::Red().WithAlpha(0.5);
358 
359  canvas.SaveLayer(alpha);
360 
361  canvas.DrawCircle({125, 125}, 125, red);
362 
363  canvas.Restore();
364 
365  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
366 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Color::WithAlpha().

◆ TEST_P() [90/317]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCanPushPopCTM   
)

Definition at line 90 of file aiks_unittests.cc.

90  {
91  Canvas canvas;
92  ASSERT_EQ(canvas.GetSaveCount(), 1u);
93  ASSERT_EQ(canvas.Restore(), false);
94 
95  canvas.Translate(Size{100, 100});
96  canvas.Save();
97  ASSERT_EQ(canvas.GetSaveCount(), 2u);
98  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(),
99  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
100  ASSERT_TRUE(canvas.Restore());
101  ASSERT_EQ(canvas.GetSaveCount(), 1u);
102  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(),
103  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
104 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransformation(), impeller::Canvas::GetSaveCount(), impeller::Matrix::MakeTranslation(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Translate().

◆ TEST_P() [91/317]

impeller::testing::TEST_P ( AiksTest  ,
CanvasCTMCanBeUpdated   
)

Definition at line 81 of file aiks_unittests.cc.

81  {
82  Canvas canvas;
83  Matrix identity;
84  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(), identity);
85  canvas.Translate(Size{100, 100});
86  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(),
87  Matrix::MakeTranslation({100.0, 100.0, 0.0}));
88 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransformation(), impeller::Matrix::MakeTranslation(), and impeller::Canvas::Translate().

◆ TEST_P() [92/317]

impeller::testing::TEST_P ( AiksTest  ,
CaptureContext   
)

Definition at line 3475 of file aiks_unittests.cc.

3475  {
3476  auto capture_context = CaptureContext::MakeAllowlist({"TestDocument"});
3477 
3478  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3479  Canvas canvas;
3480 
3481  capture_context.Rewind();
3482  auto document = capture_context.GetDocument("TestDocument");
3483 
3484  auto color = document.AddColor("Background color", Color::CornflowerBlue());
3485  canvas.DrawPaint({.color = color});
3486 
3487  ImGui::Begin("TestDocument", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
3488  document.GetElement()->properties.Iterate([](CaptureProperty& property) {
3489  property.Invoke({.color = [](CaptureColorProperty& p) {
3490  ImGui::ColorEdit4(p.label.c_str(), reinterpret_cast<float*>(&p.value));
3491  }});
3492  });
3493  ImGui::End();
3494 
3495  return canvas.EndRecordingAsPicture();
3496  };
3497  OpenPlaygroundHere(callback);
3498 }

References impeller::Canvas::DrawPaint(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [93/317]

impeller::testing::TEST_P ( AiksTest  ,
CaptureInactivatedByDefault   
)

Definition at line 3500 of file aiks_unittests.cc.

3500  {
3501  ASSERT_FALSE(GetContext()->capture.IsActive());
3502 }

◆ TEST_P() [94/317]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlend   
)

Definition at line 3577 of file aiks_unittests.cc.

3577  {
3578  Canvas canvas;
3579  Paint white;
3580  white.color = Color::Blue();
3581  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3582 
3583  Paint clear;
3584  clear.blend_mode = BlendMode::kClear;
3585 
3586  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3587 }

References impeller::Paint::blend_mode, impeller::Paint::color, impeller::Canvas::DrawCircle(), and impeller::Canvas::DrawRect().

◆ TEST_P() [95/317]

impeller::testing::TEST_P ( AiksTest  ,
ClearBlendWithBlur   
)

Definition at line 3559 of file aiks_unittests.cc.

3559  {
3560  Canvas canvas;
3561  Paint white;
3562  white.color = Color::Blue();
3563  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3564 
3565  Paint clear;
3566  clear.blend_mode = BlendMode::kClear;
3567  clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3568  .style = FilterContents::BlurStyle::kNormal,
3569  .sigma = Sigma(20),
3570  };
3571 
3572  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3573 
3574  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3575 }

References impeller::Paint::blend_mode, impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::mask_blur_descriptor, and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [96/317]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationDoesNotApplyForBackdropFilters   
)

Definition at line 2405 of file aiks_unittests.cc.

2405  {
2406  Canvas canvas;
2407  canvas.SaveLayer({}, std::nullopt,
2408  ImageFilter::MakeBlur(Sigma(3), Sigma(3),
2409  FilterContents::BlurStyle::kNormal,
2410  Entity::TileMode::kClamp));
2411  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2412  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2413  .blend_mode = BlendMode::kSourceOver});
2414  canvas.Restore();
2415 
2416  Picture picture = canvas.EndRecordingAsPicture();
2417 
2418  std::optional<Color> actual_color;
2419  bool found_subpass = false;
2420  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2421  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2422  actual_color = subpass->get()->GetClearColor();
2423  found_subpass = true;
2424  }
2425  // Fail if the first element isn't a subpass.
2426  return true;
2427  });
2428 
2429  EXPECT_TRUE(found_subpass);
2430  EXPECT_FALSE(actual_color.has_value());
2431 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Picture::pass, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [97/317]

impeller::testing::TEST_P ( AiksTest  ,
ClearColorOptimizationWhenSubpassIsBiggerThanParentPass   
)

Definition at line 3611 of file aiks_unittests.cc.

3611  {
3612  Canvas canvas;
3613  canvas.Scale(GetContentScale());
3614  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
3615  canvas.SaveLayer({
3616  .image_filter = std::make_shared<MatrixImageFilter>(
3617  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
3618  });
3619  // Draw a rectangle that would fully cover the parent pass size, but not
3620  // the subpass that it is rendered in.
3621  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
3622  // Draw a bigger rectangle to force the subpass to be bigger.
3623  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
3624  canvas.Restore();
3625 
3626  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3627 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Scale().

◆ TEST_P() [98/317]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectly   
)

Definition at line 3460 of file aiks_unittests.cc.

3460  {
3461  Canvas canvas;
3462  canvas.Translate(Point(0, -400));
3463  Paint paint;
3464  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3465  .style = FilterContents::BlurStyle::kNormal,
3466  .sigma = Radius{120 * 3},
3467  };
3468  paint.color = Color::Red();
3469  PathBuilder builder{};
3470  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3471  canvas.DrawPath(builder.TakePath(), paint);
3472  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3473 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::mask_blur_descriptor, impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [99/317]

impeller::testing::TEST_P ( AiksTest  ,
ClippedBlurFilterRendersCorrectlyInteractive   
)

Definition at line 3440 of file aiks_unittests.cc.

3440  {
3441  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3442  auto point = IMPELLER_PLAYGROUND_POINT(Point(400, 400), 20, Color::Green());
3443 
3444  Canvas canvas;
3445  canvas.Translate(point - Point(400, 400));
3446  Paint paint;
3447  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3448  .style = FilterContents::BlurStyle::kNormal,
3449  .sigma = Radius{120 * 3},
3450  };
3451  paint.color = Color::Red();
3452  PathBuilder builder{};
3453  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3454  canvas.DrawPath(builder.TakePath(), paint);
3455  return canvas.EndRecordingAsPicture();
3456  };
3457  ASSERT_TRUE(OpenPlaygroundHere(callback));
3458 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), IMPELLER_PLAYGROUND_POINT, impeller::Paint::mask_blur_descriptor, impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [100/317]

impeller::testing::TEST_P ( AiksTest  ,
ClipRectElidesNoOpClips   
)

Definition at line 2381 of file aiks_unittests.cc.

2381  {
2382  Canvas canvas(Rect(0, 0, 100, 100));
2383  canvas.ClipRect(Rect(0, 0, 100, 100));
2384  canvas.ClipRect(Rect(-100, -100, 300, 300));
2385  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2386  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2387  .blend_mode = BlendMode::kSourceOver});
2388 
2389  Picture picture = canvas.EndRecordingAsPicture();
2390  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
2391  BlendMode::kSourceOver);
2392  ASSERT_EQ(picture.pass->GetClearColor(), expected);
2393 
2394  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2395  std::shared_ptr<Context> real_context = GetContext();
2396  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2397  AiksContext renderer(mock_context, nullptr);
2398  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2399 
2400  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2401  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2402  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2403 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Picture::pass, and impeller::Picture::ToImage().

◆ TEST_P() [101/317]

impeller::testing::TEST_P ( AiksTest  ,
ClipsUseCurrentTransform   
)

Definition at line 332 of file aiks_unittests.cc.

332  {
333  std::array<Color, 5> colors = {Color::White(), Color::Black(),
334  Color::SkyBlue(), Color::Red(),
335  Color::Yellow()};
336  Canvas canvas;
337  Paint paint;
338 
339  canvas.Translate(Vector3(300, 300));
340  for (int i = 0; i < 15; i++) {
341  canvas.Scale(Vector3(0.8, 0.8));
342 
343  paint.color = colors[i % colors.size()];
344  canvas.ClipPath(PathBuilder{}.AddCircle({0, 0}, 300).TakePath());
345  canvas.DrawRect(Rect(-300, -300, 600, 600), paint);
346  }
347  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
348 }

References impeller::PathBuilder::AddCircle(), impeller::Color::Black(), impeller::Canvas::ClipPath(), impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Red(), impeller::Canvas::Scale(), impeller::Color::SkyBlue(), impeller::Canvas::Translate(), impeller::Color::White(), and impeller::Color::Yellow().

◆ TEST_P() [102/317]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpass   
)

Definition at line 2433 of file aiks_unittests.cc.

2433  {
2434  Canvas canvas;
2435  canvas.DrawPaint(
2436  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2437  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2438  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2439  .blend_mode = BlendMode::kSourceOver});
2440 
2441  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2442 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [103/317]

impeller::testing::TEST_P ( AiksTest  ,
CollapsedDrawPaintInSubpassBackdropFilter   
)

Definition at line 2444 of file aiks_unittests.cc.

2444  {
2445  // Bug: https://github.com/flutter/flutter/issues/131576
2446  Canvas canvas;
2447  canvas.DrawPaint(
2448  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2449  canvas.SaveLayer({}, {},
2450  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2451  FilterContents::BlurStyle::kNormal,
2452  Entity::TileMode::kDecal));
2453  canvas.DrawPaint(
2454  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
2455 
2456  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2457 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [104/317]

impeller::testing::TEST_P ( AiksTest  ,
ColorMatrixFilterSubpassCollapseOptimization   
)

Definition at line 2474 of file aiks_unittests.cc.

2474  {
2475  Canvas canvas;
2476 
2477  canvas.SaveLayer({
2478  .color_filter =
2479  ColorFilter::MakeMatrix({.array =
2480  {
2481  -1.0, 0, 0, 1.0, 0, //
2482  0, -1.0, 0, 1.0, 0, //
2483  0, 0, -1.0, 1.0, 0, //
2484  1.0, 1.0, 1.0, 1.0, 0 //
2485  }}),
2486  });
2487 
2488  canvas.Translate({500, 300, 0});
2489  canvas.Rotate(Radians(2 * kPi / 3));
2490  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2491 
2492  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2493 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [105/317]

impeller::testing::TEST_P ( AiksTest  ,
ColorWheel   
)

color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 -> cyan domain: r >= 0 (because modulo used is non euclidean)

Definition at line 1675 of file aiks_unittests.cc.

1675  {
1676  // Compare with https://fiddle.skia.org/c/@BlendModes
1677 
1678  BlendModeSelection blend_modes = GetBlendModeSelection();
1679 
1680  auto draw_color_wheel = [](Canvas& canvas) {
1681  /// color_wheel_sampler: r=0 -> fuchsia, r=2pi/3 -> yellow, r=4pi/3 ->
1682  /// cyan domain: r >= 0 (because modulo used is non euclidean)
1683  auto color_wheel_sampler = [](Radians r) {
1684  Scalar x = r.radians / k2Pi + 1;
1685 
1686  // https://www.desmos.com/calculator/6nhjelyoaj
1687  auto color_cycle = [](Scalar x) {
1688  Scalar cycle = std::fmod(x, 6.0f);
1689  return std::max(0.0f, std::min(1.0f, 2 - std::abs(2 - cycle)));
1690  };
1691  return Color(color_cycle(6 * x + 1), //
1692  color_cycle(6 * x - 1), //
1693  color_cycle(6 * x - 3), //
1694  1);
1695  };
1696 
1697  Paint paint;
1698  paint.blend_mode = BlendMode::kSourceOver;
1699 
1700  // Draw a fancy color wheel for the backdrop.
1701  // https://www.desmos.com/calculator/xw7kafthwd
1702  const int max_dist = 900;
1703  for (int i = 0; i <= 900; i++) {
1704  Radians r(kPhi / k2Pi * i);
1705  Scalar distance = r.radians / std::powf(4.12, 0.0026 * r.radians);
1706  Scalar normalized_distance = static_cast<Scalar>(i) / max_dist;
1707 
1708  paint.color =
1709  color_wheel_sampler(r).WithAlpha(1.0f - normalized_distance);
1710  Point position(distance * std::sin(r.radians),
1711  -distance * std::cos(r.radians));
1712 
1713  canvas.DrawCircle(position, 9 + normalized_distance * 3, paint);
1714  }
1715  };
1716 
1717  std::shared_ptr<Image> color_wheel_image;
1718  Matrix color_wheel_transform;
1719 
1720  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1721  // UI state.
1722  static bool cache_the_wheel = true;
1723  static int current_blend_index = 3;
1724  static float dst_alpha = 1;
1725  static float src_alpha = 1;
1726  static Color color0 = Color::Red();
1727  static Color color1 = Color::Green();
1728  static Color color2 = Color::Blue();
1729 
1730  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1731  {
1732  ImGui::Checkbox("Cache the wheel", &cache_the_wheel);
1733  ImGui::ListBox("Blending mode", &current_blend_index,
1734  blend_modes.blend_mode_names.data(),
1735  blend_modes.blend_mode_names.size());
1736  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1737  ImGui::ColorEdit4("Color A", reinterpret_cast<float*>(&color0));
1738  ImGui::ColorEdit4("Color B", reinterpret_cast<float*>(&color1));
1739  ImGui::ColorEdit4("Color C", reinterpret_cast<float*>(&color2));
1740  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1741  }
1742  ImGui::End();
1743 
1744  static Point content_scale;
1745  Point new_content_scale = GetContentScale();
1746 
1747  if (!cache_the_wheel || new_content_scale != content_scale) {
1748  content_scale = new_content_scale;
1749 
1750  // Render the color wheel to an image.
1751 
1752  Canvas canvas;
1753  canvas.Scale(content_scale);
1754 
1755  canvas.Translate(Vector2(500, 400));
1756  canvas.Scale(Vector2(3, 3));
1757 
1758  draw_color_wheel(canvas);
1759  auto color_wheel_picture = canvas.EndRecordingAsPicture();
1760  auto snapshot = color_wheel_picture.Snapshot(renderer);
1761  if (!snapshot.has_value() || !snapshot->texture) {
1762  return std::nullopt;
1763  }
1764  color_wheel_image = std::make_shared<Image>(snapshot->texture);
1765  color_wheel_transform = snapshot->transform;
1766  }
1767 
1768  Canvas canvas;
1769 
1770  // Blit the color wheel backdrop to the screen with managed alpha.
1771  canvas.SaveLayer({.color = Color::White().WithAlpha(dst_alpha),
1772  .blend_mode = BlendMode::kSource});
1773  {
1774  canvas.DrawPaint({.color = Color::White()});
1775 
1776  canvas.Save();
1777  canvas.Transform(color_wheel_transform);
1778  canvas.DrawImage(color_wheel_image, Point(), Paint());
1779  canvas.Restore();
1780  }
1781  canvas.Restore();
1782 
1783  canvas.Scale(content_scale);
1784  canvas.Translate(Vector2(500, 400));
1785  canvas.Scale(Vector2(3, 3));
1786 
1787  // Draw 3 circles to a subpass and blend it in.
1788  canvas.SaveLayer(
1789  {.color = Color::White().WithAlpha(src_alpha),
1790  .blend_mode = blend_modes.blend_mode_values[current_blend_index]});
1791  {
1792  Paint paint;
1793  paint.blend_mode = BlendMode::kPlus;
1794  const Scalar x = std::sin(k2Pi / 3);
1795  const Scalar y = -std::cos(k2Pi / 3);
1796  paint.color = color0;
1797  canvas.DrawCircle(Point(-x, y) * 45, 65, paint);
1798  paint.color = color1;
1799  canvas.DrawCircle(Point(0, -1) * 45, 65, paint);
1800  paint.color = color2;
1801  canvas.DrawCircle(Point(x, y) * 45, 65, paint);
1802  }
1803  canvas.Restore();
1804 
1805  return canvas.EndRecordingAsPicture();
1806  };
1807 
1808  ASSERT_TRUE(OpenPlaygroundHere(callback));
1809 }

References impeller::Paint::blend_mode, impeller::testing::BlendModeSelection::blend_mode_names, impeller::testing::BlendModeSelection::blend_mode_values, impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawImage(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), GetBlendModeSelection(), impeller::k2Pi, impeller::kPhi, impeller::Radians::radians, impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Picture::Snapshot(), impeller::Canvas::Transform(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [106/317]

impeller::testing::TEST_P ( AiksTest  ,
CoordinateConversionsAreCorrect   
)

Definition at line 1071 of file aiks_unittests.cc.

1071  {
1072  Canvas canvas;
1073 
1074  // Render a texture directly.
1075  {
1076  Paint paint;
1077  auto image =
1078  std::make_shared<Image>(CreateTextureForFixture("kalimba.jpg"));
1079  paint.color = Color::Red();
1080 
1081  canvas.Save();
1082  canvas.Translate({100, 200, 0});
1083  canvas.Scale(Vector2{0.5, 0.5});
1084  canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint);
1085  canvas.Restore();
1086  }
1087 
1088  // Render an offscreen rendered texture.
1089  {
1090  Paint red;
1091  red.color = Color::Red();
1092  Paint green;
1093  green.color = Color::Green();
1094  Paint blue;
1095  blue.color = Color::Blue();
1096 
1097  Paint alpha;
1098  alpha.color = Color::Red().WithAlpha(0.5);
1099 
1100  canvas.SaveLayer(alpha);
1101 
1102  canvas.DrawRect({000, 000, 100, 100}, red);
1103  canvas.DrawRect({020, 020, 100, 100}, green);
1104  canvas.DrawRect({040, 040, 100, 100}, blue);
1105 
1106  canvas.Restore();
1107  }
1108 
1109  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1110 }

References impeller::Color::Blue(), impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Color::Green(), impeller::TPoint< Scalar >::MakeXY(), impeller::Color::Red(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [107/317]

impeller::testing::TEST_P ( AiksTest  ,
CoverageOriginShouldBeAccountedForInSubpasses   
)

Definition at line 1990 of file aiks_unittests.cc.

1990  {
1991  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1992  Canvas canvas;
1993  canvas.Scale(GetContentScale());
1994 
1995  Paint alpha;
1996  alpha.color = Color::Red().WithAlpha(0.5);
1997 
1998  auto current = Point{25, 25};
1999  const auto offset = Point{25, 25};
2000  const auto size = Size(100, 100);
2001 
2002  auto [b0, b1] = IMPELLER_PLAYGROUND_LINE(Point(40, 40), Point(160, 160), 10,
2003  Color::White(), Color::White());
2004  auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y);
2005 
2006  canvas.DrawRect(bounds, Paint{.color = Color::Yellow(),
2007  .stroke_width = 5.0f,
2008  .style = Paint::Style::kStroke});
2009 
2010  canvas.SaveLayer(alpha, bounds);
2011 
2012  canvas.DrawRect({current, size}, Paint{.color = Color::Red()});
2013  canvas.DrawRect({current += offset, size}, Paint{.color = Color::Green()});
2014  canvas.DrawRect({current += offset, size}, Paint{.color = Color::Blue()});
2015 
2016  canvas.Restore();
2017 
2018  return canvas.EndRecordingAsPicture();
2019  };
2020 
2021  ASSERT_TRUE(OpenPlaygroundHere(callback));
2022 }

References impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), IMPELLER_PLAYGROUND_LINE, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Color::WithAlpha().

◆ TEST_P() [108/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawAdvancedBlendPartlyOffscreen   
)

Definition at line 1583 of file aiks_unittests.cc.

1583  {
1584  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
1585  Color{0.1294, 0.5882, 0.9529, 1.0}};
1586  std::vector<Scalar> stops = {0.0, 1.0};
1587 
1588  Paint paint = {
1589  .color_source = ColorSource::MakeLinearGradient(
1590  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
1591  Entity::TileMode::kRepeat, Matrix::MakeScale(Vector3(0.3, 0.3, 0.3))),
1592  .blend_mode = BlendMode::kLighten,
1593  };
1594 
1595  Canvas canvas;
1596  canvas.DrawPaint({.color = Color::Blue()});
1597  canvas.Scale(Vector2(2, 2));
1598  canvas.ClipRect(Rect::MakeLTRB(0, 0, 200, 200));
1599  canvas.DrawCircle({100, 100}, 100, paint);
1600  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1601 }

References impeller::Canvas::ClipRect(), impeller::Paint::color_source, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [109/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasAdvancedAndTransform   
)

Definition at line 3108 of file aiks_unittests.cc.

3108  {
3109  // Draws the image as four squares stiched together.
3110  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
3111  auto size = atlas->GetSize();
3112  auto image = std::make_shared<Image>(atlas);
3113  // Divide image into four quadrants.
3114  Scalar half_width = size.width / 2;
3115  Scalar half_height = size.height / 2;
3116  std::vector<Rect> texture_coordinates = {
3117  Rect::MakeLTRB(0, 0, half_width, half_height),
3118  Rect::MakeLTRB(half_width, 0, size.width, half_height),
3119  Rect::MakeLTRB(0, half_height, half_width, size.height),
3120  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
3121  // Position quadrants adjacent to eachother.
3122  std::vector<Matrix> transforms = {
3123  Matrix::MakeTranslation({0, 0, 0}),
3124  Matrix::MakeTranslation({half_width, 0, 0}),
3125  Matrix::MakeTranslation({0, half_height, 0}),
3126  Matrix::MakeTranslation({half_width, half_height, 0})};
3127 
3128  Paint paint;
3129 
3130  Canvas canvas;
3131  canvas.Scale({0.25, 0.25, 1.0});
3132  canvas.DrawAtlas(image, transforms, texture_coordinates, {},
3133  BlendMode::kModulate, {}, std::nullopt, paint);
3134 
3135  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3136 }

References impeller::Canvas::DrawAtlas(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [110/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawAtlasWithColorAdvancedAndTransform   
)

Definition at line 3075 of file aiks_unittests.cc.

3075  {
3076  // Draws the image as four squares stiched together.
3077  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
3078  auto size = atlas->GetSize();
3079  auto image = std::make_shared<Image>(atlas);
3080  // Divide image into four quadrants.
3081  Scalar half_width = size.width / 2;
3082  Scalar half_height = size.height / 2;
3083  std::vector<Rect> texture_coordinates = {
3084  Rect::MakeLTRB(0, 0, half_width, half_height),
3085  Rect::MakeLTRB(half_width, 0, size.width, half_height),
3086  Rect::MakeLTRB(0, half_height, half_width, size.height),
3087  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
3088  // Position quadrants adjacent to eachother.
3089  std::vector<Matrix> transforms = {
3090  Matrix::MakeTranslation({0, 0, 0}),
3091  Matrix::MakeTranslation({half_width, 0, 0}),
3092  Matrix::MakeTranslation({0, half_height, 0}),
3093  Matrix::MakeTranslation({half_width, half_height, 0})};
3094  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
3095  Color::Yellow()};
3096 
3097  Paint paint;
3098 
3099  Canvas canvas;
3100  canvas.Scale({0.25, 0.25, 1.0});
3101  canvas.DrawAtlas(image, transforms, texture_coordinates, colors,
3102  BlendMode::kModulate, {}, std::nullopt, paint);
3103 
3104  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3105 }

References impeller::Canvas::DrawAtlas(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Canvas::Scale().

◆ TEST_P() [111/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintAbsorbsClears   
)

Definition at line 2255 of file aiks_unittests.cc.

2255  {
2256  Canvas canvas;
2257  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2258  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2259  .blend_mode = BlendMode::kSourceOver});
2260 
2261  Picture picture = canvas.EndRecordingAsPicture();
2262  auto expected = Color::Red().Blend(Color::CornflowerBlue().WithAlpha(0.75),
2263  BlendMode::kSourceOver);
2264  ASSERT_EQ(picture.pass->GetClearColor(), expected);
2265 
2266  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2267  std::shared_ptr<Context> real_context = GetContext();
2268  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2269  AiksContext renderer(mock_context, nullptr);
2270  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2271 
2272  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2273  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2274  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2275 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Picture::pass, and impeller::Picture::ToImage().

◆ TEST_P() [112/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintTransformsBounds   
)

Definition at line 3014 of file aiks_unittests.cc.

3014  {
3015  if (GetParam() != PlaygroundBackend::kMetal) {
3016  GTEST_SKIP_("This backend doesn't support runtime effects.");
3017  }
3018 
3019  auto runtime_stage = OpenAssetAsRuntimeStage("gradient.frag.iplr");
3020  ASSERT_TRUE(runtime_stage->IsDirty());
3021 
3022  struct FragUniforms {
3023  Size size;
3024  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
3025  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
3026  uniform_data->resize(sizeof(FragUniforms));
3027  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
3028 
3029  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
3030 
3031  Paint paint;
3032  paint.color_source = ColorSource::MakeRuntimeEffect(
3033  runtime_stage, uniform_data, texture_inputs);
3034 
3035  Canvas canvas;
3036  canvas.Save();
3037  canvas.Scale(GetContentScale());
3038  canvas.DrawPaint(paint);
3039  canvas.Restore();
3040 
3041  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3042 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Scale().

◆ TEST_P() [113/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawPaintWithAdvancedBlendOverFilter   
)

Definition at line 1566 of file aiks_unittests.cc.

1566  {
1567  Paint filtered = {
1568  .color = Color::Black(),
1569  .mask_blur_descriptor =
1570  Paint::MaskBlurDescriptor{
1571  .style = FilterContents::BlurStyle::kNormal,
1572  .sigma = Sigma(60),
1573  },
1574  };
1575 
1576  Canvas canvas;
1577  canvas.DrawPaint({.color = Color::White()});
1578  canvas.DrawCircle({300, 300}, 200, filtered);
1579  canvas.DrawPaint({.color = Color::Green(), .blend_mode = BlendMode::kScreen});
1580  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1581 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [114/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawPictureClipped   
)

Definition at line 3282 of file aiks_unittests.cc.

3282  {
3283  Canvas subcanvas;
3284  subcanvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400), 15);
3285  subcanvas.DrawPaint({.color = Color::Red()});
3286  auto picture = subcanvas.EndRecordingAsPicture();
3287 
3288  Canvas canvas;
3289  canvas.DrawPaint({.color = Color::CornflowerBlue()});
3290 
3291  // Draw a red RRect via DrawPicture.
3292  canvas.DrawPicture(picture);
3293 
3294  // Draw over the picture with a larger green rectangle, completely covering it
3295  // up.
3296  canvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400).Expand(20), 15);
3297  canvas.DrawPaint({.color = Color::Green()});
3298 
3299  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3300 }

References impeller::Canvas::ClipRRect(), impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPicture(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [115/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawPictureWithText   
)

Definition at line 3253 of file aiks_unittests.cc.

3253  {
3254  Canvas subcanvas;
3255  ASSERT_TRUE(RenderTextInCanvasSkia(
3256  GetContext(), subcanvas,
3257  "the quick brown fox jumped over the lazy dog!.?", "Roboto-Regular.ttf"));
3258  subcanvas.Translate({0, 10});
3259  subcanvas.Scale(Vector2(3, 3));
3260  ASSERT_TRUE(RenderTextInCanvasSkia(
3261  GetContext(), subcanvas,
3262  "the quick brown fox jumped over the very big lazy dog!.?",
3263  "Roboto-Regular.ttf"));
3264  auto picture = subcanvas.EndRecordingAsPicture();
3265 
3266  Canvas canvas;
3267  canvas.Scale(Vector2(.2, .2));
3268  canvas.Save();
3269  canvas.Translate({200, 200});
3270  canvas.Scale(Vector2(3.5, 3.5)); // The text must not be blurry after this.
3271  canvas.DrawPicture(picture);
3272  canvas.Restore();
3273 
3274  canvas.Scale(Vector2(1.5, 1.5));
3275  ASSERT_TRUE(RenderTextInCanvasSkia(
3276  GetContext(), canvas,
3277  "the quick brown fox jumped over the smaller lazy dog!.?",
3278  "Roboto-Regular.ttf"));
3279  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3280 }

References impeller::Canvas::DrawPicture(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [116/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClears   
)

Definition at line 2301 of file aiks_unittests.cc.

2301  {
2302  Canvas canvas;
2303  canvas.DrawRect({0, 0, 300, 300},
2304  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2305  canvas.DrawRect({0, 0, 300, 300},
2306  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2307  .blend_mode = BlendMode::kSourceOver});
2308 
2309  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2310  Picture picture = canvas.EndRecordingAsPicture();
2311  std::shared_ptr<Context> real_context = GetContext();
2312  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2313  AiksContext renderer(mock_context, nullptr);
2314  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2315 
2316  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2317  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2318  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2319 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Picture::ToImage().

◆ TEST_P() [117/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegative   
)

Definition at line 2361 of file aiks_unittests.cc.

2361  {
2362  Canvas canvas;
2363  canvas.DrawRect({0, 0, 300, 300},
2364  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2365  canvas.DrawRect({0, 0, 300, 300},
2366  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2367  .blend_mode = BlendMode::kSourceOver});
2368 
2369  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2370  Picture picture = canvas.EndRecordingAsPicture();
2371  std::shared_ptr<Context> real_context = GetContext();
2372  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2373  AiksContext renderer(mock_context, nullptr);
2374  std::shared_ptr<Image> image = picture.ToImage(renderer, {301, 301});
2375 
2376  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2377  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2378  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2379 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Picture::ToImage().

◆ TEST_P() [118/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegativeRotation   
)

Definition at line 2341 of file aiks_unittests.cc.

2341  {
2342  Canvas canvas;
2343  canvas.Translate(Vector3(150.0, 150.0, 0.0));
2344  canvas.Rotate(Degrees(45.0));
2345  canvas.Translate(Vector3(-150.0, -150.0, 0.0));
2346  canvas.DrawRect({0, 0, 300, 300},
2347  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2348 
2349  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2350  Picture picture = canvas.EndRecordingAsPicture();
2351  std::shared_ptr<Context> real_context = GetContext();
2352  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2353  AiksContext renderer(mock_context, nullptr);
2354  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2355 
2356  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2357  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2358  ASSERT_EQ(render_pass->GetCommands().size(), 1llu);
2359 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Rotate(), impeller::Picture::ToImage(), and impeller::Canvas::Translate().

◆ TEST_P() [119/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectAbsorbsClearsNegativeRRect   
)

Definition at line 2321 of file aiks_unittests.cc.

2321  {
2322  Canvas canvas;
2323  canvas.DrawRRect({0, 0, 300, 300}, 5.0,
2324  {.color = Color::Red(), .blend_mode = BlendMode::kSource});
2325  canvas.DrawRRect({0, 0, 300, 300}, 5.0,
2326  {.color = Color::CornflowerBlue().WithAlpha(0.75),
2327  .blend_mode = BlendMode::kSourceOver});
2328 
2329  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2330  Picture picture = canvas.EndRecordingAsPicture();
2331  std::shared_ptr<Context> real_context = GetContext();
2332  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2333  AiksContext renderer(mock_context, nullptr);
2334  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2335 
2336  ASSERT_EQ(spy->render_passes_.size(), 1llu);
2337  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2338  ASSERT_EQ(render_pass->GetCommands().size(), 2llu);
2339 }

References impeller::Canvas::DrawRRect(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Picture::ToImage().

◆ TEST_P() [120/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawRectStrokesRenderCorrectly   
)

Definition at line 2024 of file aiks_unittests.cc.

2024  {
2025  Canvas canvas;
2026  Paint paint;
2027  paint.color = Color::Red();
2028  paint.style = Paint::Style::kStroke;
2029  paint.stroke_width = 10;
2030 
2031  canvas.Translate({100, 100});
2032  canvas.DrawPath(
2033  PathBuilder{}.AddRect(Rect::MakeSize(Size{100, 100})).TakePath(),
2034  {paint});
2035 
2036  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2037 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::stroke_width, impeller::Paint::style, and impeller::Canvas::Translate().

◆ TEST_P() [121/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveNoSaveLayer   
)

Definition at line 3383 of file aiks_unittests.cc.

3383  {
3384  Canvas canvas;
3385  // clang-format off
3386  canvas.Transform(Matrix(
3387  2.000000, 0.000000, 0.000000, 0.000000,
3388  1.445767, 2.637070, -0.507928, 0.001524,
3389  -2.451887, -0.534662, 0.861399, -0.002584,
3390  1063.481934, 1025.951416, -48.300270, 1.144901
3391  ));
3392  // clang-format on
3393 
3394  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3395  "Roboto-Regular.ttf"));
3396 
3397  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3398 }

References impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), and impeller::Canvas::Transform().

◆ TEST_P() [122/317]

impeller::testing::TEST_P ( AiksTest  ,
DrawScaledTextWithPerspectiveSaveLayer   
)

Definition at line 3400 of file aiks_unittests.cc.

3400  {
3401  Canvas canvas;
3402  Paint save_paint;
3403  canvas.SaveLayer(save_paint);
3404  // clang-format off
3405  canvas.Transform(Matrix(
3406  2.000000, 0.000000, 0.000000, 0.000000,
3407  1.445767, 2.637070, -0.507928, 0.001524,
3408  -2.451887, -0.534662, 0.861399, -0.002584,
3409  1063.481934, 1025.951416, -48.300270, 1.144901
3410  ));
3411  // clang-format on
3412 
3413  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3414  "Roboto-Regular.ttf"));
3415 }

References RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [123/317]

impeller::testing::TEST_P ( AiksTest  ,
ForegroundBlendSubpassCollapseOptimization   
)

Definition at line 2459 of file aiks_unittests.cc.

2459  {
2460  Canvas canvas;
2461 
2462  canvas.SaveLayer({
2463  .color_filter =
2464  ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
2465  });
2466 
2467  canvas.Translate({500, 300, 0});
2468  canvas.Rotate(Radians(2 * kPi / 3));
2469  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2470 
2471  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2472 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [124/317]

impeller::testing::TEST_P ( AiksTest  ,
GradientStrokesRenderCorrectly   
)

Definition at line 1913 of file aiks_unittests.cc.

1913  {
1914  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
1915  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1916  static float scale = 3;
1917  static bool add_circle_clip = true;
1918  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1919  const Entity::TileMode tile_modes[] = {
1920  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1921  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1922  static int selected_tile_mode = 0;
1923  static float alpha = 1;
1924 
1925  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1926  ImGui::SliderFloat("Scale", &scale, 0, 6);
1927  ImGui::Checkbox("Circle clip", &add_circle_clip);
1928  ImGui::SliderFloat("Alpha", &alpha, 0, 1);
1929  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1930  sizeof(tile_mode_names) / sizeof(char*));
1931  ImGui::End();
1932 
1933  Canvas canvas;
1934  canvas.Scale(GetContentScale());
1935  Paint paint;
1936  paint.color = Color::White();
1937  canvas.DrawPaint(paint);
1938 
1939  paint.style = Paint::Style::kStroke;
1940  paint.color = Color(1.0, 1.0, 1.0, alpha);
1941  paint.stroke_width = 10;
1942  auto tile_mode = tile_modes[selected_tile_mode];
1943 
1944  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
1945  Color{0.1294, 0.5882, 0.9529, 1.0}};
1946  std::vector<Scalar> stops = {0.0, 1.0};
1947 
1948  paint.color_source = ColorSource::MakeLinearGradient(
1949  {0, 0}, {50, 50}, std::move(colors), std::move(stops), tile_mode, {});
1950 
1951  Path path = PathBuilder{}
1952  .MoveTo({20, 20})
1953  .QuadraticCurveTo({60, 20}, {60, 60})
1954  .Close()
1955  .MoveTo({60, 20})
1956  .QuadraticCurveTo({60, 60}, {20, 60})
1957  .TakePath();
1958 
1959  canvas.Scale(Vector2(scale, scale));
1960 
1961  if (add_circle_clip) {
1962  auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
1963  Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red());
1964 
1965  auto screen_to_canvas = canvas.GetCurrentTransformation().Invert();
1966  Point point_a = screen_to_canvas * handle_a * GetContentScale();
1967  Point point_b = screen_to_canvas * handle_b * GetContentScale();
1968 
1969  Point middle = (point_a + point_b) / 2;
1970  auto radius = point_a.GetDistance(middle);
1971  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
1972  }
1973 
1974  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
1975  paint.stroke_join = join;
1976  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
1977  paint.stroke_cap = cap;
1978  canvas.DrawPath(path, paint);
1979  canvas.Translate({80, 0});
1980  }
1981  canvas.Translate({-240, 60});
1982  }
1983 
1984  return canvas.EndRecordingAsPicture();
1985  };
1986 
1987  ASSERT_TRUE(OpenPlaygroundHere(callback));
1988 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Close(), impeller::Paint::color, impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransformation(), impeller::TPoint< T >::GetDistance(), IMPELLER_PLAYGROUND_LINE, impeller::Matrix::Invert(), impeller::PathBuilder::MoveTo(), impeller::Canvas::Scale(), impeller::Paint::stroke_cap, impeller::Paint::stroke_join, impeller::Paint::stroke_width, impeller::Paint::style, impeller::PathBuilder::TakePath(), and impeller::Canvas::Translate().

◆ TEST_P() [125/317]

impeller::testing::TEST_P ( AiksTest  ,
LinearToSrgbFilterSubpassCollapseOptimization   
)

Definition at line 2495 of file aiks_unittests.cc.

2495  {
2496  Canvas canvas;
2497 
2498  canvas.SaveLayer({
2499  .color_filter = ColorFilter::MakeLinearToSrgb(),
2500  });
2501 
2502  canvas.Translate({500, 300, 0});
2503  canvas.Rotate(Radians(2 * kPi / 3));
2504  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2505 
2506  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2507 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [126/317]

impeller::testing::TEST_P ( AiksTest  ,
MaskBlurWithZeroSigmaIsSkipped   
)

Definition at line 3629 of file aiks_unittests.cc.

3629  {
3630  Canvas canvas;
3631 
3632  Paint paint = {
3633  .color = Color::White(),
3634  .mask_blur_descriptor =
3635  Paint::MaskBlurDescriptor{
3636  .style = FilterContents::BlurStyle::kNormal,
3637  .sigma = Sigma(0),
3638  },
3639  };
3640 
3641  canvas.DrawCircle({300, 300}, 200, paint);
3642  canvas.DrawRect(Rect::MakeLTRB(100, 300, 500, 600), paint);
3643 
3644  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3645 }

References impeller::Paint::color, impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), and impeller::Paint::MaskBlurDescriptor::style.

◆ TEST_P() [127/317]

impeller::testing::TEST_P ( AiksTest  ,
MatrixBackdropFilter   
)

Definition at line 3329 of file aiks_unittests.cc.

3329  {
3330  Canvas canvas;
3331  canvas.DrawPaint({.color = Color::Black()});
3332  canvas.SaveLayer({}, std::nullopt);
3333  {
3334  canvas.DrawCircle(Point(200, 200), 100,
3335  {.color = Color::Green().WithAlpha(0.5),
3336  .blend_mode = BlendMode::kPlus});
3337  // Should render a second circle, centered on the bottom-right-most edge of
3338  // the circle.
3339  canvas.SaveLayer(
3340  {}, std::nullopt,
3341  ImageFilter::MakeMatrix(
3342  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
3343  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3344  Matrix::MakeTranslation(Vector2(-100, -100)),
3345  SamplerDescriptor{}));
3346  canvas.Restore();
3347  }
3348  canvas.Restore();
3349 
3350  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3351 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::k1OverSqrt2, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [128/317]

impeller::testing::TEST_P ( AiksTest  ,
MatrixImageFilterMagnify   
)

Definition at line 3589 of file aiks_unittests.cc.

3589  {
3590  Canvas canvas;
3591  canvas.Scale(GetContentScale());
3592  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3593  canvas.Translate({600, -200});
3594  canvas.SaveLayer({
3595  .image_filter = std::make_shared<MatrixImageFilter>(
3596  Matrix{
3597  2, 0, 0, 0, //
3598  0, 2, 0, 0, //
3599  0, 0, 2, 0, //
3600  0, 0, 0, 1 //
3601  },
3602  SamplerDescriptor{}),
3603  });
3604  canvas.DrawImage(image, {0, 0}, Paint{.color = Color(1.0, 1.0, 1.0, 0.5)});
3605  canvas.Restore();
3606 
3607  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3608 }

References impeller::Paint::color, impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [129/317]

impeller::testing::TEST_P ( AiksTest  ,
MatrixSaveLayerFilter   
)

Definition at line 3302 of file aiks_unittests.cc.

3302  {
3303  Canvas canvas;
3304  canvas.DrawPaint({.color = Color::Black()});
3305  canvas.SaveLayer({}, std::nullopt);
3306  {
3307  canvas.DrawCircle(Point(200, 200), 100,
3308  {.color = Color::Green().WithAlpha(0.5),
3309  .blend_mode = BlendMode::kPlus});
3310  // Should render a second circle, centered on the bottom-right-most edge of
3311  // the circle.
3312  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
3313  Matrix::MakeTranslation(Vector2(1, 1) *
3314  (200 + 100 * k1OverSqrt2)) *
3315  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3316  Matrix::MakeTranslation(Vector2(-200, -200)),
3317  SamplerDescriptor{})},
3318  std::nullopt);
3319  canvas.DrawCircle(Point(200, 200), 100,
3320  {.color = Color::Green().WithAlpha(0.5),
3321  .blend_mode = BlendMode::kPlus});
3322  canvas.Restore();
3323  }
3324  canvas.Restore();
3325 
3326  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3327 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::k1OverSqrt2, impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [130/317]

impeller::testing::TEST_P ( AiksTest  ,
OpacityPeepHoleApplicationTest   
)

Definition at line 2216 of file aiks_unittests.cc.

2216  {
2217  auto entity_pass = std::make_shared<EntityPass>();
2218  auto rect = Rect::MakeLTRB(0, 0, 100, 100);
2219  Paint paint;
2220  paint.color = Color::White().WithAlpha(0.5);
2221  paint.color_filter =
2222  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
2223 
2224  // Paint has color filter, can't elide.
2225  auto delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
2226  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
2227 
2228  paint.color_filter = nullptr;
2229  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
2230  FilterContents::BlurStyle::kNormal,
2231  Entity::TileMode::kClamp);
2232 
2233  // Paint has image filter, can't elide.
2234  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
2235  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
2236 
2237  paint.image_filter = nullptr;
2238  paint.color = Color::Red();
2239 
2240  // Paint has no alpha, can't elide;
2241  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
2242  ASSERT_FALSE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
2243 
2244  // Positive test.
2245  Entity entity;
2246  entity.SetContents(SolidColorContents::Make(
2247  PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
2248  entity_pass->AddEntity(entity);
2249  paint.color = Color::Red().WithAlpha(0.5);
2250 
2251  delegate = std::make_shared<OpacityPeepholePassDelegate>(paint);
2252  ASSERT_TRUE(delegate->CanCollapseIntoParentPass(entity_pass.get()));
2253 }

References impeller::PathBuilder::AddRect(), impeller::Paint::color, impeller::Paint::color_filter, impeller::Paint::image_filter, impeller::Entity::SetContents(), and impeller::Color::WithAlpha().

◆ TEST_P() [131/317]

impeller::testing::TEST_P ( AiksTest  ,
OpaqueEntitiesGetCoercedToSource   
)

Definition at line 2817 of file aiks_unittests.cc.

2817  {
2818  Canvas canvas;
2819  canvas.Scale(Vector2(1.618, 1.618));
2820  canvas.DrawCircle(Point(), 10,
2821  {
2822  .color = Color::CornflowerBlue(),
2823  .blend_mode = BlendMode::kSourceOver,
2824  });
2825  Picture picture = canvas.EndRecordingAsPicture();
2826 
2827  // Extract the SolidColorSource.
2828  Entity entity;
2829  std::shared_ptr<SolidColorContents> contents;
2830  picture.pass->IterateAllEntities([&e = entity, &contents](Entity& entity) {
2831  if (ScalarNearlyEqual(entity.GetTransformation().GetScale().x, 1.618f)) {
2832  e = entity;
2833  contents =
2834  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2835  return false;
2836  }
2837  return true;
2838  });
2839 
2840  ASSERT_TRUE(contents->IsOpaque());
2841  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSource);
2842 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Entity::GetBlendMode(), impeller::Entity::GetContents(), impeller::Matrix::GetScale(), impeller::Entity::GetTransformation(), impeller::Picture::pass, impeller::ScalarNearlyEqual(), impeller::Canvas::Scale(), and impeller::Vector3::x.

◆ TEST_P() [132/317]

impeller::testing::TEST_P ( AiksTest  ,
PaintBlendModeIsRespected   
)

Definition at line 1656 of file aiks_unittests.cc.

1656  {
1657  Paint paint;
1658  Canvas canvas;
1659  // Default is kSourceOver.
1660  paint.color = Color(1, 0, 0, 0.5);
1661  canvas.DrawCircle(Point(150, 200), 100, paint);
1662  paint.color = Color(0, 1, 0, 0.5);
1663  canvas.DrawCircle(Point(250, 200), 100, paint);
1664 
1665  paint.blend_mode = BlendMode::kPlus;
1666  paint.color = Color::Red();
1667  canvas.DrawCircle(Point(450, 250), 100, paint);
1668  paint.color = Color::Green();
1669  canvas.DrawCircle(Point(550, 250), 100, paint);
1670  paint.color = Color::Blue();
1671  canvas.DrawCircle(Point(500, 150), 100, paint);
1672  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1673 }

References impeller::Paint::blend_mode, impeller::Paint::color, impeller::Canvas::DrawCircle(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [133/317]

impeller::testing::TEST_P ( AiksTest  ,
PaintWithFilters   
)

Definition at line 2189 of file aiks_unittests.cc.

2189  {
2190  // validate that a paint with a color filter "HasFilters", no other filters
2191  // impact this setting.
2192  Paint paint;
2193 
2194  ASSERT_FALSE(paint.HasColorFilter());
2195 
2196  paint.color_filter =
2197  ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
2198 
2199  ASSERT_TRUE(paint.HasColorFilter());
2200 
2201  paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
2202  FilterContents::BlurStyle::kNormal,
2203  Entity::TileMode::kClamp);
2204 
2205  ASSERT_TRUE(paint.HasColorFilter());
2206 
2207  paint.mask_blur_descriptor = {};
2208 
2209  ASSERT_TRUE(paint.HasColorFilter());
2210 
2211  paint.color_filter = nullptr;
2212 
2213  ASSERT_FALSE(paint.HasColorFilter());
2214 }

References impeller::Paint::color_filter, impeller::Paint::HasColorFilter(), impeller::Paint::image_filter, and impeller::Paint::mask_blur_descriptor.

◆ TEST_P() [134/317]

impeller::testing::TEST_P ( AiksTest  ,
ParentSaveLayerCreatesRenderPassWhenChildBackdropFilterIsPresent   
)

Definition at line 2279 of file aiks_unittests.cc.

2280  {
2281  Canvas canvas;
2282  canvas.SaveLayer({}, std::nullopt, ImageFilter::MakeMatrix(Matrix(), {}));
2283  canvas.DrawPaint({.color = Color::Red(), .blend_mode = BlendMode::kSource});
2284  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2285  .blend_mode = BlendMode::kSourceOver});
2286  canvas.Restore();
2287 
2288  Picture picture = canvas.EndRecordingAsPicture();
2289 
2290  std::shared_ptr<ContextSpy> spy = ContextSpy::Make();
2291  std::shared_ptr<Context> real_context = GetContext();
2292  std::shared_ptr<ContextMock> mock_context = spy->MakeContext(real_context);
2293  AiksContext renderer(mock_context, nullptr);
2294  std::shared_ptr<Image> image = picture.ToImage(renderer, {300, 300});
2295 
2296  ASSERT_EQ(spy->render_passes_.size(), 3llu);
2297  std::shared_ptr<RenderPass> render_pass = spy->render_passes_[0];
2298  ASSERT_EQ(render_pass->GetCommands().size(), 0llu);
2299 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Picture::ToImage().

◆ TEST_P() [135/317]

impeller::testing::TEST_P ( AiksTest  ,
PipelineBlendSingleParameter   
)

Definition at line 3417 of file aiks_unittests.cc.

3417  {
3418  Canvas canvas;
3419 
3420  // Should render a green square in the middle of a blue circle.
3421  canvas.SaveLayer({});
3422  {
3423  canvas.Translate(Point(100, 100));
3424  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
3425  canvas.ClipRect(Rect(100, 100, 200, 200));
3426  canvas.DrawCircle(Point(200, 200), 200,
3427  {
3428  .color = Color::Green(),
3429  .blend_mode = BlendMode::kSourceOver,
3430  .image_filter = ImageFilter::MakeFromColorFilter(
3431  *ColorFilter::MakeBlend(BlendMode::kDestination,
3432  Color::White())),
3433  });
3434  canvas.Restore();
3435  }
3436 
3437  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3438 }

References impeller::Canvas::ClipRect(), impeller::Canvas::DrawCircle(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [136/317]

impeller::testing::TEST_P ( AiksTest  ,
ReleasesTextureOnTeardown   
)

Definition at line 3505 of file aiks_unittests.cc.

3505  {
3506  auto context = GetContext();
3507  std::weak_ptr<Texture> weak_texture;
3508 
3509  {
3510  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3511 
3512  Canvas canvas;
3513  canvas.Scale(GetContentScale());
3514  canvas.Translate({100.0f, 100.0f, 0});
3515 
3516  Paint paint;
3517  paint.color_source = ColorSource::MakeImage(
3518  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
3519  canvas.DrawRect({0, 0, 600, 600}, paint);
3520 
3521  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3522  }
3523 
3524  // See https://github.com/flutter/flutter/issues/134751.
3525  //
3526  // If the fence waiter was working this may not be released by the end of the
3527  // scope above. Adding a manual shutdown so that future changes to the fence
3528  // waiter will not flake this test.
3529  context->Shutdown();
3530 
3531  // The texture should be released by now.
3532  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
3533  "by the backend, it should be "
3534  "released.";
3535 }

References impeller::Paint::color_source, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [137/317]

impeller::testing::TEST_P ( AiksTest  ,
RotateColorFilteredPath   
)

Definition at line 56 of file aiks_unittests.cc.

56  {
57  Canvas canvas;
58  canvas.Concat(Matrix::MakeTranslation({300, 300}));
59  canvas.Concat(Matrix::MakeRotationZ(Radians(kPiOver2)));
60  auto arrow_stem =
61  PathBuilder{}.MoveTo({120, 190}).LineTo({120, 50}).TakePath();
62  auto arrow_head = PathBuilder{}
63  .MoveTo({50, 120})
64  .LineTo({120, 190})
65  .LineTo({190, 120})
66  .TakePath();
67  auto paint = Paint{
68  .stroke_width = 15.0,
69  .stroke_cap = Cap::kRound,
70  .stroke_join = Join::kRound,
71  .style = Paint::Style::kStroke,
72  .color_filter =
73  ColorFilter::MakeBlend(BlendMode::kSourceIn, Color::AliceBlue()),
74  };
75 
76  canvas.DrawPath(arrow_stem, paint);
77  canvas.DrawPath(arrow_head, paint);
78  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
79 }

References impeller::Color::AliceBlue(), impeller::Canvas::Concat(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPiOver2, impeller::kRound, impeller::kSourceIn, impeller::Paint::kStroke, impeller::LineTo(), impeller::ColorFilter::MakeBlend(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::PathBuilder::MoveTo(), and impeller::Paint::stroke_width.

◆ TEST_P() [138/317]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerDrawsBehindSubsequentEntities   
)

Definition at line 2039 of file aiks_unittests.cc.

2039  {
2040  // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636
2041  Canvas canvas;
2042  Paint paint;
2043 
2044  paint.color = Color::Black();
2045  Rect rect(25, 25, 25, 25);
2046  canvas.DrawRect(rect, paint);
2047 
2048  canvas.Translate({10, 10});
2049  canvas.SaveLayer({});
2050 
2051  paint.color = Color::Green();
2052  canvas.DrawRect(rect, paint);
2053 
2054  canvas.Restore();
2055 
2056  canvas.Translate({10, 10});
2057  paint.color = Color::Red();
2058  canvas.DrawRect(rect, paint);
2059 
2060  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2061 }

References impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [139/317]

impeller::testing::TEST_P ( AiksTest  ,
SaveLayerFiltersScaleWithTransform   
)

Definition at line 2120 of file aiks_unittests.cc.

2120  {
2121  Canvas canvas;
2122  canvas.Scale(GetContentScale());
2123  canvas.Translate(Vector2(100, 100));
2124 
2125  auto texture = std::make_shared<Image>(CreateTextureForFixture("boston.jpg"));
2126  auto draw_image_layer = [&canvas, &texture](const Paint& paint) {
2127  canvas.SaveLayer(paint);
2128  canvas.DrawImage(texture, {}, Paint{});
2129  canvas.Restore();
2130  };
2131 
2132  Paint effect_paint;
2133  effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
2134  .style = FilterContents::BlurStyle::kNormal,
2135  .sigma = Sigma{6},
2136  };
2137  draw_image_layer(effect_paint);
2138 
2139  canvas.Translate(Vector2(300, 300));
2140  canvas.Scale(Vector2(3, 3));
2141  draw_image_layer(effect_paint);
2142 
2143  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2144 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Paint::mask_blur_descriptor, impeller::Canvas::Restore(), impeller::Canvas::SaveLayer(), impeller::Canvas::Scale(), impeller::Paint::MaskBlurDescriptor::style, and impeller::Canvas::Translate().

◆ TEST_P() [140/317]

impeller::testing::TEST_P ( AiksTest  ,
SiblingSaveLayerBoundsAreRespected   
)

Definition at line 2063 of file aiks_unittests.cc.

2063  {
2064  Canvas canvas;
2065  Paint paint;
2066  Rect rect(0, 0, 1000, 1000);
2067 
2068  // Black, green, and red squares offset by [10, 10].
2069  {
2070  canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25));
2071  paint.color = Color::Black();
2072  canvas.DrawRect(rect, paint);
2073  canvas.Restore();
2074  }
2075 
2076  {
2077  canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25));
2078  paint.color = Color::Green();
2079  canvas.DrawRect(rect, paint);
2080  canvas.Restore();
2081  }
2082 
2083  {
2084  canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25));
2085  paint.color = Color::Red();
2086  canvas.DrawRect(rect, paint);
2087  canvas.Restore();
2088  }
2089 
2090  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2091 }

References impeller::Paint::color, impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [141/317]

impeller::testing::TEST_P ( AiksTest  ,
SolidColorApplyColorFilter   
)

Definition at line 3353 of file aiks_unittests.cc.

3353  {
3354  auto contents = SolidColorContents();
3355  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
3356  auto result = contents.ApplyColorFilter([](const Color& color) {
3357  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
3358  });
3359  ASSERT_TRUE(result);
3360  ASSERT_COLOR_NEAR(contents.GetColor(),
3361  Color(0.433247, 0.879523, 0.825324, 0.75));
3362 }

References ASSERT_COLOR_NEAR, and impeller::Color::Blend().

◆ TEST_P() [142/317]

impeller::testing::TEST_P ( AiksTest  ,
SolidStrokesRenderCorrectly   
)

Definition at line 1850 of file aiks_unittests.cc.

1850  {
1851  // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2
1852  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1853  static Color color = Color::Black().WithAlpha(0.5);
1854  static float scale = 3;
1855  static bool add_circle_clip = true;
1856 
1857  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1858  ImGui::ColorEdit4("Color", reinterpret_cast<float*>(&color));
1859  ImGui::SliderFloat("Scale", &scale, 0, 6);
1860  ImGui::Checkbox("Circle clip", &add_circle_clip);
1861  ImGui::End();
1862 
1863  Canvas canvas;
1864  canvas.Scale(GetContentScale());
1865  Paint paint;
1866 
1867  paint.color = Color::White();
1868  canvas.DrawPaint(paint);
1869 
1870  paint.color = color;
1871  paint.style = Paint::Style::kStroke;
1872  paint.stroke_width = 10;
1873 
1874  Path path = PathBuilder{}
1875  .MoveTo({20, 20})
1876  .QuadraticCurveTo({60, 20}, {60, 60})
1877  .Close()
1878  .MoveTo({60, 20})
1879  .QuadraticCurveTo({60, 60}, {20, 60})
1880  .TakePath();
1881 
1882  canvas.Scale(Vector2(scale, scale));
1883 
1884  if (add_circle_clip) {
1885  auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE(
1886  Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red());
1887 
1888  auto screen_to_canvas = canvas.GetCurrentTransformation().Invert();
1889  Point point_a = screen_to_canvas * handle_a * GetContentScale();
1890  Point point_b = screen_to_canvas * handle_b * GetContentScale();
1891 
1892  Point middle = (point_a + point_b) / 2;
1893  auto radius = point_a.GetDistance(middle);
1894  canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath());
1895  }
1896 
1897  for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) {
1898  paint.stroke_join = join;
1899  for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) {
1900  paint.stroke_cap = cap;
1901  canvas.DrawPath(path, paint);
1902  canvas.Translate({80, 0});
1903  }
1904  canvas.Translate({-240, 60});
1905  }
1906 
1907  return canvas.EndRecordingAsPicture();
1908  };
1909 
1910  ASSERT_TRUE(OpenPlaygroundHere(callback));
1911 }

References impeller::PathBuilder::AddCircle(), impeller::Canvas::ClipPath(), impeller::Close(), impeller::Paint::color, impeller::Canvas::DrawPaint(), impeller::Canvas::DrawPath(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::GetCurrentTransformation(), impeller::TPoint< T >::GetDistance(), IMPELLER_PLAYGROUND_LINE, impeller::Matrix::Invert(), impeller::PathBuilder::MoveTo(), impeller::Canvas::Scale(), impeller::Paint::stroke_cap, impeller::Paint::stroke_join, impeller::Paint::stroke_width, impeller::Paint::style, impeller::PathBuilder::TakePath(), impeller::Canvas::Translate(), and impeller::Color::WithAlpha().

◆ TEST_P() [143/317]

impeller::testing::TEST_P ( AiksTest  ,
SrgbToLinearFilterSubpassCollapseOptimization   
)

Definition at line 2509 of file aiks_unittests.cc.

2509  {
2510  Canvas canvas;
2511 
2512  canvas.SaveLayer({
2513  .color_filter = ColorFilter::MakeSrgbToLinear(),
2514  });
2515 
2516  canvas.Translate({500, 300, 0});
2517  canvas.Rotate(Radians(2 * kPi / 3));
2518  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2519 
2520  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2521 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::kPi, impeller::Canvas::Rotate(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Translate().

◆ TEST_P() [144/317]

impeller::testing::TEST_P ( AiksTest  ,
SubpassWithClearColorOptimization   
)

Definition at line 3647 of file aiks_unittests.cc.

3647  {
3648  Canvas canvas;
3649 
3650  // Use a non-srcOver blend mode to ensure that we don't detect this as an
3651  // opacity peephole optimization.
3652  canvas.SaveLayer(
3653  {.color = Color::Blue().WithAlpha(0.5), .blend_mode = BlendMode::kSource},
3654  Rect::MakeLTRB(0, 0, 200, 200));
3655  canvas.DrawPaint(
3656  {.color = Color::BlackTransparent(), .blend_mode = BlendMode::kSource});
3657  canvas.Restore();
3658 
3659  canvas.SaveLayer(
3660  {.color = Color::Blue(), .blend_mode = BlendMode::kDestinationOver});
3661  canvas.Restore();
3662 
3663  // This playground should appear blank on CI since we are only drawing
3664  // transparent black. If the clear color optimization is broken, the texture
3665  // will be filled with NaNs and may produce a magenta texture on macOS or iOS.
3666  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3667 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [145/317]

impeller::testing::TEST_P ( AiksTest  ,
TextForegroundShaderWithTransform   
)

Definition at line 3171 of file aiks_unittests.cc.

3171  {
3172  auto mapping = OpenFixtureAsSkData("Roboto-Regular.ttf");
3173  ASSERT_NE(mapping, nullptr);
3174 
3175  Scalar font_size = 100;
3176  SkFont sk_font(SkTypeface::MakeFromData(mapping), font_size);
3177 
3178  Paint text_paint;
3179  text_paint.color = Color::Blue();
3180 
3181  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
3182  Color{0.1294, 0.5882, 0.9529, 1.0}};
3183  std::vector<Scalar> stops = {
3184  0.0,
3185  1.0,
3186  };
3187  text_paint.color_source = ColorSource::MakeLinearGradient(
3188  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
3189  Entity::TileMode::kRepeat, {});
3190 
3191  Canvas canvas;
3192  canvas.Translate({100, 100});
3193  canvas.Rotate(Radians(kPi / 4));
3194 
3195  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
3196  ASSERT_NE(blob, nullptr);
3197  auto frame = MakeTextFrameFromTextBlobSkia(blob);
3198  canvas.DrawTextFrame(frame, Point(), text_paint);
3199 
3200  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3201 }

References impeller::Paint::color, impeller::Paint::color_source, impeller::kPi, impeller::MakeTextFrameFromTextBlobSkia(), OpenFixtureAsSkData(), and impeller::Canvas::Translate().

◆ TEST_P() [146/317]

impeller::testing::TEST_P ( AiksTest  ,
TextFrameSubpixelAlignment   
)

Definition at line 1385 of file aiks_unittests.cc.

1385  {
1386  std::array<Scalar, 20> phase_offsets;
1387  for (Scalar& offset : phase_offsets) {
1388  auto rand = std::rand(); // NOLINT
1389  offset = (static_cast<float>(rand) / static_cast<float>(RAND_MAX)) * k2Pi;
1390  }
1391 
1392  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
1393  static float font_size = 20;
1394  static float phase_variation = 0.2;
1395  static float speed = 0.5;
1396  static float magnitude = 100;
1397  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1398  ImGui::SliderFloat("Font size", &font_size, 5, 50);
1399  ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1);
1400  ImGui::SliderFloat("Oscillation speed", &speed, 0, 2);
1401  ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300);
1402  ImGui::End();
1403 
1404  Canvas canvas;
1405  canvas.Scale(GetContentScale());
1406 
1407  for (size_t i = 0; i < phase_offsets.size(); i++) {
1408  auto position = Point(
1409  200 + magnitude * std::sin((-phase_offsets[i] * phase_variation +
1410  GetSecondsElapsed() * speed)), //
1411  200 + i * font_size * 1.1 //
1412  );
1414  GetContext(), canvas,
1415  "the quick brown fox jumped over "
1416  "the lazy dog!.?",
1417  "Roboto-Regular.ttf",
1418  {.font_size = font_size, .position = position})) {
1419  return std::nullopt;
1420  }
1421  }
1422  return canvas.EndRecordingAsPicture();
1423  };
1424 
1425  ASSERT_TRUE(OpenPlaygroundHere(callback));
1426 }

References impeller::Canvas::EndRecordingAsPicture(), impeller::k2Pi, RenderTextInCanvasSkia(), and impeller::Canvas::Scale().

◆ TEST_P() [147/317]

impeller::testing::TEST_P ( AiksTest  ,
TextRotated   
)

Definition at line 1526 of file aiks_unittests.cc.

1526  {
1527  Canvas canvas;
1528  canvas.Scale(GetContentScale());
1529  canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)});
1530 
1531  canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, //
1532  0, 0.5, 0, 0, //
1533  0, 0, 0.3, 0, //
1534  100, 100, 0, 1.3));
1535  ASSERT_TRUE(RenderTextInCanvasSkia(
1536  GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?",
1537  "Roboto-Regular.ttf"));
1538 
1539  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1540 }

References impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Scale(), and impeller::Canvas::Transform().

◆ TEST_P() [148/317]

impeller::testing::TEST_P ( AiksTest  ,
TransformMultipliesCorrectly   
)

Definition at line 1811 of file aiks_unittests.cc.

1811  {
1812  Canvas canvas;
1813  ASSERT_MATRIX_NEAR(canvas.GetCurrentTransformation(), Matrix());
1814 
1815  // clang-format off
1816  canvas.Translate(Vector3(100, 200));
1818  canvas.GetCurrentTransformation(),
1819  Matrix( 1, 0, 0, 0,
1820  0, 1, 0, 0,
1821  0, 0, 1, 0,
1822  100, 200, 0, 1));
1823 
1824  canvas.Rotate(Radians(kPiOver2));
1826  canvas.GetCurrentTransformation(),
1827  Matrix( 0, 1, 0, 0,
1828  -1, 0, 0, 0,
1829  0, 0, 1, 0,
1830  100, 200, 0, 1));
1831 
1832  canvas.Scale(Vector3(2, 3));
1834  canvas.GetCurrentTransformation(),
1835  Matrix( 0, 2, 0, 0,
1836  -3, 0, 0, 0,
1837  0, 0, 0, 0,
1838  100, 200, 0, 1));
1839 
1840  canvas.Translate(Vector3(100, 200));
1842  canvas.GetCurrentTransformation(),
1843  Matrix( 0, 2, 0, 0,
1844  -3, 0, 0, 0,
1845  0, 0, 0, 0,
1846  -500, 400, 0, 1));
1847  // clang-format on
1848 }

References ASSERT_MATRIX_NEAR, impeller::Canvas::GetCurrentTransformation(), impeller::kPiOver2, impeller::Canvas::Rotate(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [149/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerDrawsCorrectly   
)

Definition at line 2615 of file aiks_unittests.cc.

2615  {
2616  Canvas canvas;
2617 
2618  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2619 
2620  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2621  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2622  canvas.Restore();
2623 
2624  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2625 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [150/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerImageDrawsCorrectly   
)

Definition at line 2677 of file aiks_unittests.cc.

2677  {
2678  Canvas canvas;
2679 
2680  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2681  canvas.DrawImage(image, {100, 100}, {});
2682 
2683  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2684  canvas.DrawImage(image, {100, 500}, {});
2685  canvas.Restore();
2686 
2687  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2688 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [151/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithAdvancedBlendModeDrawsCorrectly   
)

Definition at line 2761 of file aiks_unittests.cc.

2761  {
2762  Canvas canvas;
2763  canvas.DrawRect({0, 0, 400, 400}, {.color = Color::Red()});
2764  canvas.SaveLayer({
2765  .color = Color::Black().WithAlpha(0.5),
2766  .blend_mode = BlendMode::kLighten,
2767  });
2768  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2769  canvas.Restore();
2770  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2771 }

References impeller::Canvas::DrawCircle(), impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [152/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendColorFilterDrawsCorrectly   
)

Definition at line 2627 of file aiks_unittests.cc.

2627  {
2628  Canvas canvas;
2629 
2630  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2631 
2632  canvas.SaveLayer({
2633  .color = Color::Black().WithAlpha(0.5),
2634  .color_filter =
2635  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2636  });
2637  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2638  canvas.Restore();
2639 
2640  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2641 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [153/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithBlendImageFilterDrawsCorrectly   
)

Definition at line 2643 of file aiks_unittests.cc.

2643  {
2644  Canvas canvas;
2645 
2646  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2647 
2648  canvas.SaveLayer({
2649  .color = Color::Black().WithAlpha(0.5),
2650  .image_filter = ImageFilter::MakeFromColorFilter(
2651  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
2652  });
2653 
2654  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2655  canvas.Restore();
2656 
2657  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2658 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [154/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorAndImageFilterDrawsCorrectly   
)

Definition at line 2660 of file aiks_unittests.cc.

2660  {
2661  Canvas canvas;
2662 
2663  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2664 
2665  canvas.SaveLayer({
2666  .color = Color::Black().WithAlpha(0.5),
2667  .color_filter =
2668  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2669  });
2670 
2671  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2672  canvas.Restore();
2673 
2674  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2675 }

References impeller::Canvas::DrawRect(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [155/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorFilterAndImageFilterDrawsCorrectly   
)

Definition at line 2735 of file aiks_unittests.cc.

2736  {
2737  Canvas canvas;
2738 
2739  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2740  canvas.DrawImage(image, {100, 100}, {});
2741 
2742  canvas.SaveLayer({
2743  .color = Color::Black().WithAlpha(0.5),
2744  .image_filter = ImageFilter::MakeFromColorFilter(
2745  *ColorFilter::MakeMatrix({.array =
2746  {
2747  1, 0, 0, 0, 0, //
2748  0, 1, 0, 0, 0, //
2749  0, 0.2, 1, 0, 0, //
2750  0, 0, 0, 0.5, 0 //
2751  }})),
2752  .color_filter =
2753  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2754  });
2755  canvas.DrawImage(image, {100, 500}, {});
2756  canvas.Restore();
2757 
2758  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2759 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [156/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixColorFilterDrawsCorrectly   
)

Definition at line 2690 of file aiks_unittests.cc.

2690  {
2691  Canvas canvas;
2692 
2693  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2694  canvas.DrawImage(image, {100, 100}, {});
2695 
2696  canvas.SaveLayer({
2697  .color = Color::Black().WithAlpha(0.5),
2698  .color_filter = ColorFilter::MakeMatrix({.array =
2699  {
2700  1, 0, 0, 0, 0, //
2701  0, 1, 0, 0, 0, //
2702  0, 0, 1, 0, 0, //
2703  0, 0, 0, 2, 0 //
2704  }}),
2705  });
2706  canvas.DrawImage(image, {100, 500}, {});
2707  canvas.Restore();
2708 
2709  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2710 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [157/317]

impeller::testing::TEST_P ( AiksTest  ,
TranslucentSaveLayerWithColorMatrixImageFilterDrawsCorrectly   
)

Definition at line 2712 of file aiks_unittests.cc.

2712  {
2713  Canvas canvas;
2714 
2715  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2716  canvas.DrawImage(image, {100, 100}, {});
2717 
2718  canvas.SaveLayer({
2719  .color = Color::Black().WithAlpha(0.5),
2720  .image_filter = ImageFilter::MakeFromColorFilter(
2721  *ColorFilter::MakeMatrix({.array =
2722  {
2723  1, 0, 0, 0, 0, //
2724  0, 1, 0, 0, 0, //
2725  0, 0, 1, 0, 0, //
2726  0, 0, 0, 2, 0 //
2727  }})),
2728  });
2729  canvas.DrawImage(image, {100, 500}, {});
2730  canvas.Restore();
2731 
2732  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2733 }

References impeller::Canvas::DrawImage(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), and impeller::Canvas::SaveLayer().

◆ TEST_P() [158/317]

impeller::testing::TEST_P ( AiksTest  ,
VerticesGeometryUVPositionData   
)

Definition at line 3538 of file aiks_unittests.cc.

3538  {
3539  Canvas canvas;
3540  Paint paint;
3541  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3542 
3543  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
3544  Entity::TileMode::kClamp, {}, {});
3545 
3546  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3547  Point(0, texture->GetSize().height)};
3548  std::vector<uint16_t> indices = {0u, 1u, 2u};
3549  std::vector<Point> texture_coordinates = {};
3550  std::vector<Color> vertex_colors = {};
3551  auto geometry = std::make_shared<VerticesGeometry>(
3552  vertices, indices, texture_coordinates, vertex_colors,
3553  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3554 
3555  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3556  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3557 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [159/317]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
CapabilitiesSuportSubgroups   
)

Definition at line 42 of file compute_subgroup_unittests.cc.

42  {
43  auto context = GetContext();
44  ASSERT_TRUE(context);
45  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
46 }

◆ TEST_P() [160/317]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
LargePath   
)

Definition at line 179 of file compute_subgroup_unittests.cc.

179  {
180  // The path in here is large enough to highlight issues around exceeding
181  // subgroup size.
182  using SS = StrokeComputeShader;
183 
184  auto context = GetContext();
185  ASSERT_TRUE(context);
186  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
187  size_t vertex_count = 0;
188  Scalar stroke_width = 1.0;
189 
190  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
191  context, "VertexBuffer");
192  auto vertex_buffer_count =
193  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
194  "VertexCount");
195 
196  auto complex_path =
197  PathBuilder{}
198  .MoveTo({359.934, 96.6335})
199  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
200  {354.673, 96.8895})
201  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
202  {354.367, 96.9075})
203  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
204  {349.259, 97.2355})
205  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
206  {348.625, 97.2834})
207  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
208  {343.789, 97.6722})
209  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
210  {342.703, 97.7734})
211  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
212  {338.246, 98.207})
213  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
214  {336.612, 98.3894})
215  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
216  {332.623, 98.8476})
217  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
218  {332.237, 98.8982})
219  .LineTo({332.237, 102.601})
220  .LineTo({321.778, 102.601})
221  .LineTo({321.778, 100.382})
222  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
223  {321.161, 100.476})
224  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
225  {315.332, 101.479})
226  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
227  {315.301, 101.484})
228  .LineTo({310.017, 105.94})
229  .LineTo({309.779, 105.427})
230  .LineTo({314.403, 101.651})
231  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
232  {314.368, 101.658})
233  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
234  {308.846, 102.748})
235  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
236  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
237  {303.425, 103.936})
238  .LineTo({299.105, 107.578})
239  .LineTo({298.867, 107.065})
240  .LineTo({302.394, 104.185})
241  .LineTo({302.412, 104.171})
242  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
243  {299.344, 104.921})
244  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
245  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
246  {291.462, 106.979})
247  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
248  {290.471, 107.257})
249  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
250  {287.449, 108.139})
251  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
252  {284.536, 109.035})
253  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
254  {281.952, 109.859})
255  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
256  {279.633, 110.638})
257  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
258  {276.803, 111.607})
259  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
260  {276.672, 111.653})
261  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
262  {271.721, 113.463})
263  .LineTo({271.717, 113.449})
264  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
265  {270.963, 113.628})
266  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
267  {270.748, 113.682})
268  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
269  {269.839, 113.926})
270  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
271  {269.681, 113.972})
272  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
273  {268.756, 114.239})
274  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
275  {268.367, 114.354})
276  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
277  {267.752, 114.54})
278  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
279  {253.564, 119.252})
280  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
281  {253.538, 119.261})
282  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
283  {248.189, 121.131})
284  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
285  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
286  {245.975, 121.912})
287  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
288  {244.698, 122.364})
289  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
290  {242.794, 123.04})
291  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
292  {240.961, 123.693})
293  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
294  {240.052, 124.018})
295  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
296  .LineTo({237.164, 125.003})
297  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
298  {235.81, 125.538})
299  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
300  {234.592, 125.977})
301  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
302  {234.59, 125.977})
303  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
304  {192.381, 141.429})
305  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
306  .LineTo({360, 160})
307  .LineTo({360, 119.256})
308  .LineTo({360, 106.332})
309  .LineTo({360, 96.6307})
310  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
311  {359.934, 96.6335})
312  .Close()
313  .TakePath();
314 
315  auto callback = [&](RenderPass& pass) -> bool {
316  ::memset(vertex_buffer_count->AsBufferView().contents, 0,
317  sizeof(SS::VertexBufferCount));
318  ::memset(vertex_buffer->AsBufferView().contents, 0,
319  sizeof(SS::VertexBuffer<2048>));
320 
321  ComputeTessellator{}
322  .SetStrokeWidth(stroke_width)
323  .Tessellate(
324  complex_path, context, vertex_buffer->AsBufferView(),
325  vertex_buffer_count->AsBufferView(),
326  [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) {
327  vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
328  vertex_buffer_count->AsBufferView().contents)
329  ->count;
330  });
331 
332  ContentContext renderer(context, nullptr);
333  if (!renderer.IsValid()) {
334  return false;
335  }
336 
337  using VS = SolidFillPipeline::VertexShader;
338 
339  Command cmd;
340  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
341  cmd.stencil_reference = 0;
342 
343  ContentContextOptions options;
344  options.sample_count = pass.GetRenderTarget().GetSampleCount();
345  options.color_attachment_pixel_format =
346  pass.GetRenderTarget().GetRenderTargetPixelFormat();
347  options.has_stencil_attachment =
348  pass.GetRenderTarget().GetStencilAttachment().has_value();
349  options.blend_mode = BlendMode::kSourceIn;
350  options.primitive_type = PrimitiveType::kTriangleStrip;
351  options.stencil_compare = CompareFunction::kEqual;
352  options.stencil_operation = StencilOperation::kIncrementClamp;
353 
354  cmd.pipeline = renderer.GetSolidFillPipeline(options);
355 
356  auto count = reinterpret_cast<SS::VertexBufferCount*>(
357  vertex_buffer_count->AsBufferView().contents)
358  ->count;
359 
360  VertexBuffer render_vertex_buffer{
361  .vertex_buffer = vertex_buffer->AsBufferView(),
362  .vertex_count = count,
363  .index_type = IndexType::kNone};
364  cmd.BindVertices(render_vertex_buffer);
365 
366  VS::FrameInfo frame_info;
367  auto world_matrix = Matrix::MakeScale(GetContentScale());
368  frame_info.mvp =
369  Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
370  frame_info.color = Color::Red().Premultiply();
371  VS::BindFrameInfo(cmd,
372  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
373 
374  if (!pass.AddCommand(std::move(cmd))) {
375  return false;
376  }
377 
378  return true;
379  };
380  ASSERT_TRUE(OpenPlaygroundHere(callback));
381 }

References impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::Close(), impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::kSourceIn, impeller::kTriangleStrip, impeller::LineTo(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [161/317]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
PathPlayground   
)

Definition at line 48 of file compute_subgroup_unittests.cc.

48  {
49  // Renders stroked SVG paths in an interactive playground.
50  using SS = StrokeComputeShader;
51 
52  auto context = GetContext();
53  ASSERT_TRUE(context);
54  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
55  char svg_path_data[16384] =
56  "M140 20 "
57  "C73 20 20 74 20 140 "
58  "c0 135 136 170 228 303 "
59  "88-132 229-173 229-303 "
60  "0-66-54-120-120-120 "
61  "-48 0-90 28-109 69 "
62  "-19-41-60-69-108-69z";
63  size_t vertex_count = 0;
64  Scalar stroke_width = 1.0;
65 
66  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
67  context, "VertexBuffer");
68  auto vertex_buffer_count =
69  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
70  "VertexCount");
71 
72  auto callback = [&](RenderPass& pass) -> bool {
73  ::memset(vertex_buffer_count->AsBufferView().contents, 0,
74  sizeof(SS::VertexBufferCount));
75  ::memset(vertex_buffer->AsBufferView().contents, 0,
76  sizeof(SS::VertexBuffer<2048>));
77  const auto* main_viewport = ImGui::GetMainViewport();
78  ImGui::SetNextWindowPos(
79  ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20));
80  ImGui::Begin("Path data", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
81  ImGui::InputTextMultiline("Path", svg_path_data,
82  IM_ARRAYSIZE(svg_path_data));
83  ImGui::DragFloat("Stroke width", &stroke_width, .1, 0.0, 25.0);
84 
85  SkPath sk_path;
86  if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) {
87  std::promise<bool> promise;
88  auto future = promise.get_future();
89 
90  auto path = skia_conversions::ToPath(sk_path);
91  auto status =
92  ComputeTessellator{}
93  .SetStrokeWidth(stroke_width)
94  .Tessellate(
95  path, context, vertex_buffer->AsBufferView(),
96  vertex_buffer_count->AsBufferView(),
97  [vertex_buffer_count, &vertex_count,
98  &promise](CommandBuffer::Status status) {
99  vertex_count =
100  reinterpret_cast<SS::VertexBufferCount*>(
101  vertex_buffer_count->AsBufferView().contents)
102  ->count;
103  promise.set_value(status ==
104  CommandBuffer::Status::kCompleted);
105  });
106  switch (status) {
107  case ComputeTessellator::Status::kCommandInvalid:
108  ImGui::Text("Failed to submit compute job (invalid command)");
109  break;
110  case ComputeTessellator::Status::kTooManyComponents:
111  ImGui::Text("Failed to submit compute job (too many components) ");
112  break;
113  case ComputeTessellator::Status::kOk:
114  break;
115  }
116  if (!future.get()) {
117  ImGui::Text("Failed to submit compute job.");
118  return false;
119  }
120  if (vertex_count > 0) {
121  ImGui::Text("Vertex count: %zu", vertex_count);
122  }
123  } else {
124  ImGui::Text("Failed to parse path data");
125  }
126  ImGui::End();
127 
128  ContentContext renderer(context, nullptr);
129  if (!renderer.IsValid()) {
130  return false;
131  }
132 
133  using VS = SolidFillPipeline::VertexShader;
134 
135  Command cmd;
136  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
137  cmd.stencil_reference = 0;
138 
139  ContentContextOptions options;
140  options.sample_count = pass.GetRenderTarget().GetSampleCount();
141  options.color_attachment_pixel_format =
142  pass.GetRenderTarget().GetRenderTargetPixelFormat();
143  options.has_stencil_attachment =
144  pass.GetRenderTarget().GetStencilAttachment().has_value();
145  options.blend_mode = BlendMode::kSourceIn;
146  options.primitive_type = PrimitiveType::kTriangleStrip;
147  options.stencil_compare = CompareFunction::kEqual;
148  options.stencil_operation = StencilOperation::kIncrementClamp;
149 
150  cmd.pipeline = renderer.GetSolidFillPipeline(options);
151 
152  auto count = reinterpret_cast<SS::VertexBufferCount*>(
153  vertex_buffer_count->AsBufferView().contents)
154  ->count;
155 
156  VertexBuffer render_vertex_buffer{
157  .vertex_buffer = vertex_buffer->AsBufferView(),
158  .vertex_count = count,
159  .index_type = IndexType::kNone};
160  cmd.BindVertices(render_vertex_buffer);
161 
162  VS::FrameInfo frame_info;
163  auto world_matrix = Matrix::MakeScale(GetContentScale());
164  frame_info.mvp =
165  Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
166  frame_info.color = Color::Red().Premultiply();
167  VS::BindFrameInfo(cmd,
168  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
169 
170  if (!pass.AddCommand(std::move(cmd))) {
171  return false;
172  }
173 
174  return true;
175  };
176  ASSERT_TRUE(OpenPlaygroundHere(callback));
177 }

References impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::ComputeTessellator::kCommandInvalid, impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::ComputeTessellator::kTooManyComponents, impeller::kTriangleStrip, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ComputeTessellator::SetStrokeWidth(), impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), impeller::skia_conversions::ToPath(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [162/317]

impeller::testing::TEST_P ( ComputeSubgroupTest  ,
QuadAndCubicInOnePath   
)

Definition at line 383 of file compute_subgroup_unittests.cc.

383  {
384  using SS = StrokeComputeShader;
385 
386  auto context = GetContext();
387  ASSERT_TRUE(context);
388  ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
389 
390  auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
391  context, "VertexBuffer");
392  auto vertex_buffer_count =
393  CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
394  "VertexBufferCount");
395 
396  auto path = PathBuilder{}
397  .AddCubicCurve({140, 20}, {73, 20}, {20, 74}, {20, 140})
398  .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42})
399  .TakePath();
400 
401  auto tessellator = ComputeTessellator{};
402 
403  fml::AutoResetWaitableEvent latch;
404 
405  auto status = tessellator.Tessellate(
406  path, context, vertex_buffer->AsBufferView(),
407  vertex_buffer_count->AsBufferView(),
408  [&latch](CommandBuffer::Status status) {
409  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
410  latch.Signal();
411  });
412 
413  ASSERT_EQ(status, ComputeTessellator::Status::kOk);
414 
415  auto callback = [&](RenderPass& pass) -> bool {
416  ContentContext renderer(context, nullptr);
417  if (!renderer.IsValid()) {
418  return false;
419  }
420 
421  using VS = SolidFillPipeline::VertexShader;
422 
423  Command cmd;
424  DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
425  cmd.stencil_reference = 0;
426 
427  ContentContextOptions options;
428  options.sample_count = pass.GetRenderTarget().GetSampleCount();
429  options.color_attachment_pixel_format =
430  pass.GetRenderTarget().GetRenderTargetPixelFormat();
431  options.has_stencil_attachment =
432  pass.GetRenderTarget().GetStencilAttachment().has_value();
433  options.blend_mode = BlendMode::kSourceIn;
434  options.primitive_type = PrimitiveType::kTriangleStrip;
435  options.stencil_compare = CompareFunction::kEqual;
436  options.stencil_operation = StencilOperation::kIncrementClamp;
437 
438  cmd.pipeline = renderer.GetSolidFillPipeline(options);
439 
440  auto count = reinterpret_cast<SS::VertexBufferCount*>(
441  vertex_buffer_count->AsBufferView().contents)
442  ->count;
443 
444  VertexBuffer render_vertex_buffer{
445  .vertex_buffer = vertex_buffer->AsBufferView(),
446  .vertex_count = count,
447  .index_type = IndexType::kNone};
448  cmd.BindVertices(render_vertex_buffer);
449 
450  VS::FrameInfo frame_info;
451  auto world_matrix = Matrix::MakeScale(GetContentScale());
452  frame_info.mvp =
453  Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
454  frame_info.color = Color::Red().Premultiply();
455  VS::BindFrameInfo(cmd,
456  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
457 
458  if (!pass.AddCommand(std::move(cmd))) {
459  return false;
460  }
461 
462  return true;
463  };
464  ASSERT_TRUE(OpenPlaygroundHere(callback));
465 
466  // The latch is down here because it's expected that on Metal the backend
467  // will take care of synchronizing the buffer between the compute and render
468  // pass usages, since it's not MTLHeap allocated. However, if playgrounds
469  // are disabled, no render pass actually gets submitted and we need to do a
470  // CPU latch here.
471  latch.Wait();
472 
473  auto vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
474  vertex_buffer_count->AsBufferView().contents)
475  ->count;
476  EXPECT_EQ(vertex_count, golden_cubic_and_quad_points.size());
477  auto vertex_buffer_data = reinterpret_cast<SS::VertexBuffer<2048>*>(
478  vertex_buffer->AsBufferView().contents);
479  for (size_t i = 0; i < vertex_count; i++) {
480  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].x -
481  vertex_buffer_data->position[i].x),
482  1e-3);
483  EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].y -
484  vertex_buffer_data->position[i].y),
485  1e-3);
486  }
487 }

References impeller::PathBuilder::AddCubicCurve(), impeller::Command::BindVertices(), impeller::ContentContextOptions::blend_mode, impeller::ContentContextOptions::color_attachment_pixel_format, DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), golden_cubic_and_quad_points, impeller::ContentContextOptions::has_stencil_attachment, impeller::ContentContext::IsValid(), impeller::kEqual, impeller::kIncrementClamp, impeller::kNone, impeller::ComputeTessellator::kOk, impeller::kSourceIn, impeller::kTriangleStrip, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::Color::Premultiply(), impeller::ContentContextOptions::primitive_type, impeller::Color::Red(), impeller::ContentContextOptions::sample_count, impeller::ContentContextOptions::stencil_compare, impeller::ContentContextOptions::stencil_operation, impeller::Command::stencil_reference, impeller::ComputeTessellator::Tessellate(), and impeller::VertexBuffer::vertex_buffer.

◆ TEST_P() [163/317]

impeller::testing::TEST_P ( ComputeTest  ,
1DThreadgroupSizingIsCorrect   
)

Definition at line 178 of file compute_unittests.cc.

178  {
179  using CS = ThreadgroupSizingTestComputeShader;
180  auto context = GetContext();
181  ASSERT_TRUE(context);
182  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
183 
184  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
185  auto pipeline_desc =
186  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
187  ASSERT_TRUE(pipeline_desc.has_value());
188  auto compute_pipeline =
189  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
190  ASSERT_TRUE(compute_pipeline);
191 
192  auto cmd_buffer = context->CreateCommandBuffer();
193  auto pass = cmd_buffer->CreateComputePass();
194  ASSERT_TRUE(pass && pass->IsValid());
195 
196  static constexpr size_t kCount = 2048;
197 
198  pass->SetGridSize(ISize(kCount, 1));
199  pass->SetThreadGroupSize(ISize(kCount, 1));
200 
201  ComputeCommand cmd;
202  cmd.pipeline = compute_pipeline;
203 
204  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
205  context, "Output Buffer");
206 
207  CS::BindOutputData(cmd, output_buffer->AsBufferView());
208 
209  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
210  ASSERT_TRUE(pass->EncodeCommands());
211 
212  fml::AutoResetWaitableEvent latch;
213  ASSERT_TRUE(cmd_buffer->SubmitCommands(
214  [&latch, output_buffer](CommandBuffer::Status status) {
215  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
216 
217  auto view = output_buffer->AsBufferView();
218  EXPECT_EQ(view.range.length, sizeof(CS::OutputData<kCount>));
219 
220  CS::OutputData<kCount>* output =
221  reinterpret_cast<CS::OutputData<kCount>*>(view.contents);
222  EXPECT_TRUE(output);
223  EXPECT_EQ(output->data[kCount - 1], kCount - 1);
224  latch.Signal();
225  }));
226 
227  latch.Wait();
228 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [164/317]

impeller::testing::TEST_P ( ComputeTest  ,
CanCompute1DimensionalData   
)

Definition at line 373 of file compute_unittests.cc.

373  {
374  using CS = SampleComputeShader;
375  auto context = GetContext();
376  ASSERT_TRUE(context);
377  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
378 
379  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
380  auto pipeline_desc =
381  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
382  ASSERT_TRUE(pipeline_desc.has_value());
383  auto compute_pipeline =
384  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
385  ASSERT_TRUE(compute_pipeline);
386 
387  auto cmd_buffer = context->CreateCommandBuffer();
388  auto pass = cmd_buffer->CreateComputePass();
389  ASSERT_TRUE(pass && pass->IsValid());
390 
391  static constexpr size_t kCount = 5;
392 
393  pass->SetGridSize(ISize(kCount, 1));
394 
395  ComputeCommand cmd;
396  cmd.pipeline = compute_pipeline;
397 
398  CS::Info info{.count = kCount};
399  CS::Input0<kCount> input_0;
400  CS::Input1<kCount> input_1;
401  for (size_t i = 0; i < kCount; i++) {
402  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
403  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
404  }
405 
406  input_0.fixed_array[1] = IPoint32(2, 2);
407  input_1.fixed_array[0] = UintPoint32(3, 3);
408  input_0.some_int = 5;
409  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
410 
411  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
412  context, "Output Buffer");
413 
414  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
415  CS::BindInput0(cmd,
416  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
417  CS::BindInput1(cmd,
418  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
419  CS::BindOutput(cmd, output_buffer->AsBufferView());
420 
421  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
422  ASSERT_TRUE(pass->EncodeCommands());
423 
424  fml::AutoResetWaitableEvent latch;
425  ASSERT_TRUE(
426  cmd_buffer->SubmitCommands([&latch, output_buffer, &input_0,
427  &input_1](CommandBuffer::Status status) {
428  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
429 
430  auto view = output_buffer->AsBufferView();
431  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
432 
433  CS::Output<kCount>* output =
434  reinterpret_cast<CS::Output<kCount>*>(view.contents);
435  EXPECT_TRUE(output);
436  for (size_t i = 0; i < kCount; i++) {
437  Vector4 vector = output->elements[i];
438  Vector4 computed = input_0.elements[i] * input_1.elements[i];
439  EXPECT_EQ(vector, Vector4(computed.x + 2 + input_1.some_struct.i,
440  computed.y + 3 + input_1.some_struct.vf.x,
441  computed.z + 5 + input_1.some_struct.vf.y,
442  computed.w));
443  }
444  latch.Signal();
445  }));
446 
447  latch.Wait();
448 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [165/317]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSum   
)

Definition at line 113 of file compute_unittests.cc.

113  {
114  using CS = PrefixSumTestComputeShader;
115  auto context = GetContext();
116  ASSERT_TRUE(context);
117  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
118 
119  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
120  auto pipeline_desc =
121  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
122  ASSERT_TRUE(pipeline_desc.has_value());
123  auto compute_pipeline =
124  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
125  ASSERT_TRUE(compute_pipeline);
126 
127  auto cmd_buffer = context->CreateCommandBuffer();
128  auto pass = cmd_buffer->CreateComputePass();
129  ASSERT_TRUE(pass && pass->IsValid());
130 
131  static constexpr size_t kCount = 5;
132 
133  pass->SetGridSize(ISize(kCount, 1));
134  pass->SetThreadGroupSize(ISize(kCount, 1));
135 
136  ComputeCommand cmd;
137  cmd.pipeline = compute_pipeline;
138 
139  CS::InputData<kCount> input_data;
140  input_data.count = kCount;
141  for (size_t i = 0; i < kCount; i++) {
142  input_data.data[i] = 1 + i;
143  }
144 
145  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
146  context, "Output Buffer");
147 
148  CS::BindInputData(
149  cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data));
150  CS::BindOutputData(cmd, output_buffer->AsBufferView());
151 
152  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
153  ASSERT_TRUE(pass->EncodeCommands());
154 
155  fml::AutoResetWaitableEvent latch;
156  ASSERT_TRUE(cmd_buffer->SubmitCommands(
157  [&latch, output_buffer](CommandBuffer::Status status) {
158  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
159 
160  auto view = output_buffer->AsBufferView();
161  EXPECT_EQ(view.range.length, sizeof(CS::OutputData<kCount>));
162 
163  CS::OutputData<kCount>* output =
164  reinterpret_cast<CS::OutputData<kCount>*>(view.contents);
165  EXPECT_TRUE(output);
166 
167  constexpr uint32_t expected[kCount] = {1, 3, 6, 10, 15};
168  for (size_t i = 0; i < kCount; i++) {
169  auto computed_sum = output->data[i];
170  EXPECT_EQ(computed_sum, expected[i]);
171  }
172  latch.Signal();
173  }));
174 
175  latch.Wait();
176 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [166/317]

impeller::testing::TEST_P ( ComputeTest  ,
CanComputePrefixSumLargeInteractive   
)

Definition at line 230 of file compute_unittests.cc.

230  {
231  using CS = PrefixSumTestComputeShader;
232 
233  auto context = GetContext();
234  ASSERT_TRUE(context);
235  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
236 
237  auto callback = [&](RenderPass& render_pass) -> bool {
238  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
239  auto pipeline_desc =
240  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
241  auto compute_pipeline =
242  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
243 
244  auto cmd_buffer = context->CreateCommandBuffer();
245  auto pass = cmd_buffer->CreateComputePass();
246 
247  static constexpr size_t kCount = 1023;
248 
249  pass->SetGridSize(ISize(kCount, 1));
250 
251  ComputeCommand cmd;
252  cmd.pipeline = compute_pipeline;
253 
254  CS::InputData<kCount> input_data;
255  input_data.count = kCount;
256  for (size_t i = 0; i < kCount; i++) {
257  input_data.data[i] = 1 + i;
258  }
259 
260  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::OutputData<kCount>>(
261  context, "Output Buffer");
262 
263  CS::BindInputData(
264  cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(input_data));
265  CS::BindOutputData(cmd, output_buffer->AsBufferView());
266 
267  pass->AddCommand(std::move(cmd));
268  pass->EncodeCommands();
269  return cmd_buffer->SubmitCommands();
270  };
271  ASSERT_TRUE(OpenPlaygroundHere(callback));
272 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [167/317]

impeller::testing::TEST_P ( ComputeTest  ,
CanCreateComputePass   
)

Definition at line 35 of file compute_unittests.cc.

35  {
36  using CS = SampleComputeShader;
37  auto context = GetContext();
38  ASSERT_TRUE(context);
39  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
40 
41  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
42  auto pipeline_desc =
43  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
44  ASSERT_TRUE(pipeline_desc.has_value());
45  auto compute_pipeline =
46  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
47  ASSERT_TRUE(compute_pipeline);
48 
49  auto cmd_buffer = context->CreateCommandBuffer();
50  auto pass = cmd_buffer->CreateComputePass();
51  ASSERT_TRUE(pass && pass->IsValid());
52 
53  static constexpr size_t kCount = 5;
54 
55  pass->SetGridSize(ISize(kCount, 1));
56  pass->SetThreadGroupSize(ISize(kCount, 1));
57 
58  ComputeCommand cmd;
59  cmd.pipeline = compute_pipeline;
60 
61  CS::Info info{.count = kCount};
62  CS::Input0<kCount> input_0;
63  CS::Input1<kCount> input_1;
64  for (size_t i = 0; i < kCount; i++) {
65  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
66  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
67  }
68 
69  input_0.fixed_array[1] = IPoint32(2, 2);
70  input_1.fixed_array[0] = UintPoint32(3, 3);
71  input_0.some_int = 5;
72  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
73 
74  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
75  context, "Output Buffer");
76 
77  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
78  CS::BindInput0(cmd,
79  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
80  CS::BindInput1(cmd,
81  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
82  CS::BindOutput(cmd, output_buffer->AsBufferView());
83 
84  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
85  ASSERT_TRUE(pass->EncodeCommands());
86 
87  fml::AutoResetWaitableEvent latch;
88  ASSERT_TRUE(
89  cmd_buffer->SubmitCommands([&latch, output_buffer, &input_0,
90  &input_1](CommandBuffer::Status status) {
91  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
92 
93  auto view = output_buffer->AsBufferView();
94  EXPECT_EQ(view.range.length, sizeof(CS::Output<kCount>));
95 
96  CS::Output<kCount>* output =
97  reinterpret_cast<CS::Output<kCount>*>(view.contents);
98  EXPECT_TRUE(output);
99  for (size_t i = 0; i < kCount; i++) {
100  Vector4 vector = output->elements[i];
101  Vector4 computed = input_0.elements[i] * input_1.elements[i];
102  EXPECT_EQ(vector, Vector4(computed.x + 2 + input_1.some_struct.i,
103  computed.y + 3 + input_1.some_struct.vf.x,
104  computed.z + 5 + input_1.some_struct.vf.y,
105  computed.w));
106  }
107  latch.Signal();
108  }));
109 
110  latch.Wait();
111 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [168/317]

impeller::testing::TEST_P ( ComputeTest  ,
CapabilitiesReportSupport   
)

Definition at line 29 of file compute_unittests.cc.

29  {
30  auto context = GetContext();
31  ASSERT_TRUE(context);
32  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
33 }

◆ TEST_P() [169/317]

impeller::testing::TEST_P ( ComputeTest  ,
MultiStageInputAndOutput   
)

Definition at line 274 of file compute_unittests.cc.

274  {
275  using CS1 = Stage1ComputeShader;
276  using Stage1PipelineBuilder = ComputePipelineBuilder<CS1>;
277  using CS2 = Stage2ComputeShader;
278  using Stage2PipelineBuilder = ComputePipelineBuilder<CS2>;
279 
280  auto context = GetContext();
281  ASSERT_TRUE(context);
282  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
283 
284  auto pipeline_desc_1 =
285  Stage1PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
286  ASSERT_TRUE(pipeline_desc_1.has_value());
287  auto compute_pipeline_1 =
288  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_1).Get();
289  ASSERT_TRUE(compute_pipeline_1);
290 
291  auto pipeline_desc_2 =
292  Stage2PipelineBuilder::MakeDefaultPipelineDescriptor(*context);
293  ASSERT_TRUE(pipeline_desc_2.has_value());
294  auto compute_pipeline_2 =
295  context->GetPipelineLibrary()->GetPipeline(pipeline_desc_2).Get();
296  ASSERT_TRUE(compute_pipeline_2);
297 
298  auto cmd_buffer = context->CreateCommandBuffer();
299  auto pass = cmd_buffer->CreateComputePass();
300  ASSERT_TRUE(pass && pass->IsValid());
301 
302  static constexpr size_t kCount1 = 5;
303  static constexpr size_t kCount2 = kCount1 * 2;
304 
305  pass->SetGridSize(ISize(512, 1));
306  pass->SetThreadGroupSize(ISize(512, 1));
307 
308  CS1::Input<kCount1> input_1;
309  input_1.count = kCount1;
310  for (size_t i = 0; i < kCount1; i++) {
311  input_1.elements[i] = i;
312  }
313 
314  CS2::Input<kCount2> input_2;
315  input_2.count = kCount2;
316  for (size_t i = 0; i < kCount2; i++) {
317  input_2.elements[i] = i;
318  }
319 
320  auto output_buffer_1 = CreateHostVisibleDeviceBuffer<CS1::Output<kCount2>>(
321  context, "Output Buffer Stage 1");
322  auto output_buffer_2 = CreateHostVisibleDeviceBuffer<CS2::Output<kCount2>>(
323  context, "Output Buffer Stage 2");
324 
325  {
326  ComputeCommand cmd;
327  cmd.pipeline = compute_pipeline_1;
328 
329  CS1::BindInput(cmd,
330  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
331  CS1::BindOutput(cmd, output_buffer_1->AsBufferView());
332 
333  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
334  }
335 
336  {
337  ComputeCommand cmd;
338  cmd.pipeline = compute_pipeline_2;
339 
340  CS1::BindInput(cmd, output_buffer_1->AsBufferView());
341  CS2::BindOutput(cmd, output_buffer_2->AsBufferView());
342  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
343  }
344 
345  ASSERT_TRUE(pass->EncodeCommands());
346 
347  fml::AutoResetWaitableEvent latch;
348  ASSERT_TRUE(cmd_buffer->SubmitCommands([&latch, &output_buffer_1,
349  &output_buffer_2](
350  CommandBuffer::Status status) {
351  EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
352 
353  CS1::Output<kCount2>* output_1 = reinterpret_cast<CS1::Output<kCount2>*>(
354  output_buffer_1->AsBufferView().contents);
355  EXPECT_TRUE(output_1);
356  EXPECT_EQ(output_1->count, 10u);
357  EXPECT_THAT(output_1->elements,
358  ::testing::ElementsAre(0, 0, 2, 3, 4, 6, 6, 9, 8, 12));
359 
360  CS2::Output<kCount2>* output_2 = reinterpret_cast<CS2::Output<kCount2>*>(
361  output_buffer_2->AsBufferView().contents);
362  EXPECT_TRUE(output_2);
363  EXPECT_EQ(output_2->count, 10u);
364  EXPECT_THAT(output_2->elements,
365  ::testing::ElementsAre(0, 0, 4, 6, 8, 12, 12, 18, 16, 24));
366 
367  latch.Signal();
368  }));
369 
370  latch.Wait();
371 }

References impeller::kCount1, and impeller::ComputeCommand::pipeline.

◆ TEST_P() [170/317]

impeller::testing::TEST_P ( ComputeTest  ,
ReturnsEarlyWhenAnyGridDimensionIsZero   
)

Definition at line 450 of file compute_unittests.cc.

450  {
451  using CS = SampleComputeShader;
452  auto context = GetContext();
453  ASSERT_TRUE(context);
454  ASSERT_TRUE(context->GetCapabilities()->SupportsCompute());
455 
456  using SamplePipelineBuilder = ComputePipelineBuilder<CS>;
457  auto pipeline_desc =
458  SamplePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
459  ASSERT_TRUE(pipeline_desc.has_value());
460  auto compute_pipeline =
461  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
462  ASSERT_TRUE(compute_pipeline);
463 
464  auto cmd_buffer = context->CreateCommandBuffer();
465  auto pass = cmd_buffer->CreateComputePass();
466  ASSERT_TRUE(pass && pass->IsValid());
467 
468  static constexpr size_t kCount = 5;
469 
470  // Intentionally making the grid size zero in one dimension. No GPU will
471  // tolerate this.
472  pass->SetGridSize(ISize(0, 1));
473  pass->SetThreadGroupSize(ISize(0, 1));
474 
475  ComputeCommand cmd;
476  cmd.pipeline = compute_pipeline;
477 
478  CS::Info info{.count = kCount};
479  CS::Input0<kCount> input_0;
480  CS::Input1<kCount> input_1;
481  for (size_t i = 0; i < kCount; i++) {
482  input_0.elements[i] = Vector4(2.0 + i, 3.0 + i, 4.0 + i, 5.0 * i);
483  input_1.elements[i] = Vector4(6.0, 7.0, 8.0, 9.0);
484  }
485 
486  input_0.fixed_array[1] = IPoint32(2, 2);
487  input_1.fixed_array[0] = UintPoint32(3, 3);
488  input_0.some_int = 5;
489  input_1.some_struct = CS::SomeStruct{.vf = Point(3, 4), .i = 42};
490 
491  auto output_buffer = CreateHostVisibleDeviceBuffer<CS::Output<kCount>>(
492  context, "Output Buffer");
493 
494  CS::BindInfo(cmd, pass->GetTransientsBuffer().EmplaceUniform(info));
495  CS::BindInput0(cmd,
496  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_0));
497  CS::BindInput1(cmd,
498  pass->GetTransientsBuffer().EmplaceStorageBuffer(input_1));
499  CS::BindOutput(cmd, output_buffer->AsBufferView());
500 
501  ASSERT_TRUE(pass->AddCommand(std::move(cmd)));
502  ASSERT_FALSE(pass->EncodeCommands());
503 }

References impeller::ComputeCommand::pipeline.

◆ TEST_P() [171/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanBlendDstOverAndDstCorrectly   
)

Definition at line 1263 of file dl_unittests.cc.

1263  {
1264  flutter::DisplayListBuilder builder;
1265 
1266  {
1267  builder.SaveLayer(nullptr, nullptr);
1268  builder.Translate(100, 100);
1269  flutter::DlPaint paint;
1270  paint.setColor(flutter::DlColor::kRed());
1271  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1272  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1273  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1274  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1275  builder.Restore();
1276  }
1277  {
1278  builder.SaveLayer(nullptr, nullptr);
1279  builder.Translate(300, 100);
1280  flutter::DlPaint paint;
1281  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1282  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1283  paint.setColor(flutter::DlColor::kRed());
1284  paint.setBlendMode(flutter::DlBlendMode::kDstOver);
1285  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1286  builder.Restore();
1287  }
1288  {
1289  builder.SaveLayer(nullptr, nullptr);
1290  builder.Translate(100, 300);
1291  flutter::DlPaint paint;
1292  paint.setColor(flutter::DlColor::kRed());
1293  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1294  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1295  paint.setBlendMode(flutter::DlBlendMode::kSrc);
1296  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1297  builder.Restore();
1298  }
1299  {
1300  builder.SaveLayer(nullptr, nullptr);
1301  builder.Translate(300, 300);
1302  flutter::DlPaint paint;
1303  paint.setColor(flutter::DlColor::kBlue().withAlpha(127));
1304  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1305  paint.setColor(flutter::DlColor::kRed());
1306  paint.setBlendMode(flutter::DlBlendMode::kDst);
1307  builder.DrawRect(SkRect::MakeSize({200, 200}), paint);
1308  builder.Restore();
1309  }
1310 
1311  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1312 }

◆ TEST_P() [172/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanClampTheResultingColorOfColorMatrixFilter   
)

Definition at line 627 of file dl_unittests.cc.

627  {
628  auto texture = CreateTextureForFixture("boston.jpg");
629  const float inner_color_matrix[20] = {
630  1, 0, 0, 0, 0, //
631  0, 1, 0, 0, 0, //
632  0, 0, 1, 0, 0, //
633  0, 0, 0, 2, 0, //
634  };
635  const float outer_color_matrix[20] = {
636  1, 0, 0, 0, 0, //
637  0, 1, 0, 0, 0, //
638  0, 0, 1, 0, 0, //
639  0, 0, 0, 0.5, 0, //
640  };
641  auto inner_color_filter =
642  std::make_shared<flutter::DlMatrixColorFilter>(inner_color_matrix);
643  auto outer_color_filter =
644  std::make_shared<flutter::DlMatrixColorFilter>(outer_color_matrix);
645  auto inner =
646  std::make_shared<flutter::DlColorFilterImageFilter>(inner_color_filter);
647  auto outer =
648  std::make_shared<flutter::DlColorFilterImageFilter>(outer_color_filter);
649  auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
650 
651  flutter::DisplayListBuilder builder;
652  flutter::DlPaint paint;
653  paint.setImageFilter(compose.get());
654  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
655  flutter::DlImageSampling::kNearestNeighbor, &paint);
656  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
657 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [173/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanConvertTriangleFanToTriangles   
)

Definition at line 974 of file dl_unittests.cc.

974  {
975  constexpr Scalar hexagon_radius = 125;
976  auto hex_start = Point(200.0, -hexagon_radius + 200.0);
977  auto center_to_flat = 1.73 / 2 * hexagon_radius;
978 
979  // clang-format off
980  std::vector<SkPoint> vertices = {
981  SkPoint::Make(hex_start.x, hex_start.y),
982  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 0.5 * hexagon_radius),
983  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
984  SkPoint::Make(hex_start.x + center_to_flat, hex_start.y + 1.5 * hexagon_radius),
985  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
986  SkPoint::Make(hex_start.x, hex_start.y + 2 * hexagon_radius),
987  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
988  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 1.5 * hexagon_radius),
989  SkPoint::Make(hex_start.x - center_to_flat, hex_start.y + 0.5 * hexagon_radius)
990  };
991  // clang-format on
992  auto paint = flutter::DlPaint(flutter::DlColor::kDarkGrey());
993  auto dl_vertices = flutter::DlVertices::Make(
994  flutter::DlVertexMode::kTriangleFan, vertices.size(), vertices.data(),
995  nullptr, nullptr);
996  flutter::DisplayListBuilder builder;
997  builder.DrawVertices(dl_vertices, flutter::DlBlendMode::kSrcOver, paint);
998  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
999 }

◆ TEST_P() [174/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawAnOpenPath   
)

Definition at line 417 of file dl_unittests.cc.

417  {
418  flutter::DisplayListBuilder builder;
419  flutter::DlPaint paint;
420 
421  paint.setColor(flutter::DlColor::kRed());
422  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
423  paint.setStrokeWidth(10);
424 
425  builder.Translate(300, 300);
426 
427  // Move to (50, 50) and draw lines from:
428  // 1. (50, height)
429  // 2. (width, height)
430  // 3. (width, 50)
431  SkPath path;
432  path.moveTo(50, 50);
433  path.lineTo(50, 100);
434  path.lineTo(100, 100);
435  path.lineTo(100, 50);
436  builder.DrawPath(path, paint);
437 
438  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
439 }

◆ TEST_P() [175/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawArc   
)

Definition at line 164 of file dl_unittests.cc.

164  {
165  auto callback = [&]() {
166  static float start_angle = 45;
167  static float sweep_angle = 270;
168  static float stroke_width = 10;
169  static bool use_center = true;
170 
171  static int selected_cap = 0;
172  const char* cap_names[] = {"Butt", "Round", "Square"};
173  flutter::DlStrokeCap cap;
174 
175  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
176  ImGui::SliderFloat("Start angle", &start_angle, -360, 360);
177  ImGui::SliderFloat("Sweep angle", &sweep_angle, -360, 360);
178  ImGui::SliderFloat("Stroke width", &stroke_width, 0, 300);
179  ImGui::Combo("Cap", &selected_cap, cap_names,
180  sizeof(cap_names) / sizeof(char*));
181  ImGui::Checkbox("Use center", &use_center);
182  ImGui::End();
183 
184  switch (selected_cap) {
185  case 0:
186  cap = flutter::DlStrokeCap::kButt;
187  break;
188  case 1:
189  cap = flutter::DlStrokeCap::kRound;
190  break;
191  case 2:
192  cap = flutter::DlStrokeCap::kSquare;
193  break;
194  default:
195  cap = flutter::DlStrokeCap::kButt;
196  break;
197  }
198 
199  auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
200  Point(200, 200), Point(400, 400), 20, Color::White(), Color::White());
201 
202  flutter::DisplayListBuilder builder;
203  flutter::DlPaint paint;
204 
205  Vector2 scale = GetContentScale();
206  builder.Scale(scale.x, scale.y);
207  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
208  paint.setStrokeCap(cap);
209  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
210  paint.setStrokeMiter(10);
211  auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
212  paint.setColor(flutter::DlColor::kGreen());
213  paint.setStrokeWidth(2);
214  builder.DrawRect(rect, paint);
215  paint.setColor(flutter::DlColor::kRed());
216  paint.setStrokeWidth(stroke_width);
217  builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
218 
219  return builder.Build();
220  };
221  ASSERT_TRUE(OpenPlaygroundHere(callback));
222 }

References IMPELLER_PLAYGROUND_LINE, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [176/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawBackdropFilter   
)

Definition at line 659 of file dl_unittests.cc.

659  {
660  auto texture = CreateTextureForFixture("embarcadero.jpg");
661 
662  auto callback = [&]() {
663  static float sigma[] = {10, 10};
664  static float ctm_scale = 1;
665  static bool use_bounds = true;
666  static bool draw_circle = true;
667  static bool add_clip = true;
668 
669  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
670  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
671  ImGui::SliderFloat("Scale", &ctm_scale, 0, 10);
672  ImGui::NewLine();
673  ImGui::TextWrapped(
674  "If everything is working correctly, none of the options below should "
675  "impact the filter's appearance.");
676  ImGui::Checkbox("Use SaveLayer bounds", &use_bounds);
677  ImGui::Checkbox("Draw child element", &draw_circle);
678  ImGui::Checkbox("Add pre-clip", &add_clip);
679  ImGui::End();
680 
681  flutter::DisplayListBuilder builder;
682 
683  Vector2 scale = ctm_scale * GetContentScale();
684  builder.Scale(scale.x, scale.y);
685 
686  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
687  flutter::DlTileMode::kClamp);
688 
689  std::optional<SkRect> bounds;
690  if (use_bounds) {
691  auto [p1, p2] = IMPELLER_PLAYGROUND_LINE(
692  Point(350, 150), Point(800, 600), 20, Color::White(), Color::White());
693  bounds = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
694  }
695 
696  // Insert a clip to test that the backdrop filter handles stencil depths > 0
697  // correctly.
698  if (add_clip) {
699  builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
700  flutter::DlCanvas::ClipOp::kIntersect, true);
701  }
702 
703  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
704  flutter::DlImageSampling::kNearestNeighbor, nullptr);
705  builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
706  &filter);
707 
708  if (draw_circle) {
709  auto circle_center =
710  IMPELLER_PLAYGROUND_POINT(Point(500, 400), 20, Color::Red());
711 
712  flutter::DlPaint paint;
713  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
714  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
715  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
716  paint.setStrokeWidth(10);
717  paint.setColor(flutter::DlColor::kRed().withAlpha(100));
718  builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
719  }
720 
721  return builder.Build();
722  };
723 
724  ASSERT_TRUE(OpenPlaygroundHere(callback));
725 }

References IMPELLER_PLAYGROUND_LINE, IMPELLER_PLAYGROUND_POINT, impeller::DlImageImpeller::Make(), impeller::Color::Red(), impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [177/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCapsAndJoins   
)

Definition at line 118 of file dl_unittests.cc.

118  {
119  flutter::DisplayListBuilder builder;
120  flutter::DlPaint paint;
121 
122  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
123  paint.setStrokeWidth(30);
124  paint.setColor(flutter::DlColor::kRed());
125 
126  auto path =
127  SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
128 
129  builder.Translate(100, 100);
130  {
131  paint.setStrokeCap(flutter::DlStrokeCap::kButt);
132  paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
133  paint.setStrokeMiter(4);
134  builder.DrawPath(path, paint);
135  }
136 
137  {
138  builder.Save();
139  builder.Translate(0, 100);
140  // The joint in the path is 45 degrees. A miter length of 1 convert to a
141  // bevel in this case.
142  paint.setStrokeMiter(1);
143  builder.DrawPath(path, paint);
144  builder.Restore();
145  }
146 
147  builder.Translate(150, 0);
148  {
149  paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
150  paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
151  builder.DrawPath(path, paint);
152  }
153 
154  builder.Translate(150, 0);
155  {
156  paint.setStrokeCap(flutter::DlStrokeCap::kRound);
157  paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
158  builder.DrawPath(path, paint);
159  }
160 
161  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
162 }

◆ TEST_P() [178/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawCorrectlyWithColorFilterAndImageFilter   
)

Definition at line 1314 of file dl_unittests.cc.

1314  {
1315  flutter::DisplayListBuilder builder;
1316  const float green_color_matrix[20] = {
1317  0, 0, 0, 0, 0, //
1318  0, 0, 0, 0, 1, //
1319  0, 0, 0, 0, 0, //
1320  0, 0, 0, 1, 0, //
1321  };
1322  const float blue_color_matrix[20] = {
1323  0, 0, 0, 0, 0, //
1324  0, 0, 0, 0, 0, //
1325  0, 0, 0, 0, 1, //
1326  0, 0, 0, 1, 0, //
1327  };
1328  auto green_color_filter =
1329  std::make_shared<flutter::DlMatrixColorFilter>(green_color_matrix);
1330  auto blue_color_filter =
1331  std::make_shared<flutter::DlMatrixColorFilter>(blue_color_matrix);
1332  auto blue_image_filter =
1333  std::make_shared<flutter::DlColorFilterImageFilter>(blue_color_filter);
1334 
1335  flutter::DlPaint paint;
1336  paint.setColor(flutter::DlColor::kRed());
1337  paint.setColorFilter(green_color_filter);
1338  paint.setImageFilter(blue_image_filter);
1339  builder.DrawRect(SkRect::MakeLTRB(100, 100, 500, 500), paint);
1340  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1341 }

◆ TEST_P() [179/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawImage   
)

Definition at line 110 of file dl_unittests.cc.

110  {
111  auto texture = CreateTextureForFixture("embarcadero.jpg");
112  flutter::DisplayListBuilder builder;
113  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
114  flutter::DlImageSampling::kNearestNeighbor, nullptr);
115  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
116 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [180/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImage   
)

Definition at line 727 of file dl_unittests.cc.

727  {
728  // Image is drawn with corners to scale and center pieces stretched to fit.
729  auto texture = CreateTextureForFixture("embarcadero.jpg");
730  flutter::DisplayListBuilder builder;
731  auto size = texture->GetSize();
732  builder.DrawImageNine(
733  DlImageImpeller::Make(texture),
734  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
735  size.height * 3 / 4),
736  SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
737  flutter::DlFilterMode::kNearest, nullptr);
738  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
739 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [181/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterBiggerThanDest   
)

Definition at line 773 of file dl_unittests.cc.

773  {
774  // Edge case, the width and height of the corners does not leave any
775  // room for the center slices. Only the corners are displayed.
776  auto texture = CreateTextureForFixture("embarcadero.jpg");
777  flutter::DisplayListBuilder builder;
778  auto size = texture->GetSize();
779  builder.DrawImageNine(
780  DlImageImpeller::Make(texture),
781  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
782  size.height * 3 / 4),
783  SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
784  flutter::DlFilterMode::kNearest, nullptr);
785  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
786 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [182/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterHeightBiggerThanDest   
)

Definition at line 757 of file dl_unittests.cc.

757  {
758  // Edge case, the height of the corners does not leave any room for the
759  // center slice. The center (across the horizontal axis) is folded out of the
760  // resulting image.
761  auto texture = CreateTextureForFixture("embarcadero.jpg");
762  flutter::DisplayListBuilder builder;
763  auto size = texture->GetSize();
764  builder.DrawImageNine(
765  DlImageImpeller::Make(texture),
766  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
767  size.height * 3 / 4),
768  SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
769  flutter::DlFilterMode::kNearest, nullptr);
770  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
771 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [183/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCenterWidthBiggerThanDest   
)

Definition at line 741 of file dl_unittests.cc.

741  {
742  // Edge case, the width of the corners does not leave any room for the
743  // center slice. The center (across the vertical axis) is folded out of the
744  // resulting image.
745  auto texture = CreateTextureForFixture("embarcadero.jpg");
746  flutter::DisplayListBuilder builder;
747  auto size = texture->GetSize();
748  builder.DrawImageNine(
749  DlImageImpeller::Make(texture),
750  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
751  size.height * 3 / 4),
752  SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
753  flutter::DlFilterMode::kNearest, nullptr);
754  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
755 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [184/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawNinePatchImageCornersScaledDown   
)

Definition at line 788 of file dl_unittests.cc.

788  {
789  // Edge case, there is not enough room for the corners to be drawn
790  // without scaling them down.
791  auto texture = CreateTextureForFixture("embarcadero.jpg");
792  flutter::DisplayListBuilder builder;
793  auto size = texture->GetSize();
794  builder.DrawImageNine(
795  DlImageImpeller::Make(texture),
796  SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
797  size.height * 3 / 4),
798  SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
799  flutter::DlFilterMode::kNearest, nullptr);
800  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
801 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [185/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPaintWithColorSource   
)

Definition at line 1211 of file dl_unittests.cc.

1211  {
1212  const flutter::DlColor colors[2] = {
1213  flutter::DlColor(0xFFF44336),
1214  flutter::DlColor(0xFF2196F3),
1215  };
1216  const float stops[2] = {0.0, 1.0};
1217  flutter::DlPaint paint;
1218  flutter::DisplayListBuilder builder;
1219  auto clip_bounds = SkRect::MakeWH(300.0, 300.0);
1220  builder.Save();
1221  builder.Translate(100, 100);
1222  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1223  auto linear =
1224  flutter::DlColorSource::MakeLinear({0.0, 0.0}, {100.0, 100.0}, 2, colors,
1225  stops, flutter::DlTileMode::kRepeat);
1226  paint.setColorSource(linear);
1227  builder.DrawPaint(paint);
1228  builder.Restore();
1229 
1230  builder.Save();
1231  builder.Translate(500, 100);
1232  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1233  auto radial = flutter::DlColorSource::MakeRadial(
1234  {100.0, 100.0}, 100.0, 2, colors, stops, flutter::DlTileMode::kRepeat);
1235  paint.setColorSource(radial);
1236  builder.DrawPaint(paint);
1237  builder.Restore();
1238 
1239  builder.Save();
1240  builder.Translate(100, 500);
1241  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1242  auto sweep =
1243  flutter::DlColorSource::MakeSweep({100.0, 100.0}, 180.0, 270.0, 2, colors,
1244  stops, flutter::DlTileMode::kRepeat);
1245  paint.setColorSource(sweep);
1246  builder.DrawPaint(paint);
1247  builder.Restore();
1248 
1249  builder.Save();
1250  builder.Translate(500, 500);
1251  builder.ClipRect(clip_bounds, flutter::DlCanvas::ClipOp::kIntersect, false);
1252  auto texture = CreateTextureForFixture("table_mountain_nx.png");
1253  auto image = std::make_shared<flutter::DlImageColorSource>(
1254  DlImageImpeller::Make(texture), flutter::DlTileMode::kRepeat,
1255  flutter::DlTileMode::kRepeat);
1256  paint.setColorSource(image);
1257  builder.DrawPaint(paint);
1258  builder.Restore();
1259 
1260  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1261 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [186/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawPoints   
)

Definition at line 803 of file dl_unittests.cc.

803  {
804  flutter::DisplayListBuilder builder;
805  SkPoint points[7] = {
806  {0, 0}, //
807  {100, 100}, //
808  {100, 0}, //
809  {0, 100}, //
810  {0, 0}, //
811  {48, 48}, //
812  {52, 52}, //
813  };
814  std::vector<flutter::DlStrokeCap> caps = {
815  flutter::DlStrokeCap::kButt,
816  flutter::DlStrokeCap::kRound,
817  flutter::DlStrokeCap::kSquare,
818  };
819  flutter::DlPaint paint =
820  flutter::DlPaint() //
821  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
822  .setStrokeWidth(20);
823  builder.Translate(50, 50);
824  for (auto cap : caps) {
825  paint.setStrokeCap(cap);
826  builder.Save();
827  builder.DrawPoints(flutter::DlCanvas::PointMode::kPoints, 7, points, paint);
828  builder.Translate(150, 0);
829  builder.DrawPoints(flutter::DlCanvas::PointMode::kLines, 5, points, paint);
830  builder.Translate(150, 0);
831  builder.DrawPoints(flutter::DlCanvas::PointMode::kPolygon, 5, points,
832  paint);
833  builder.Restore();
834  builder.Translate(0, 150);
835  }
836  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
837 }

◆ TEST_P() [187/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRect   
)

Definition at line 61 of file dl_unittests.cc.

61  {
62  flutter::DisplayListBuilder builder;
63  builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
64  flutter::DlPaint(flutter::DlColor::kBlue()));
65  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
66 }

◆ TEST_P() [188/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawRectWithLinearToSrgbColorFilter   
)

Definition at line 1195 of file dl_unittests.cc.

1195  {
1196  flutter::DlPaint paint;
1197  paint.setColor(flutter::DlColor(0xFF2196F3).withAlpha(128));
1198  flutter::DisplayListBuilder builder;
1199  paint.setColorFilter(
1200  flutter::DlLinearToSrgbGammaColorFilter::kInstance.get());
1201  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1202  builder.Translate(0, 200);
1203 
1204  paint.setColorFilter(
1205  flutter::DlSrgbToLinearGammaColorFilter::kInstance.get());
1206  builder.DrawRect(SkRect::MakeXYWH(0, 0, 200, 200), paint);
1207 
1208  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1209 }

◆ TEST_P() [189/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawShadow   
)

Definition at line 862 of file dl_unittests.cc.

862  {
863  flutter::DisplayListBuilder builder;
864  flutter::DlPaint paint;
865 
866  auto content_scale = GetContentScale() * 0.8;
867  builder.Scale(content_scale.x, content_scale.y);
868 
869  constexpr size_t star_spikes = 5;
870  constexpr SkScalar half_spike_rotation = kPi / star_spikes;
871  constexpr SkScalar radius = 40;
872  constexpr SkScalar spike_size = 10;
873  constexpr SkScalar outer_radius = radius + spike_size;
874  constexpr SkScalar inner_radius = radius - spike_size;
875  std::array<SkPoint, star_spikes * 2> star;
876  for (size_t i = 0; i < star_spikes; i++) {
877  const SkScalar rotation = half_spike_rotation * i * 2;
878  star[i * 2] = SkPoint::Make(50 + std::sin(rotation) * outer_radius,
879  50 - std::cos(rotation) * outer_radius);
880  star[i * 2 + 1] = SkPoint::Make(
881  50 + std::sin(rotation + half_spike_rotation) * inner_radius,
882  50 - std::cos(rotation + half_spike_rotation) * inner_radius);
883  }
884 
885  std::array<SkPath, 4> paths = {
886  SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
887  SkPath{}.addRRect(
888  SkRRect::MakeRectXY(SkRect::MakeXYWH(20, 0, 200, 100), 30, 30)),
889  SkPath{}.addCircle(100, 50, 50),
890  SkPath{}.addPoly(star.data(), star.size(), true),
891  };
892  paint.setColor(flutter::DlColor::kWhite());
893  builder.DrawPaint(paint);
894  paint.setColor(flutter::DlColor::kCyan());
895  builder.Translate(100, 50);
896  for (size_t x = 0; x < paths.size(); x++) {
897  builder.Save();
898  for (size_t y = 0; y < 6; y++) {
899  builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
900  1);
901  builder.DrawPath(paths[x], paint);
902  builder.Translate(0, 150);
903  }
904  builder.Restore();
905  builder.Translate(250, 0);
906  }
907 
908  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
909 }

References impeller::kPi.

◆ TEST_P() [190/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawStrokedText   
)

Definition at line 477 of file dl_unittests.cc.

477  {
478  flutter::DisplayListBuilder builder;
479  flutter::DlPaint paint;
480 
481  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
482  paint.setColor(flutter::DlColor::kRed());
483  builder.DrawTextBlob(
484  SkTextBlob::MakeFromString("stoked about stroked text", CreateTestFont()),
485  250, 250, paint);
486 
487  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
488 }

◆ TEST_P() [191/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlob   
)

Definition at line 68 of file dl_unittests.cc.

68  {
69  flutter::DisplayListBuilder builder;
70  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
71  100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
72  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
73 }

◆ TEST_P() [192/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextBlobWithGradient   
)

Definition at line 75 of file dl_unittests.cc.

75  {
76  flutter::DisplayListBuilder builder;
77 
78  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
79  flutter::DlColor::kRed()};
80  const float stops[2] = {0.0, 1.0};
81 
82  auto linear = flutter::DlColorSource::MakeLinear({0.0, 0.0}, {300.0, 300.0},
83  2, colors.data(), stops,
84  flutter::DlTileMode::kClamp);
85  flutter::DlPaint paint;
86  paint.setColorSource(linear);
87 
88  builder.DrawTextBlob(
89  SkTextBlob::MakeFromString("Hello World", CreateTestFont()), 100, 100,
90  paint);
91  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
92 }

◆ TEST_P() [193/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawTextWithSaveLayer   
)

Definition at line 94 of file dl_unittests.cc.

94  {
95  flutter::DisplayListBuilder builder;
96  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
97  100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
98 
99  flutter::DlPaint save_paint;
100  float alpha = 0.5;
101  save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
102  builder.SaveLayer(nullptr, &save_paint);
103  builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
104  CreateTestFontOfSize(100)),
105  100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
106  builder.Restore();
107  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
108 }

◆ TEST_P() [194/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithBlendColorFilter   
)

Definition at line 529 of file dl_unittests.cc.

529  {
530  auto texture = CreateTextureForFixture("embarcadero.jpg");
531  flutter::DisplayListBuilder builder;
532  flutter::DlPaint paint;
533 
534  // Pipeline blended image.
535  {
536  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kYellow(),
537  flutter::DlBlendMode::kModulate);
538  paint.setColorFilter(&filter);
539  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
540  flutter::DlImageSampling::kNearestNeighbor, &paint);
541  }
542 
543  // Advanced blended image.
544  {
545  auto filter = flutter::DlBlendColorFilter(flutter::DlColor::kRed(),
546  flutter::DlBlendMode::kScreen);
547  paint.setColorFilter(&filter);
548  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
549  flutter::DlImageSampling::kNearestNeighbor, &paint);
550  }
551 
552  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
553 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [195/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithColorFilterImageFilter   
)

Definition at line 555 of file dl_unittests.cc.

555  {
556  const float invert_color_matrix[20] = {
557  -1, 0, 0, 0, 1, //
558  0, -1, 0, 0, 1, //
559  0, 0, -1, 0, 1, //
560  0, 0, 0, 1, 0, //
561  };
562  auto texture = CreateTextureForFixture("boston.jpg");
563  flutter::DisplayListBuilder builder;
564  flutter::DlPaint paint;
565 
566  auto color_filter =
567  std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
568  auto image_filter =
569  std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
570 
571  paint.setImageFilter(image_filter.get());
572  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
573  flutter::DlImageSampling::kNearestNeighbor, &paint);
574 
575  builder.Translate(0, 700);
576  paint.setColorFilter(color_filter.get());
577  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
578  flutter::DlImageSampling::kNearestNeighbor, &paint);
579  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
580 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [196/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithComposeImageFilter   
)

Definition at line 607 of file dl_unittests.cc.

607  {
608  auto texture = CreateTextureForFixture("boston.jpg");
609  flutter::DisplayListBuilder builder;
610  flutter::DlPaint paint;
611 
612  auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
613  auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
614  auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
615  auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
616 
617  paint.setImageFilter(open.get());
618  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
619  flutter::DlImageSampling::kNearestNeighbor, &paint);
620  builder.Translate(0, 700);
621  paint.setImageFilter(close.get());
622  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
623  flutter::DlImageSampling::kNearestNeighbor, &paint);
624  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
625 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [197/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithImageBlurFilter   
)

Definition at line 582 of file dl_unittests.cc.

582  {
583  auto texture = CreateTextureForFixture("embarcadero.jpg");
584 
585  auto callback = [&]() {
586  static float sigma[] = {10, 10};
587 
588  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
589  ImGui::SliderFloat2("Sigma", sigma, 0, 100);
590  ImGui::End();
591 
592  flutter::DisplayListBuilder builder;
593  flutter::DlPaint paint;
594 
595  auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
596  flutter::DlTileMode::kClamp);
597  paint.setImageFilter(&filter);
598  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
599  flutter::DlImageSampling::kNearestNeighbor, &paint);
600 
601  return builder.Build();
602  };
603 
604  ASSERT_TRUE(OpenPlaygroundHere(callback));
605 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [198/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMaskBlur   
)

Definition at line 441 of file dl_unittests.cc.

441  {
442  auto texture = CreateTextureForFixture("embarcadero.jpg");
443  flutter::DisplayListBuilder builder;
444  flutter::DlPaint paint;
445 
446  // Mask blurred image.
447  {
448  auto filter =
449  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
450  paint.setMaskFilter(&filter);
451  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
452  flutter::DlImageSampling::kNearestNeighbor, &paint);
453  }
454 
455  // Mask blurred filled path.
456  {
457  paint.setColor(flutter::DlColor::kYellow());
458  auto filter =
459  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kOuter, 10.0f);
460  paint.setMaskFilter(&filter);
461  builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
462  }
463 
464  // Mask blurred text.
465  {
466  auto filter =
467  flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kSolid, 10.0f);
468  paint.setMaskFilter(&filter);
469  builder.DrawTextBlob(
470  SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
471  paint);
472  }
473 
474  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
475 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [199/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilter   
)

Definition at line 1035 of file dl_unittests.cc.

1035  {
1036  auto boston = CreateTextureForFixture("boston.jpg");
1037 
1038  auto callback = [&]() {
1039  static int selected_matrix_type = 0;
1040  const char* matrix_type_names[] = {"Matrix", "Local Matrix"};
1041 
1042  static float ctm_translation[2] = {200, 200};
1043  static float ctm_scale[2] = {0.65, 0.65};
1044  static float ctm_skew[2] = {0, 0};
1045 
1046  static bool enable = true;
1047  static float translation[2] = {100, 100};
1048  static float scale[2] = {0.8, 0.8};
1049  static float skew[2] = {0.2, 0.2};
1050 
1051  static bool enable_savelayer = true;
1052 
1053  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1054  {
1055  ImGui::Combo("Filter type", &selected_matrix_type, matrix_type_names,
1056  sizeof(matrix_type_names) / sizeof(char*));
1057 
1058  ImGui::TextWrapped("Current Transform");
1059  ImGui::SliderFloat2("CTM Translation", ctm_translation, 0, 1000);
1060  ImGui::SliderFloat2("CTM Scale", ctm_scale, 0, 3);
1061  ImGui::SliderFloat2("CTM Skew", ctm_skew, -3, 3);
1062 
1063  ImGui::TextWrapped(
1064  "MatrixFilter and LocalMatrixFilter modify the CTM in the same way. "
1065  "The only difference is that MatrixFilter doesn't affect the effect "
1066  "transform, whereas LocalMatrixFilter does.");
1067  // Note: See this behavior in:
1068  // https://fiddle.skia.org/c/6cbb551ab36d06f163db8693972be954
1069  ImGui::Checkbox("Enable", &enable);
1070  ImGui::SliderFloat2("Filter Translation", translation, 0, 1000);
1071  ImGui::SliderFloat2("Filter Scale", scale, 0, 3);
1072  ImGui::SliderFloat2("Filter Skew", skew, -3, 3);
1073 
1074  ImGui::TextWrapped(
1075  "Rendering the filtered image within a layer can expose bounds "
1076  "issues. If the rendered image gets cut off when this setting is "
1077  "enabled, there's a coverage bug in the filter.");
1078  ImGui::Checkbox("Render in layer", &enable_savelayer);
1079  }
1080  ImGui::End();
1081 
1082  flutter::DisplayListBuilder builder;
1083  flutter::DlPaint paint;
1084 
1085  if (enable_savelayer) {
1086  builder.SaveLayer(nullptr, nullptr);
1087  }
1088  {
1089  auto content_scale = GetContentScale();
1090  builder.Scale(content_scale.x, content_scale.y);
1091 
1092  // Set the current transform
1093  auto ctm_matrix =
1094  SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
1095  ctm_skew[1], ctm_scale[1], ctm_translation[1], //
1096  0, 0, 1);
1097  builder.Transform(ctm_matrix);
1098 
1099  // Set the matrix filter
1100  auto filter_matrix =
1101  SkMatrix::MakeAll(scale[0], skew[0], translation[0], //
1102  skew[1], scale[1], translation[1], //
1103  0, 0, 1);
1104 
1105  if (enable) {
1106  switch (selected_matrix_type) {
1107  case 0: {
1108  auto filter = flutter::DlMatrixImageFilter(
1109  filter_matrix, flutter::DlImageSampling::kLinear);
1110  paint.setImageFilter(&filter);
1111  break;
1112  }
1113  case 1: {
1114  auto internal_filter =
1115  flutter::DlBlurImageFilter(10, 10, flutter::DlTileMode::kDecal)
1116  .shared();
1117  auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
1118  internal_filter);
1119  paint.setImageFilter(&filter);
1120  break;
1121  }
1122  }
1123  }
1124 
1125  builder.DrawImage(DlImageImpeller::Make(boston), {},
1126  flutter::DlImageSampling::kLinear, &paint);
1127  }
1128  if (enable_savelayer) {
1129  builder.Restore();
1130  }
1131 
1132  return builder.Build();
1133  };
1134 
1135  ASSERT_TRUE(OpenPlaygroundHere(callback));
1136 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [200/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithMatrixFilterWhenSavingLayer   
)

Definition at line 1138 of file dl_unittests.cc.

1138  {
1139  auto callback = [&]() {
1140  static float translation[2] = {0, 0};
1141  static bool enable_save_layer = true;
1142 
1143  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1144  ImGui::SliderFloat2("Translation", translation, -130, 130);
1145  ImGui::Checkbox("Enable save layer", &enable_save_layer);
1146  ImGui::End();
1147 
1148  flutter::DisplayListBuilder builder;
1149  builder.Save();
1150  builder.Scale(2.0, 2.0);
1151  flutter::DlPaint paint;
1152  paint.setColor(flutter::DlColor::kYellow());
1153  builder.DrawRect(SkRect::MakeWH(300, 300), paint);
1154  paint.setStrokeWidth(1.0);
1155  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1156  paint.setColor(flutter::DlColor::kBlack().withAlpha(0x80));
1157  builder.DrawLine(SkPoint::Make(150, 0), SkPoint::Make(150, 300), paint);
1158  builder.DrawLine(SkPoint::Make(0, 150), SkPoint::Make(300, 150), paint);
1159 
1160  flutter::DlPaint save_paint;
1161  SkRect bounds = SkRect::MakeXYWH(100, 100, 100, 100);
1162  SkMatrix translate_matrix =
1163  SkMatrix::Translate(translation[0], translation[1]);
1164  if (enable_save_layer) {
1165  auto filter = flutter::DlMatrixImageFilter(
1166  translate_matrix, flutter::DlImageSampling::kNearestNeighbor);
1167  save_paint.setImageFilter(filter.shared());
1168  builder.SaveLayer(&bounds, &save_paint);
1169  } else {
1170  builder.Save();
1171  builder.Transform(translate_matrix);
1172  }
1173 
1174  SkMatrix filter_matrix = SkMatrix::I();
1175  filter_matrix.postTranslate(-150, -150);
1176  filter_matrix.postScale(0.2f, 0.2f);
1177  filter_matrix.postTranslate(150, 150);
1178  auto filter = flutter::DlMatrixImageFilter(
1179  filter_matrix, flutter::DlImageSampling::kNearestNeighbor);
1180 
1181  save_paint.setImageFilter(filter.shared());
1182 
1183  builder.SaveLayer(&bounds, &save_paint);
1184  flutter::DlPaint paint2;
1185  paint2.setColor(flutter::DlColor::kBlue());
1186  builder.DrawRect(bounds, paint2);
1187  builder.Restore();
1188  builder.Restore();
1189  return builder.Build();
1190  };
1191 
1192  ASSERT_TRUE(OpenPlaygroundHere(callback));
1193 }

◆ TEST_P() [201/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawWithOddPathWinding   
)

Definition at line 397 of file dl_unittests.cc.

397  {
398  flutter::DisplayListBuilder builder;
399  flutter::DlPaint paint;
400 
401  paint.setColor(flutter::DlColor::kRed());
402  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
403 
404  builder.Translate(300, 300);
405  SkPath path;
406  path.setFillType(SkPathFillType::kEvenOdd);
407  path.addCircle(0, 0, 100);
408  path.addCircle(0, 0, 50);
409  builder.DrawPath(path, paint);
410 
411  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
412 }

◆ TEST_P() [202/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroLengthLine   
)

Definition at line 839 of file dl_unittests.cc.

839  {
840  flutter::DisplayListBuilder builder;
841  std::vector<flutter::DlStrokeCap> caps = {
842  flutter::DlStrokeCap::kButt,
843  flutter::DlStrokeCap::kRound,
844  flutter::DlStrokeCap::kSquare,
845  };
846  flutter::DlPaint paint =
847  flutter::DlPaint() //
848  .setColor(flutter::DlColor::kYellow().withAlpha(127)) //
849  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
850  .setStrokeCap(flutter::DlStrokeCap::kButt) //
851  .setStrokeWidth(20);
852  SkPath path = SkPath().addPoly({{150, 50}, {150, 50}}, false);
853  for (auto cap : caps) {
854  paint.setStrokeCap(cap);
855  builder.DrawLine({50, 50}, {50, 50}, paint);
856  builder.DrawPath(path, paint);
857  builder.Translate(0, 150);
858  }
859  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
860 }

◆ TEST_P() [203/317]

impeller::testing::TEST_P ( DisplayListTest  ,
CanDrawZeroWidthLine   
)

Definition at line 1001 of file dl_unittests.cc.

1001  {
1002  flutter::DisplayListBuilder builder;
1003  std::vector<flutter::DlStrokeCap> caps = {
1004  flutter::DlStrokeCap::kButt,
1005  flutter::DlStrokeCap::kRound,
1006  flutter::DlStrokeCap::kSquare,
1007  };
1008  flutter::DlPaint paint = //
1009  flutter::DlPaint() //
1010  .setColor(flutter::DlColor::kWhite()) //
1011  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1012  .setStrokeWidth(0);
1013  flutter::DlPaint outline_paint = //
1014  flutter::DlPaint() //
1015  .setColor(flutter::DlColor::kYellow()) //
1016  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1017  .setStrokeCap(flutter::DlStrokeCap::kSquare) //
1018  .setStrokeWidth(1);
1019  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1020  for (auto cap : caps) {
1021  paint.setStrokeCap(cap);
1022  builder.DrawLine({50, 50}, {60, 50}, paint);
1023  builder.DrawRect({45, 45, 65, 55}, outline_paint);
1024  builder.DrawLine({100, 50}, {100, 50}, paint);
1025  if (cap != flutter::DlStrokeCap::kButt) {
1026  builder.DrawRect({95, 45, 105, 55}, outline_paint);
1027  }
1028  builder.DrawPath(path, paint);
1029  builder.DrawRect(path.getBounds().makeOutset(5, 5), outline_paint);
1030  builder.Translate(0, 150);
1031  }
1032  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1033 }

◆ TEST_P() [204/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DispatcherDoesNotCullPerspectiveTransformedChildDisplayLists   
)

Definition at line 911 of file dl_unittests.cc.

912  {
913  // Regression test for https://github.com/flutter/flutter/issues/130613
914  flutter::DisplayListBuilder sub_builder(true);
915  sub_builder.DrawRect(SkRect::MakeXYWH(0, 0, 50, 50),
916  flutter::DlPaint(flutter::DlColor::kRed()));
917  auto display_list = sub_builder.Build();
918 
919  DlDispatcher dispatcher(Rect::MakeLTRB(0, 0, 2400, 1800));
920  dispatcher.scale(2.0, 2.0);
921  dispatcher.translate(-93.0, 0.0);
922  // clang-format off
923  dispatcher.transformFullPerspective(
924  0.8, -0.2, -0.1, -0.0,
925  0.0, 1.0, 0.0, 0.0,
926  1.4, 1.3, 1.0, 0.0,
927  63.2, 65.3, 48.6, 1.1
928  );
929  // clang-format on
930  dispatcher.translate(35.0, 75.0);
931  dispatcher.drawDisplayList(display_list, 1.0f);
932  auto picture = dispatcher.EndRecordingAsPicture();
933 
934  bool found = false;
935  picture.pass->IterateAllEntities([&found](Entity& entity) {
936  if (std::static_pointer_cast<SolidColorContents>(entity.GetContents())
937  ->GetColor() == Color::Red()) {
938  found = true;
939  return false;
940  }
941 
942  return true;
943  });
944  EXPECT_TRUE(found);
945 }

References impeller::DlDispatcher::drawDisplayList(), impeller::DlDispatcher::EndRecordingAsPicture(), impeller::Entity::GetContents(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Picture::pass, impeller::Color::Red(), impeller::DlDispatcher::scale(), impeller::DlDispatcher::transformFullPerspective(), and impeller::DlDispatcher::translate().

◆ TEST_P() [205/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawPictureWithAClip   
)

Definition at line 48 of file dl_unittests.cc.

48  {
49  flutter::DisplayListBuilder sub_builder;
50  sub_builder.ClipRect(SkRect::MakeXYWH(0, 0, 24, 24));
51  sub_builder.DrawPaint(flutter::DlPaint(flutter::DlColor::kBlue()));
52 
53  auto display_list = sub_builder.Build();
54  flutter::DisplayListBuilder builder;
55  builder.DrawDisplayList(display_list);
56  builder.DrawRect(SkRect::MakeXYWH(30, 30, 24, 24),
57  flutter::DlPaint(flutter::DlColor::kRed()));
58  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
59 }

◆ TEST_P() [206/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawShapes   
)

Definition at line 1555 of file dl_unittests.cc.

1555  {
1556  flutter::DisplayListBuilder builder;
1557  std::vector<flutter::DlStrokeJoin> joins = {
1558  flutter::DlStrokeJoin::kBevel,
1559  flutter::DlStrokeJoin::kRound,
1560  flutter::DlStrokeJoin::kMiter,
1561  };
1562  flutter::DlPaint paint = //
1563  flutter::DlPaint() //
1564  .setColor(flutter::DlColor::kWhite()) //
1565  .setDrawStyle(flutter::DlDrawStyle::kFill) //
1566  .setStrokeWidth(10);
1567  flutter::DlPaint stroke_paint = //
1568  flutter::DlPaint() //
1569  .setColor(flutter::DlColor::kWhite()) //
1570  .setDrawStyle(flutter::DlDrawStyle::kStroke) //
1571  .setStrokeWidth(10);
1572  SkPath path = SkPath().addPoly({{150, 50}, {160, 50}}, false);
1573 
1574  builder.Translate(300, 50);
1575  builder.Scale(0.8, 0.8);
1576  for (auto join : joins) {
1577  paint.setStrokeJoin(join);
1578  stroke_paint.setStrokeJoin(join);
1579  builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint);
1580  builder.DrawRect(SkRect::MakeXYWH(0, 150, 100, 100), stroke_paint);
1581  builder.DrawRRect(
1582  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 0, 100, 100), 30, 30), paint);
1583  builder.DrawRRect(
1584  SkRRect::MakeRectXY(SkRect::MakeXYWH(150, 150, 100, 100), 30, 30),
1585  stroke_paint);
1586  builder.DrawCircle({350, 50}, 50, paint);
1587  builder.DrawCircle({350, 200}, 50, stroke_paint);
1588  builder.Translate(0, 300);
1589  }
1590  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1591 }

◆ TEST_P() [207/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesBlendModes   
)

Definition at line 1593 of file dl_unittests.cc.

1593  {
1594  std::vector<const char*> blend_mode_names;
1595  std::vector<flutter::DlBlendMode> blend_mode_values;
1596  {
1597  const std::vector<std::tuple<const char*, flutter::DlBlendMode>> blends = {
1598  // Pipeline blends (Porter-Duff alpha compositing)
1599  {"Clear", flutter::DlBlendMode::kClear},
1600  {"Source", flutter::DlBlendMode::kSrc},
1601  {"Destination", flutter::DlBlendMode::kDst},
1602  {"SourceOver", flutter::DlBlendMode::kSrcOver},
1603  {"DestinationOver", flutter::DlBlendMode::kDstOver},
1604  {"SourceIn", flutter::DlBlendMode::kSrcIn},
1605  {"DestinationIn", flutter::DlBlendMode::kDstIn},
1606  {"SourceOut", flutter::DlBlendMode::kSrcOut},
1607  {"DestinationOut", flutter::DlBlendMode::kDstOut},
1608  {"SourceATop", flutter::DlBlendMode::kSrcATop},
1609  {"DestinationATop", flutter::DlBlendMode::kDstATop},
1610  {"Xor", flutter::DlBlendMode::kXor},
1611  {"Plus", flutter::DlBlendMode::kPlus},
1612  {"Modulate", flutter::DlBlendMode::kModulate},
1613  // Advanced blends (color component blends)
1614  {"Screen", flutter::DlBlendMode::kScreen},
1615  {"Overlay", flutter::DlBlendMode::kOverlay},
1616  {"Darken", flutter::DlBlendMode::kDarken},
1617  {"Lighten", flutter::DlBlendMode::kLighten},
1618  {"ColorDodge", flutter::DlBlendMode::kColorDodge},
1619  {"ColorBurn", flutter::DlBlendMode::kColorBurn},
1620  {"HardLight", flutter::DlBlendMode::kHardLight},
1621  {"SoftLight", flutter::DlBlendMode::kSoftLight},
1622  {"Difference", flutter::DlBlendMode::kDifference},
1623  {"Exclusion", flutter::DlBlendMode::kExclusion},
1624  {"Multiply", flutter::DlBlendMode::kMultiply},
1625  {"Hue", flutter::DlBlendMode::kHue},
1626  {"Saturation", flutter::DlBlendMode::kSaturation},
1627  {"Color", flutter::DlBlendMode::kColor},
1628  {"Luminosity", flutter::DlBlendMode::kLuminosity},
1629  };
1630  assert(blends.size() ==
1631  static_cast<size_t>(flutter::DlBlendMode::kLastMode) + 1);
1632  for (const auto& [name, mode] : blends) {
1633  blend_mode_names.push_back(name);
1634  blend_mode_values.push_back(mode);
1635  }
1636  }
1637 
1638  auto callback = [&]() {
1639  static int current_blend_index = 3;
1640  static float dst_alpha = 1;
1641  static float src_alpha = 1;
1642  static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f};
1643  static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f};
1644  static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f};
1645  static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
1646 
1647  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1648  {
1649  ImGui::ListBox("Blending mode", &current_blend_index,
1650  blend_mode_names.data(), blend_mode_names.size());
1651  ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1);
1652  ImGui::ColorEdit4("Color A", color0);
1653  ImGui::ColorEdit4("Color B", color1);
1654  ImGui::ColorEdit4("Color C", color2);
1655  ImGui::ColorEdit4("Source Color", src_color);
1656  ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1);
1657  }
1658  ImGui::End();
1659 
1660  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1661  SkPoint::Make(200, 100),
1662  SkPoint::Make(300, 300)};
1663  std::vector<flutter::DlColor> colors = {
1664  toColor(color0).modulateOpacity(dst_alpha),
1665  toColor(color1).modulateOpacity(dst_alpha),
1666  toColor(color2).modulateOpacity(dst_alpha)};
1667 
1668  auto vertices = flutter::DlVertices::Make(
1669  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1670  /*texture_coorindates=*/nullptr, colors.data());
1671 
1672  flutter::DisplayListBuilder builder;
1673  flutter::DlPaint paint;
1674 
1675  paint.setColor(toColor(src_color).modulateOpacity(src_alpha));
1676  builder.DrawVertices(vertices, blend_mode_values[current_blend_index],
1677  paint);
1678  return builder.Build();
1679  };
1680 
1681  ASSERT_TRUE(OpenPlaygroundHere(callback));
1682 }

References impeller::kColor, and toColor().

◆ TEST_P() [208/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinates   
)

Definition at line 1459 of file dl_unittests.cc.

1459  {
1460  auto texture = CreateTextureForFixture("embarcadero.jpg");
1461  auto dl_image = DlImageImpeller::Make(texture);
1462  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1463  SkPoint::Make(200, 100),
1464  SkPoint::Make(300, 300)};
1465  std::vector<SkPoint> texture_coordinates = {
1466  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1467 
1468  auto vertices = flutter::DlVertices::Make(
1469  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1470  texture_coordinates.data(), /*colors=*/nullptr);
1471 
1472  flutter::DisplayListBuilder builder;
1473  flutter::DlPaint paint;
1474 
1475  auto image_source = flutter::DlImageColorSource(
1476  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1477 
1478  paint.setColorSource(&image_source);
1479  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1480 
1481  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1482 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [209/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesImageSourceWithTextureCoordinatesAndColorBlending   
)

Definition at line 1484 of file dl_unittests.cc.

1485  {
1486  auto texture = CreateTextureForFixture("embarcadero.jpg");
1487  auto dl_image = DlImageImpeller::Make(texture);
1488  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1489  SkPoint::Make(200, 100),
1490  SkPoint::Make(300, 300)};
1491  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1492  flutter::DlColor::kGreen(),
1493  flutter::DlColor::kWhite()};
1494  std::vector<SkPoint> texture_coordinates = {
1495  SkPoint::Make(0, 0), SkPoint::Make(100, 200), SkPoint::Make(200, 100)};
1496 
1497  auto vertices = flutter::DlVertices::Make(
1498  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1499  texture_coordinates.data(), colors.data());
1500 
1501  flutter::DisplayListBuilder builder;
1502  flutter::DlPaint paint;
1503 
1504  auto image_source = flutter::DlImageColorSource(
1505  dl_image, flutter::DlTileMode::kRepeat, flutter::DlTileMode::kRepeat);
1506 
1507  paint.setColorSource(&image_source);
1508  builder.DrawVertices(vertices, flutter::DlBlendMode::kModulate, paint);
1509 
1510  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1511 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [210/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithoutIndices   
)

Definition at line 1404 of file dl_unittests.cc.

1404  {
1405  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1406  SkPoint::Make(200, 100),
1407  SkPoint::Make(300, 300)};
1408 
1409  auto vertices = flutter::DlVertices::Make(
1410  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1411  /*texture_coorindates=*/nullptr, /*colors=*/nullptr);
1412 
1413  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1414  flutter::DlColor::kRed()};
1415  const float stops[2] = {0.0, 1.0};
1416 
1417  auto linear = flutter::DlColorSource::MakeLinear(
1418  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1419  flutter::DlTileMode::kRepeat);
1420 
1421  flutter::DisplayListBuilder builder;
1422  flutter::DlPaint paint;
1423 
1424  paint.setColorSource(linear);
1425  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1426 
1427  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1428 }

◆ TEST_P() [211/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesLinearGradientWithTextureCoordinates   
)

Definition at line 1430 of file dl_unittests.cc.

1430  {
1431  std::vector<SkPoint> positions = {SkPoint::Make(100, 300),
1432  SkPoint::Make(200, 100),
1433  SkPoint::Make(300, 300)};
1434  std::vector<SkPoint> texture_coordinates = {SkPoint::Make(300, 100),
1435  SkPoint::Make(100, 200),
1436  SkPoint::Make(300, 300)};
1437 
1438  auto vertices = flutter::DlVertices::Make(
1439  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1440  texture_coordinates.data(), /*colors=*/nullptr);
1441 
1442  std::vector<flutter::DlColor> colors = {flutter::DlColor::kBlue(),
1443  flutter::DlColor::kRed()};
1444  const float stops[2] = {0.0, 1.0};
1445 
1446  auto linear = flutter::DlColorSource::MakeLinear(
1447  {100.0, 100.0}, {300.0, 300.0}, 2, colors.data(), stops,
1448  flutter::DlTileMode::kRepeat);
1449 
1450  flutter::DisplayListBuilder builder;
1451  flutter::DlPaint paint;
1452 
1453  paint.setColorSource(linear);
1454  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1455 
1456  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1457 }

◆ TEST_P() [212/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesPremultipliesColors   
)

Definition at line 1532 of file dl_unittests.cc.

1532  {
1533  std::vector<SkPoint> positions = {
1534  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1535  SkPoint::Make(200, 500)};
1536  auto color = flutter::DlColor::kBlue().withAlpha(0x99);
1537  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1538  std::vector<flutter::DlColor> colors = {color, color, color, color};
1539 
1540  auto vertices = flutter::DlVertices::Make(
1541  flutter::DlVertexMode::kTriangles, 6, positions.data(),
1542  /*texture_coorindates=*/nullptr, colors.data(), 6, indices.data());
1543 
1544  flutter::DisplayListBuilder builder;
1545  flutter::DlPaint paint;
1546  paint.setBlendMode(flutter::DlBlendMode::kSrcOver);
1547  paint.setColor(flutter::DlColor::kRed());
1548 
1549  builder.DrawRect(SkRect::MakeLTRB(0, 0, 400, 400), paint);
1550  builder.DrawVertices(vertices, flutter::DlBlendMode::kDst, paint);
1551 
1552  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1553 }

◆ TEST_P() [213/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithIndices   
)

Definition at line 1513 of file dl_unittests.cc.

1513  {
1514  std::vector<SkPoint> positions = {
1515  SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300),
1516  SkPoint::Make(200, 500)};
1517  std::vector<uint16_t> indices = {0, 1, 2, 0, 2, 3};
1518 
1519  auto vertices = flutter::DlVertices::Make(
1520  flutter::DlVertexMode::kTriangles, 6, positions.data(),
1521  /*texture_coorindates=*/nullptr, /*colors=*/nullptr, 6, indices.data());
1522 
1523  flutter::DisplayListBuilder builder;
1524  flutter::DlPaint paint;
1525 
1526  paint.setColor(flutter::DlColor::kWhite());
1527  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1528 
1529  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1530 }

◆ TEST_P() [214/317]

impeller::testing::TEST_P ( DisplayListTest  ,
DrawVerticesSolidColorTrianglesWithoutIndices   
)

Definition at line 1380 of file dl_unittests.cc.

1380  {
1381  // Use negative coordinates and then scale the transform by -1, -1 to make
1382  // sure coverage is taking the transform into account.
1383  std::vector<SkPoint> positions = {SkPoint::Make(-100, -300),
1384  SkPoint::Make(-200, -100),
1385  SkPoint::Make(-300, -300)};
1386  std::vector<flutter::DlColor> colors = {flutter::DlColor::kWhite(),
1387  flutter::DlColor::kGreen(),
1388  flutter::DlColor::kWhite()};
1389 
1390  auto vertices = flutter::DlVertices::Make(
1391  flutter::DlVertexMode::kTriangles, 3, positions.data(),
1392  /*texture_coorindates=*/nullptr, colors.data());
1393 
1394  flutter::DisplayListBuilder builder;
1395  flutter::DlPaint paint;
1396 
1397  paint.setColor(flutter::DlColor::kRed().modulateOpacity(0.5));
1398  builder.Scale(-1, -1);
1399  builder.DrawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint);
1400 
1401  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1402 }

◆ TEST_P() [215/317]

impeller::testing::TEST_P ( DisplayListTest  ,
IgnoreMaskFilterWhenSavingLayer   
)

Definition at line 516 of file dl_unittests.cc.

516  {
517  auto texture = CreateTextureForFixture("embarcadero.jpg");
518  flutter::DisplayListBuilder builder;
519  auto filter = flutter::DlBlurMaskFilter(flutter::DlBlurStyle::kNormal, 10.0f);
520  flutter::DlPaint paint;
521  paint.setMaskFilter(&filter);
522  builder.SaveLayer(nullptr, &paint);
523  builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
524  flutter::DlImageSampling::kNearestNeighbor);
525  builder.Restore();
526  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
527 }

References impeller::DlImageImpeller::Make().

◆ TEST_P() [216/317]

impeller::testing::TEST_P ( DisplayListTest  ,
MaskBlursApplyCorrectlyToColorSources   
)

Definition at line 1343 of file dl_unittests.cc.

1343  {
1344  auto blur_filter = std::make_shared<flutter::DlBlurMaskFilter>(
1345  flutter::DlBlurStyle::kNormal, 10);
1346 
1347  flutter::DisplayListBuilder builder;
1348 
1349  std::array<flutter::DlColor, 2> colors = {flutter::DlColor::kBlue(),
1350  flutter::DlColor::kGreen()};
1351  std::array<float, 2> stops = {0, 1};
1352  std::array<std::shared_ptr<flutter::DlColorSource>, 2> color_sources = {
1353  std::make_shared<flutter::DlColorColorSource>(flutter::DlColor::kWhite()),
1354  flutter::DlColorSource::MakeLinear(
1355  SkPoint::Make(0, 0), SkPoint::Make(100, 50), 2, colors.data(),
1356  stops.data(), flutter::DlTileMode::kClamp)};
1357 
1358  int offset = 100;
1359  for (auto color_source : color_sources) {
1360  flutter::DlPaint paint;
1361  paint.setColorSource(color_source);
1362  paint.setMaskFilter(blur_filter);
1363 
1364  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
1365  builder.DrawRRect(
1366  SkRRect::MakeRectXY(SkRect::MakeXYWH(100, offset, 100, 50), 30, 30),
1367  paint);
1368  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
1369  paint.setStrokeWidth(10);
1370  builder.DrawRRect(
1371  SkRRect::MakeRectXY(SkRect::MakeXYWH(300, offset, 100, 50), 30, 30),
1372  paint);
1373 
1374  offset += 100;
1375  }
1376 
1377  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1378 }

◆ TEST_P() [217/317]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedPathsDrawCorrectly   
)

Definition at line 224 of file dl_unittests.cc.

224  {
225  auto callback = [&]() {
226  flutter::DisplayListBuilder builder;
227  flutter::DlPaint paint;
228 
229  paint.setColor(flutter::DlColor::kRed());
230  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
231 
232  static float stroke_width = 10.0f;
233  static int selected_stroke_type = 0;
234  static int selected_join_type = 0;
235  const char* stroke_types[] = {"Butte", "Round", "Square"};
236  const char* join_type[] = {"kMiter", "Round", "kBevel"};
237 
238  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
239  ImGui::Combo("Cap", &selected_stroke_type, stroke_types,
240  sizeof(stroke_types) / sizeof(char*));
241  ImGui::Combo("Join", &selected_join_type, join_type,
242  sizeof(join_type) / sizeof(char*));
243  ImGui::SliderFloat("Stroke Width", &stroke_width, 10.0f, 50.0f);
244  ImGui::End();
245 
246  flutter::DlStrokeCap cap;
247  flutter::DlStrokeJoin join;
248  switch (selected_stroke_type) {
249  case 0:
250  cap = flutter::DlStrokeCap::kButt;
251  break;
252  case 1:
253  cap = flutter::DlStrokeCap::kRound;
254  break;
255  case 2:
256  cap = flutter::DlStrokeCap::kSquare;
257  break;
258  default:
259  cap = flutter::DlStrokeCap::kButt;
260  break;
261  }
262  switch (selected_join_type) {
263  case 0:
264  join = flutter::DlStrokeJoin::kMiter;
265  break;
266  case 1:
267  join = flutter::DlStrokeJoin::kRound;
268  break;
269  case 2:
270  join = flutter::DlStrokeJoin::kBevel;
271  break;
272  default:
273  join = flutter::DlStrokeJoin::kMiter;
274  break;
275  }
276  paint.setStrokeCap(cap);
277  paint.setStrokeJoin(join);
278  paint.setStrokeWidth(stroke_width);
279 
280  // Make rendering better to watch.
281  builder.Scale(1.5f, 1.5f);
282 
283  // Rectangle
284  builder.Translate(100, 100);
285  builder.DrawRect(SkRect::MakeSize({100, 100}), paint);
286 
287  // Rounded rectangle
288  builder.Translate(150, 0);
289  builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
290  paint);
291 
292  // Double rounded rectangle
293  builder.Translate(150, 0);
294  builder.DrawDRRect(
295  SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
296  SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
297 
298  // Contour with duplicate join points
299  {
300  builder.Translate(150, 0);
301  SkPath path;
302  path.moveTo(0, 0);
303  path.lineTo(0, 0);
304  path.lineTo({100, 0});
305  path.lineTo({100, 0});
306  path.lineTo({100, 100});
307  builder.DrawPath(path, paint);
308  }
309 
310  // Contour with duplicate start and end points
311 
312  // Line.
313  builder.Translate(200, 0);
314  {
315  builder.Save();
316 
317  SkPath line_path;
318  line_path.moveTo(0, 0);
319  line_path.moveTo(0, 0);
320  line_path.lineTo({0, 0});
321  line_path.lineTo({0, 0});
322  line_path.lineTo({50, 50});
323  line_path.lineTo({50, 50});
324  line_path.lineTo({100, 0});
325  line_path.lineTo({100, 0});
326  builder.DrawPath(line_path, paint);
327 
328  builder.Translate(0, 100);
329  builder.DrawPath(line_path, paint);
330 
331  builder.Translate(0, 100);
332  SkPath line_path2;
333  line_path2.moveTo(0, 0);
334  line_path2.lineTo(0, 0);
335  line_path2.lineTo(0, 0);
336  builder.DrawPath(line_path2, paint);
337 
338  builder.Restore();
339  }
340 
341  // Cubic.
342  builder.Translate(150, 0);
343  {
344  builder.Save();
345 
346  SkPath cubic_path;
347  cubic_path.moveTo({0, 0});
348  cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
349  builder.DrawPath(cubic_path, paint);
350 
351  builder.Translate(0, 100);
352  SkPath cubic_path2;
353  cubic_path2.moveTo({0, 0});
354  cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
355  builder.DrawPath(cubic_path2, paint);
356 
357  builder.Translate(0, 100);
358  SkPath cubic_path3;
359  cubic_path3.moveTo({0, 0});
360  cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
361  builder.DrawPath(cubic_path3, paint);
362 
363  builder.Restore();
364  }
365 
366  // Quad.
367  builder.Translate(200, 0);
368  {
369  builder.Save();
370 
371  SkPath quad_path;
372  quad_path.moveTo(0, 0);
373  quad_path.moveTo(0, 0);
374  quad_path.quadTo({100, 40}, {50, 80});
375  builder.DrawPath(quad_path, paint);
376 
377  builder.Translate(0, 150);
378  SkPath quad_path2;
379  quad_path2.moveTo(0, 0);
380  quad_path2.moveTo(0, 0);
381  quad_path2.quadTo({0, 0}, {100, 100});
382  builder.DrawPath(quad_path2, paint);
383 
384  builder.Translate(0, 100);
385  SkPath quad_path3;
386  quad_path3.moveTo(0, 0);
387  quad_path3.quadTo({0, 0}, {0, 0});
388  builder.DrawPath(quad_path3, paint);
389 
390  builder.Restore();
391  }
392  return builder.Build();
393  };
394  ASSERT_TRUE(OpenPlaygroundHere(callback));
395 }

◆ TEST_P() [218/317]

impeller::testing::TEST_P ( DisplayListTest  ,
StrokedTextNotOffsetFromNormalText   
)

Definition at line 491 of file dl_unittests.cc.

491  {
492  flutter::DisplayListBuilder builder;
493  flutter::DlPaint paint;
494  auto const& text_blob = SkTextBlob::MakeFromString("00000", CreateTestFont());
495 
496  // https://api.flutter.dev/flutter/material/Colors/blue-constant.html.
497  auto const& mat_blue = flutter::DlColor(0xFF2196f3);
498 
499  // Draw a blue filled rectangle so the text is easier to see.
500  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
501  paint.setColor(mat_blue);
502  builder.DrawRect(SkRect::MakeXYWH(0, 0, 500, 500), paint);
503 
504  // Draw stacked text, with stroked text on top.
505  paint.setDrawStyle(flutter::DlDrawStyle::kFill);
506  paint.setColor(flutter::DlColor::kWhite());
507  builder.DrawTextBlob(text_blob, 250, 250, paint);
508 
509  paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
510  paint.setColor(flutter::DlColor::kBlack());
511  builder.DrawTextBlob(text_blob, 250, 250, paint);
512 
513  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
514 }

◆ TEST_P() [219/317]

impeller::testing::TEST_P ( DisplayListTest  ,
TransparentShadowProducesCorrectColor   
)

Definition at line 947 of file dl_unittests.cc.

947  {
948  DlDispatcher dispatcher;
949  dispatcher.save();
950  dispatcher.scale(1.618, 1.618);
951  dispatcher.drawShadow(SkPath{}.addRect(SkRect::MakeXYWH(0, 0, 200, 100)),
952  flutter::DlColor::kTransparent(), 15, false, 1);
953  dispatcher.restore();
954  auto picture = dispatcher.EndRecordingAsPicture();
955 
956  std::shared_ptr<SolidRRectBlurContents> rrect_blur;
957  picture.pass->IterateAllEntities([&rrect_blur](Entity& entity) {
958  if (ScalarNearlyEqual(entity.GetTransformation().GetScale().x, 1.618f)) {
959  rrect_blur = std::static_pointer_cast<SolidRRectBlurContents>(
960  entity.GetContents());
961  return false;
962  }
963  return true;
964  });
965 
966  ASSERT_NE(rrect_blur, nullptr);
967  ASSERT_EQ(rrect_blur->GetColor().red, 0);
968  ASSERT_EQ(rrect_blur->GetColor().green, 0);
969  ASSERT_EQ(rrect_blur->GetColor().blue, 0);
970  ASSERT_EQ(rrect_blur->GetColor().alpha, 0);
971 }

References impeller::DlDispatcher::drawShadow(), impeller::DlDispatcher::EndRecordingAsPicture(), impeller::Matrix::GetScale(), impeller::Entity::GetTransformation(), impeller::Picture::pass, impeller::DlDispatcher::restore(), impeller::DlDispatcher::save(), impeller::ScalarNearlyEqual(), impeller::DlDispatcher::scale(), and impeller::Vector3::x.

◆ TEST_P() [220/317]

impeller::testing::TEST_P ( EntityTest  ,
AdvancedBlendCoverageHintIsNotResetByEntityPass   
)

Definition at line 2492 of file entity_unittests.cc.

2492  {
2493  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2494  GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2495  "for advanced blends.";
2496  }
2497 
2498  auto contents = std::make_shared<SolidColorContents>();
2499  contents->SetGeometry(Geometry::MakeRect({100, 100, 100, 100}));
2500  contents->SetColor(Color::Red());
2501 
2502  Entity entity;
2503  entity.SetTransformation(Matrix::MakeScale(Vector3(2, 2, 1)));
2504  entity.SetBlendMode(BlendMode::kColorBurn);
2505  entity.SetContents(contents);
2506 
2507  auto coverage = entity.GetCoverage();
2508  EXPECT_TRUE(coverage.has_value());
2509 
2510  auto pass = std::make_unique<EntityPass>();
2511  auto test_allocator = std::make_shared<TestRenderTargetAllocator>(
2512  GetContext()->GetResourceAllocator());
2513  auto stencil_config = RenderTarget::AttachmentConfig{
2514  .storage_mode = StorageMode::kDevicePrivate,
2515  .load_action = LoadAction::kClear,
2516  .store_action = StoreAction::kDontCare,
2517  .clear_color = Color::BlackTransparent()};
2518  auto rt = RenderTarget::CreateOffscreen(
2519  *GetContext(), *test_allocator, ISize::MakeWH(1000, 1000), "Offscreen",
2520  RenderTarget::kDefaultColorAttachmentConfig, stencil_config);
2521  auto content_context = ContentContext(
2522  GetContext(), TypographerContextSkia::Make(), test_allocator);
2523  pass->AddEntity(entity);
2524 
2525  EXPECT_TRUE(pass->Render(content_context, rt));
2526 
2527  if (test_allocator->GetDescriptors().size() == 6u) {
2528  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2529  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2530 
2531  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(200, 200));
2532  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(200, 200));
2533  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(200, 200));
2534  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2535  } else if (test_allocator->GetDescriptors().size() == 9u) {
2536  // Onscreen render target.
2537  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2538  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2539  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(1000, 1000));
2540  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(1000, 1000));
2541  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(1000, 1000));
2542 
2543  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2544  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2545  EXPECT_EQ(test_allocator->GetDescriptors()[6].size, ISize(200, 200));
2546  EXPECT_EQ(test_allocator->GetDescriptors()[7].size, ISize(200, 200));
2547  } else {
2548  EXPECT_TRUE(false);
2549  }
2550 }

References impeller::Color::BlackTransparent(), impeller::RenderTarget::CreateOffscreen(), impeller::Entity::GetCoverage(), impeller::kClear, impeller::kColorBurn, impeller::RenderTarget::kDefaultColorAttachmentConfig, impeller::kDevicePrivate, impeller::kDontCare, impeller::TypographerContextSkia::Make(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::TSize< int64_t >::MakeWH(), impeller::Color::Red(), impeller::Entity::SetBlendMode(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::RenderTarget::AttachmentConfig::storage_mode.

◆ TEST_P() [221/317]

impeller::testing::TEST_P ( EntityTest  ,
AtlasContentsSubAtlas   
)

Definition at line 1949 of file entity_unittests.cc.

1949  {
1950  auto boston = CreateTextureForFixture("boston.jpg");
1951 
1952  {
1953  auto contents = std::make_shared<AtlasContents>();
1954  contents->SetBlendMode(BlendMode::kSourceOver);
1955  contents->SetTexture(boston);
1956  contents->SetColors({
1957  Color::Red(),
1958  Color::Red(),
1959  Color::Red(),
1960  });
1961  contents->SetTextureCoordinates({
1962  Rect::MakeLTRB(0, 0, 10, 10),
1963  Rect::MakeLTRB(0, 0, 10, 10),
1964  Rect::MakeLTRB(0, 0, 10, 10),
1965  });
1966  contents->SetTransforms({
1967  Matrix::MakeTranslation(Vector2(0, 0)),
1968  Matrix::MakeTranslation(Vector2(100, 100)),
1969  Matrix::MakeTranslation(Vector2(200, 200)),
1970  });
1971 
1972  // Since all colors and sample rects are the same, there should
1973  // only be a single entry in the sub atlas.
1974  auto subatlas = contents->GenerateSubAtlas();
1975  ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
1976  }
1977 
1978  {
1979  auto contents = std::make_shared<AtlasContents>();
1980  contents->SetBlendMode(BlendMode::kSourceOver);
1981  contents->SetTexture(boston);
1982  contents->SetColors({
1983  Color::Red(),
1984  Color::Green(),
1985  Color::Blue(),
1986  });
1987  contents->SetTextureCoordinates({
1988  Rect::MakeLTRB(0, 0, 10, 10),
1989  Rect::MakeLTRB(0, 0, 10, 10),
1990  Rect::MakeLTRB(0, 0, 10, 10),
1991  });
1992  contents->SetTransforms({
1993  Matrix::MakeTranslation(Vector2(0, 0)),
1994  Matrix::MakeTranslation(Vector2(100, 100)),
1995  Matrix::MakeTranslation(Vector2(200, 200)),
1996  });
1997 
1998  // Since all colors are different, there are three entires.
1999  auto subatlas = contents->GenerateSubAtlas();
2000  ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
2001 
2002  // The translations are kept but the sample rects point into
2003  // different parts of the sub atlas.
2004  ASSERT_EQ(subatlas->result_texture_coords[0], Rect::MakeXYWH(0, 0, 10, 10));
2005  ASSERT_EQ(subatlas->result_texture_coords[1],
2006  Rect::MakeXYWH(11, 0, 10, 10));
2007  ASSERT_EQ(subatlas->result_texture_coords[2],
2008  Rect::MakeXYWH(22, 0, 10, 10));
2009  }
2010 }

References impeller::Color::Blue(), impeller::Color::Green(), impeller::kSourceOver, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Color::Red().

◆ TEST_P() [222/317]

impeller::testing::TEST_P ( EntityTest  ,
BezierCircleScaled   
)

Definition at line 930 of file entity_unittests.cc.

930  {
931  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
932  static float scale = 20;
933 
934  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
935  ImGui::SliderFloat("Scale", &scale, 1, 100);
936  ImGui::End();
937 
938  Entity entity;
939  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
940  auto path = PathBuilder{}
941  .MoveTo({97.325, 34.818})
942  .CubicCurveTo({98.50862885295136, 34.81812293973836},
943  {99.46822048142015, 33.85863261475589},
944  {99.46822048142015, 32.67499810206613})
945  .CubicCurveTo({99.46822048142015, 31.491363589376355},
946  {98.50862885295136, 30.53187326439389},
947  {97.32499434685802, 30.531998226542708})
948  .CubicCurveTo({96.14153655073771, 30.532123170035373},
949  {95.18222070648729, 31.491540299350355},
950  {95.18222070648729, 32.67499810206613})
951  .CubicCurveTo({95.18222070648729, 33.85845590478189},
952  {96.14153655073771, 34.81787303409686},
953  {97.32499434685802, 34.81799797758954})
954  .Close()
955  .TakePath();
956  entity.SetTransformation(
957  Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
958  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
959  return entity.Render(context, pass);
960  };
961  ASSERT_TRUE(OpenPlaygroundHere(callback));
962 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [223/317]

impeller::testing::TEST_P ( EntityTest  ,
BlendingModeOptions   
)

Definition at line 803 of file entity_unittests.cc.

803  {
804  std::vector<const char*> blend_mode_names;
805  std::vector<BlendMode> blend_mode_values;
806  {
807  // Force an exhausiveness check with a switch. When adding blend modes,
808  // update this switch with a new name/value to make it selectable in the
809  // test GUI.
810 
811  const BlendMode b{};
812  static_assert(b == BlendMode::kClear); // Ensure the first item in
813  // the switch is the first
814  // item in the enum.
815  static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
816  switch (b) {
817  case BlendMode::kClear:
818  blend_mode_names.push_back("Clear");
819  blend_mode_values.push_back(BlendMode::kClear);
820  case BlendMode::kSource:
821  blend_mode_names.push_back("Source");
822  blend_mode_values.push_back(BlendMode::kSource);
823  case BlendMode::kDestination:
824  blend_mode_names.push_back("Destination");
825  blend_mode_values.push_back(BlendMode::kDestination);
826  case BlendMode::kSourceOver:
827  blend_mode_names.push_back("SourceOver");
828  blend_mode_values.push_back(BlendMode::kSourceOver);
829  case BlendMode::kDestinationOver:
830  blend_mode_names.push_back("DestinationOver");
831  blend_mode_values.push_back(BlendMode::kDestinationOver);
832  case BlendMode::kSourceIn:
833  blend_mode_names.push_back("SourceIn");
834  blend_mode_values.push_back(BlendMode::kSourceIn);
835  case BlendMode::kDestinationIn:
836  blend_mode_names.push_back("DestinationIn");
837  blend_mode_values.push_back(BlendMode::kDestinationIn);
838  case BlendMode::kSourceOut:
839  blend_mode_names.push_back("SourceOut");
840  blend_mode_values.push_back(BlendMode::kSourceOut);
841  case BlendMode::kDestinationOut:
842  blend_mode_names.push_back("DestinationOut");
843  blend_mode_values.push_back(BlendMode::kDestinationOut);
844  case BlendMode::kSourceATop:
845  blend_mode_names.push_back("SourceATop");
846  blend_mode_values.push_back(BlendMode::kSourceATop);
847  case BlendMode::kDestinationATop:
848  blend_mode_names.push_back("DestinationATop");
849  blend_mode_values.push_back(BlendMode::kDestinationATop);
850  case BlendMode::kXor:
851  blend_mode_names.push_back("Xor");
852  blend_mode_values.push_back(BlendMode::kXor);
853  case BlendMode::kPlus:
854  blend_mode_names.push_back("Plus");
855  blend_mode_values.push_back(BlendMode::kPlus);
856  case BlendMode::kModulate:
857  blend_mode_names.push_back("Modulate");
858  blend_mode_values.push_back(BlendMode::kModulate);
859  };
860  }
861 
862  auto callback = [&](ContentContext& context, RenderPass& pass) {
863  auto world_matrix = Matrix::MakeScale(GetContentScale());
864  auto draw_rect = [&context, &pass, &world_matrix](
865  Rect rect, Color color, BlendMode blend_mode) -> bool {
866  using VS = SolidFillPipeline::VertexShader;
867 
868  VertexBufferBuilder<VS::PerVertexData> vtx_builder;
869  {
870  auto r = rect.GetLTRB();
871  vtx_builder.AddVertices({
872  {Point(r[0], r[1])},
873  {Point(r[2], r[1])},
874  {Point(r[2], r[3])},
875  {Point(r[0], r[1])},
876  {Point(r[2], r[3])},
877  {Point(r[0], r[3])},
878  });
879  }
880 
881  Command cmd;
882  DEBUG_COMMAND_INFO(cmd, "Blended Rectangle");
883  auto options = OptionsFromPass(pass);
884  options.blend_mode = blend_mode;
885  options.primitive_type = PrimitiveType::kTriangle;
886  cmd.pipeline = context.GetSolidFillPipeline(options);
887  cmd.BindVertices(
888  vtx_builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
889 
890  VS::FrameInfo frame_info;
891  frame_info.mvp =
892  Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
893  frame_info.color = color.Premultiply();
894  VS::BindFrameInfo(cmd,
895  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
896 
897  return pass.AddCommand(std::move(cmd));
898  };
899 
900  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
901  static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
902  ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
903  ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
904  static int current_blend_index = 3;
905  ImGui::ListBox("Blending mode", &current_blend_index,
906  blend_mode_names.data(), blend_mode_names.size());
907  ImGui::End();
908 
909  BlendMode selected_mode = blend_mode_values[current_blend_index];
910 
911  Point a, b, c, d;
912  std::tie(a, b) = IMPELLER_PLAYGROUND_LINE(
913  Point(400, 100), Point(200, 300), 20, Color::White(), Color::White());
914  std::tie(c, d) = IMPELLER_PLAYGROUND_LINE(
915  Point(470, 190), Point(270, 390), 20, Color::White(), Color::White());
916 
917  bool result = true;
918  result = result && draw_rect(Rect(0, 0, pass.GetRenderTargetSize().width,
919  pass.GetRenderTargetSize().height),
920  Color(), BlendMode::kClear);
921  result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
922  BlendMode::kSourceOver);
923  result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
924  selected_mode);
925  return result;
926  };
927  ASSERT_TRUE(OpenPlaygroundHere(callback));
928 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::ContentContext::GetSolidFillPipeline(), IMPELLER_PLAYGROUND_LINE, impeller::kClear, impeller::kDestination, impeller::kDestinationATop, impeller::kDestinationIn, impeller::kDestinationOut, impeller::kDestinationOver, impeller::Entity::kLastPipelineBlendMode, impeller::kModulate, impeller::kPlus, impeller::kSource, impeller::kSourceATop, impeller::kSourceIn, impeller::kSourceOut, impeller::kSourceOver, impeller::kTriangle, impeller::kXor, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::OptionsFromPass(), impeller::Command::pipeline, impeller::Color::White(), impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

◆ TEST_P() [224/317]

impeller::testing::TEST_P ( EntityTest  ,
BorderMaskBlurCoverageIsCorrect   
)

Definition at line 1312 of file entity_unittests.cc.

1312  {
1313  auto fill = std::make_shared<SolidColorContents>();
1314  fill->SetGeometry(Geometry::MakeFillPath(
1315  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1316  fill->SetColor(Color::CornflowerBlue());
1317  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
1318  FilterInput::Make(fill), Radius{3}, Radius{4});
1319 
1320  {
1321  Entity e;
1322  e.SetTransformation(Matrix());
1323  auto actual = border_mask_blur->GetCoverage(e);
1324  auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
1325  ASSERT_TRUE(actual.has_value());
1326  ASSERT_RECT_NEAR(actual.value(), expected);
1327  }
1328 
1329  {
1330  Entity e;
1331  e.SetTransformation(Matrix::MakeRotationZ(Radians{kPi / 4}));
1332  auto actual = border_mask_blur->GetCoverage(e);
1333  auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
1334  ASSERT_TRUE(actual.has_value());
1335  ASSERT_RECT_NEAR(actual.value(), expected);
1336  }
1337 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::CornflowerBlue(), impeller::kPi, impeller::FilterInput::Make(), impeller::FilterContents::MakeBorderMaskBlur(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeRotationZ(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransformation().

◆ TEST_P() [225/317]

impeller::testing::TEST_P ( EntityTest  ,
CanCreateEntity   
)

Definition at line 70 of file entity_unittests.cc.

70  {
71  Entity entity;
72  ASSERT_TRUE(entity.GetTransformation().IsIdentity());
73 }

References impeller::Entity::GetTransformation(), and impeller::Matrix::IsIdentity().

◆ TEST_P() [226/317]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawCorrectlyWithRotatedTransformation   
)

Definition at line 487 of file entity_unittests.cc.

487  {
488  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
489  const char* input_axis[] = {"X", "Y", "Z"};
490  static int rotation_axis_index = 0;
491  static float rotation = 0;
492  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
493  ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
494  ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
495  sizeof(input_axis) / sizeof(char*));
496  Matrix rotation_matrix;
497  switch (rotation_axis_index) {
498  case 0:
499  rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
500  break;
501  case 1:
502  rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
503  break;
504  case 2:
505  rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
506  break;
507  default:
508  rotation_matrix = Matrix{};
509  break;
510  }
511 
512  if (ImGui::Button("Reset")) {
513  rotation = 0;
514  }
515  ImGui::End();
516  Matrix current_transform =
517  Matrix::MakeScale(GetContentScale())
518  .MakeTranslation(
519  Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
520  pass.GetRenderTargetSize().height / 2.0)));
521  Matrix result_transform = current_transform * rotation_matrix;
522  Path path =
523  PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();
524 
525  Entity entity;
526  entity.SetTransformation(result_transform);
527  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
528  return entity.Render(context, pass);
529  };
530  ASSERT_TRUE(OpenPlaygroundHere(callback));
531 }

References impeller::PathBuilder::AddRect(), impeller::kPi, impeller::SolidColorContents::Make(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [227/317]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRect   
)

Definition at line 225 of file entity_unittests.cc.

225  {
226  auto contents = std::make_shared<SolidColorContents>();
227  contents->SetGeometry(Geometry::MakeRect({100, 100, 100, 100}));
228  contents->SetColor(Color::Red());
229 
230  Entity entity;
231  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
232  entity.SetContents(contents);
233 
234  ASSERT_TRUE(OpenPlaygroundHere(entity));
235 }

References impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [228/317]

impeller::testing::TEST_P ( EntityTest  ,
CanDrawRRect   
)

Definition at line 237 of file entity_unittests.cc.

237  {
238  auto contents = std::make_shared<SolidColorContents>();
239  auto path = PathBuilder{}
240  .SetConvexity(Convexity::kConvex)
241  .AddRoundedRect({100, 100, 100, 100}, 10.0)
242  .TakePath();
243  contents->SetGeometry(Geometry::MakeFillPath(path));
244  contents->SetColor(Color::Red());
245 
246  Entity entity;
247  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
248  entity.SetContents(contents);
249 
250  ASSERT_TRUE(OpenPlaygroundHere(entity));
251 }

References impeller::PathBuilder::AddRoundedRect(), impeller::kConvex, impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::PathBuilder::SetConvexity(), impeller::Entity::SetTransformation(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [229/317]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetStencilCoverageIsCorrect   
)

Definition at line 1648 of file entity_unittests.cc.

1648  {
1649  // Intersection: No stencil coverage, no geometry.
1650  {
1651  auto clip = std::make_shared<ClipContents>();
1652  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1653  auto result = clip->GetStencilCoverage(Entity{}, Rect{});
1654 
1655  ASSERT_FALSE(result.coverage.has_value());
1656  }
1657 
1658  // Intersection: No stencil coverage, with geometry.
1659  {
1660  auto clip = std::make_shared<ClipContents>();
1661  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1662  clip->SetGeometry(Geometry::MakeFillPath(
1663  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1664  auto result = clip->GetStencilCoverage(Entity{}, Rect{});
1665 
1666  ASSERT_FALSE(result.coverage.has_value());
1667  }
1668 
1669  // Intersection: With stencil coverage, no geometry.
1670  {
1671  auto clip = std::make_shared<ClipContents>();
1672  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1673  auto result =
1674  clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1675 
1676  ASSERT_FALSE(result.coverage.has_value());
1677  }
1678 
1679  // Intersection: With stencil coverage, with geometry.
1680  {
1681  auto clip = std::make_shared<ClipContents>();
1682  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1683  clip->SetGeometry(Geometry::MakeFillPath(
1684  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1685  auto result =
1686  clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1687 
1688  ASSERT_TRUE(result.coverage.has_value());
1689  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1690  ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
1691  }
1692 
1693  // Difference: With stencil coverage, with geometry.
1694  {
1695  auto clip = std::make_shared<ClipContents>();
1696  clip->SetClipOperation(Entity::ClipOperation::kDifference);
1697  clip->SetGeometry(Geometry::MakeFillPath(
1698  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1699  auto result =
1700  clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1701 
1702  ASSERT_TRUE(result.coverage.has_value());
1703  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
1704  ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
1705  }
1706 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Contents::StencilCoverage::kAppend, impeller::Entity::kDifference, impeller::Entity::kIntersect, impeller::Geometry::MakeFillPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [230/317]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsShouldRenderIsCorrect   
)

Definition at line 1624 of file entity_unittests.cc.

1624  {
1625  // For clip ops, `ShouldRender` should always return true.
1626 
1627  // Clip.
1628  {
1629  auto clip = std::make_shared<ClipContents>();
1630  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1631  clip->SetGeometry(Geometry::MakeFillPath(
1632  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1633  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1634  ASSERT_TRUE(
1635  clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1636  }
1637 
1638  // Clip restore.
1639  {
1640  auto restore = std::make_shared<ClipRestoreContents>();
1641  ASSERT_TRUE(
1642  restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1643  ASSERT_TRUE(
1644  restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1645  }
1646 }

References impeller::PathBuilder::AddRect(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [231/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2442 of file entity_unittests.cc.

2442  {
2443  Entity entity;
2444  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
2445  auto src_contents = std::make_shared<SolidColorContents>();
2446  src_contents->SetGeometry(
2447  Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2448  src_contents->SetColor(Color::Red());
2449 
2450  auto dst_contents = std::make_shared<SolidColorContents>();
2451  dst_contents->SetGeometry(
2452  Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2453  dst_contents->SetColor(Color::Blue());
2454 
2455  auto contents = ColorFilterContents::MakeBlend(
2456  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2457  FilterInput::Make(src_contents, false)});
2458  entity.SetContents(std::move(contents));
2459  ASSERT_TRUE(OpenPlaygroundHere(entity));
2460 }

References impeller::Color::Blue(), impeller::kSourceOver, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [232/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 2225 of file entity_unittests.cc.

2225  {
2226  auto image = CreateTextureForFixture("boston.jpg");
2227  auto filter = ColorFilterContents::MakeBlend(
2228  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2229 
2230  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2231  Entity entity;
2232  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2233  Matrix::MakeTranslation({500, 300}) *
2234  Matrix::MakeScale(Vector2{0.5, 0.5}));
2235  entity.SetContents(filter);
2236  return entity.Render(context, pass);
2237  };
2238  ASSERT_TRUE(OpenPlaygroundHere(callback));
2239 }

References impeller::kColorBurn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [233/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 2241 of file entity_unittests.cc.

2241  {
2242  auto image = CreateTextureForFixture("boston.jpg");
2243  auto filter = ColorFilterContents::MakeBlend(
2244  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2245 
2246  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2247  Entity entity;
2248  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2249  Matrix::MakeTranslation({500, 300}) *
2250  Matrix::MakeScale(Vector2{0.5, 0.5}));
2251  entity.SetContents(filter);
2252  return entity.Render(context, pass);
2253  };
2254  ASSERT_TRUE(OpenPlaygroundHere(callback));
2255 }

References impeller::kClear, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [234/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 2273 of file entity_unittests.cc.

2273  {
2274  auto image = CreateTextureForFixture("boston.jpg");
2275  auto filter = ColorFilterContents::MakeBlend(
2276  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2277 
2278  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2279  Entity entity;
2280  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2281  Matrix::MakeTranslation({500, 300}) *
2282  Matrix::MakeScale(Vector2{0.5, 0.5}));
2283  entity.SetContents(filter);
2284  return entity.Render(context, pass);
2285  };
2286  ASSERT_TRUE(OpenPlaygroundHere(callback));
2287 }

References impeller::kDestination, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [235/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 2257 of file entity_unittests.cc.

2257  {
2258  auto image = CreateTextureForFixture("boston.jpg");
2259  auto filter = ColorFilterContents::MakeBlend(
2260  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2261 
2262  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2263  Entity entity;
2264  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2265  Matrix::MakeTranslation({500, 300}) *
2266  Matrix::MakeScale(Vector2{0.5, 0.5}));
2267  entity.SetContents(filter);
2268  return entity.Render(context, pass);
2269  };
2270  ASSERT_TRUE(OpenPlaygroundHere(callback));
2271 }

References impeller::kSource, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [236/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 2289 of file entity_unittests.cc.

2289  {
2290  auto image = CreateTextureForFixture("boston.jpg");
2291  auto filter = ColorFilterContents::MakeBlend(
2292  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2293 
2294  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2295  Entity entity;
2296  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2297  Matrix::MakeTranslation({500, 300}) *
2298  Matrix::MakeScale(Vector2{0.5, 0.5}));
2299  entity.SetContents(filter);
2300  return entity.Render(context, pass);
2301  };
2302  ASSERT_TRUE(OpenPlaygroundHere(callback));
2303 }

References impeller::kSourceIn, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [237/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1758 of file entity_unittests.cc.

1758  {
1759  // Set up a simple color background.
1760  auto fill = std::make_shared<SolidColorContents>();
1761  fill->SetGeometry(Geometry::MakeFillPath(
1762  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1763  fill->SetColor(Color::Coral());
1764 
1765  // Set the color matrix filter.
1766  ColorMatrix matrix = {
1767  1, 1, 1, 1, 1, //
1768  1, 1, 1, 1, 1, //
1769  1, 1, 1, 1, 1, //
1770  1, 1, 1, 1, 1, //
1771  };
1772 
1773  auto filter =
1774  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1775 
1776  Entity e;
1777  e.SetTransformation(Matrix());
1778 
1779  // Confirm that the actual filter coverage matches the expected coverage.
1780  auto actual = filter->GetCoverage(e);
1781  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1782 
1783  ASSERT_TRUE(actual.has_value());
1784  ASSERT_RECT_NEAR(actual.value(), expected);
1785 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::Coral(), impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransformation().

◆ TEST_P() [238/317]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1787 of file entity_unittests.cc.

1787  {
1788  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1789  ASSERT_TRUE(bay_bridge);
1790 
1791  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1792  // UI state.
1793  static ColorMatrix color_matrix = {
1794  1, 0, 0, 0, 0, //
1795  0, 3, 0, 0, 0, //
1796  0, 0, 1, 0, 0, //
1797  0, 0, 0, 1, 0, //
1798  };
1799  static float offset[2] = {500, 400};
1800  static float rotation = 0;
1801  static float scale[2] = {0.65, 0.65};
1802  static float skew[2] = {0, 0};
1803 
1804  // Define the ImGui
1805  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1806  {
1807  std::string label = "##1";
1808  for (int i = 0; i < 20; i += 5) {
1809  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1810  &(color_matrix.array[i]), 5, nullptr, nullptr,
1811  "%.2f", 0);
1812  label[2]++;
1813  }
1814 
1815  ImGui::SliderFloat2("Translation", &offset[0], 0,
1816  pass.GetRenderTargetSize().width);
1817  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1818  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1819  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1820  }
1821  ImGui::End();
1822 
1823  // Set the color matrix filter.
1824  auto filter = ColorFilterContents::MakeColorMatrix(
1825  FilterInput::Make(bay_bridge), color_matrix);
1826 
1827  // Define the entity with the color matrix filter.
1828  Entity entity;
1829  entity.SetTransformation(
1830  Matrix::MakeScale(GetContentScale()) *
1831  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1832  Matrix::MakeRotationZ(Radians(rotation)) *
1833  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1834  Matrix::MakeSkew(skew[0], skew[1]) *
1835  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1836  entity.SetContents(filter);
1837  entity.Render(context, pass);
1838 
1839  return true;
1840  };
1841 
1842  ASSERT_TRUE(OpenPlaygroundHere(callback));
1843 }

References impeller::ColorMatrix::array, impeller::kPi, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeColorMatrix(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [239/317]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2329 of file entity_unittests.cc.

2329  {
2330  ConicalGradientContents contents;
2331  contents.SetColors({Color::CornflowerBlue()});
2332  ASSERT_FALSE(contents.IsOpaque());
2333  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2334  ASSERT_FALSE(contents.IsOpaque());
2335 }

References impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::ConicalGradientContents::SetColors(), and impeller::Color::WithAlpha().

◆ TEST_P() [240/317]

impeller::testing::TEST_P ( EntityTest  ,
ContentsGetBoundsForEmptyPathReturnsNullopt   
)

Definition at line 1253 of file entity_unittests.cc.

1253  {
1254  Entity entity;
1255  entity.SetContents(std::make_shared<SolidColorContents>());
1256  ASSERT_FALSE(entity.GetCoverage().has_value());
1257 }

References impeller::Entity::GetCoverage(), and impeller::Entity::SetContents().

◆ TEST_P() [241/317]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2305 of file entity_unittests.cc.

2305  {
2306  auto arrow_head = PathBuilder{}
2307  .MoveTo({50, 120})
2308  .LineTo({120, 190})
2309  .LineTo({190, 120})
2310  .TakePath();
2311  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2312  Join::kRound);
2313 
2314  auto transform = Matrix::MakeTranslation({300, 300}) *
2315  Matrix::MakeRotationZ(Radians(kPiOver2));
2316  EXPECT_LT(transform.e[0][0], 0.f);
2317  auto coverage = geometry->GetCoverage(transform);
2318  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2319 }

References ASSERT_RECT_NEAR, impeller::kPiOver2, impeller::kRound, impeller::LineTo(), impeller::Matrix::MakeRotationZ(), impeller::Geometry::MakeStrokePath(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::PathBuilder::MoveTo().

◆ TEST_P() [242/317]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveAndOverlapTest   
)

Definition at line 533 of file entity_unittests.cc.

533  {
534  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
535  Path path =
536  PathBuilder{}
537  .MoveTo({359.934, 96.6335})
538  .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
539  {354.673, 96.8895})
540  .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
541  {354.367, 96.9075})
542  .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
543  {349.259, 97.2355})
544  .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
545  {348.625, 97.2834})
546  .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
547  {343.789, 97.6722})
548  .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
549  {342.703, 97.7734})
550  .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
551  {338.246, 98.207})
552  .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
553  {336.612, 98.3894})
554  .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
555  {332.623, 98.8476})
556  .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
557  {332.237, 98.8982})
558  .LineTo({332.237, 102.601})
559  .LineTo({321.778, 102.601})
560  .LineTo({321.778, 100.382})
561  .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
562  {321.161, 100.476})
563  .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
564  {315.332, 101.479})
565  .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
566  {315.301, 101.484})
567  .LineTo({310.017, 105.94})
568  .LineTo({309.779, 105.427})
569  .LineTo({314.403, 101.651})
570  .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
571  {314.368, 101.658})
572  .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
573  {308.846, 102.748})
574  .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
575  .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
576  {303.425, 103.936})
577  .LineTo({299.105, 107.578})
578  .LineTo({298.867, 107.065})
579  .LineTo({302.394, 104.185})
580  .LineTo({302.412, 104.171})
581  .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
582  {299.344, 104.921})
583  .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
584  .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
585  {291.462, 106.979})
586  .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
587  {290.471, 107.257})
588  .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
589  {287.449, 108.139})
590  .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
591  {284.536, 109.035})
592  .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
593  {281.952, 109.859})
594  .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
595  {279.633, 110.638})
596  .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
597  {276.803, 111.607})
598  .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
599  {276.672, 111.653})
600  .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
601  {271.721, 113.463})
602  .LineTo({271.717, 113.449})
603  .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
604  {270.963, 113.628})
605  .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
606  {270.748, 113.682})
607  .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
608  {269.839, 113.926})
609  .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
610  {269.681, 113.972})
611  .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
612  {268.756, 114.239})
613  .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
614  {268.367, 114.354})
615  .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
616  {267.752, 114.54})
617  .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
618  {253.564, 119.252})
619  .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
620  {253.538, 119.261})
621  .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
622  {248.189, 121.131})
623  .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
624  .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
625  {245.975, 121.912})
626  .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
627  {244.698, 122.364})
628  .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
629  {242.794, 123.04})
630  .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
631  {240.961, 123.693})
632  .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
633  {240.052, 124.018})
634  .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
635  .LineTo({237.164, 125.003})
636  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
637  {235.81, 125.538})
638  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
639  {234.592, 125.977})
640  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
641  {234.59, 125.977})
642  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
643  {192.381, 141.429})
644  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
645  .LineTo({360, 160})
646  .LineTo({360, 119.256})
647  .LineTo({360, 106.332})
648  .LineTo({360, 96.6307})
649  .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
650  {359.934, 96.6335})
651  .Close()
652  .MoveTo({337.336, 124.143})
653  .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
654  {338.903, 121.511})
655  .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
656  {337.336, 124.143})
657  .Close()
658  .MoveTo({340.082, 121.849})
659  .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
660  {340.046, 122.075})
661  .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
662  {340.023, 122.177})
663  .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
664  {339.952, 122.437})
665  .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
666  {339.918, 122.544})
667  .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
668  {339.75, 122.938})
669  .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
670  {339.74, 122.955})
671  .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
672  {339.501, 123.328})
673  .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
674  {339.41, 123.438})
675  .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
676  {339.145, 123.714})
677  .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
678  {339.025, 123.821})
679  .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
680  {338.539, 124.143})
681  .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
682  {338.58, 123.626})
683  .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
684  .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
685  {338.704, 123.151})
686  .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
687  {338.714, 123.117})
688  .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
689  {338.905, 122.712})
690  .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
691  {338.922, 122.682})
692  .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
693  {339.155, 122.34})
694  .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
695  {339.172, 122.319})
696  .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
697  {339.425, 122.037})
698  .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
699  {339.435, 122.027})
700  .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
701  {340.106, 121.511})
702  .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
703  {340.082, 121.849})
704  .Close()
705  .MoveTo({340.678, 113.245})
706  .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
707  {340.135, 113.775})
708  .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
709  {339.115, 114.151})
710  .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
711  {336.448, 114.516})
712  .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
713  {334.384, 114.513})
714  .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
715  {333.605, 114.424})
716  .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
717  {331.41, 113.883})
718  .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
719  {330.672, 112.813})
720  .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
721  {334.526, 113.833})
722  .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
723  .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
724  {332.76, 110.402})
725  .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
726  {335.228, 113.395})
727  .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
728  {335.661, 109.592})
729  .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
730  {336.07, 113.389})
731  .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
732  {338.563, 110.402})
733  .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
734  {336.753, 113.784})
735  .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
736  {336.796, 113.833})
737  .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
738  {340.65, 112.813})
739  .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
740  {340.678, 113.245})
741  .Close()
742  .MoveTo({346.357, 106.771})
743  .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
744  {347.924, 104.139})
745  .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
746  {346.357, 106.771})
747  .Close()
748  .MoveTo({347.56, 106.771})
749  .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
750  {349.127, 104.139})
751  .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
752  {347.56, 106.771})
753  .Close()
754  .TakePath();
755  Entity entity;
756  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
757  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
758  ASSERT_TRUE(OpenPlaygroundHere(entity));
759 }

References impeller::Close(), impeller::LineTo(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [243/317]

impeller::testing::TEST_P ( EntityTest  ,
CubicCurveTest   
)

Definition at line 465 of file entity_unittests.cc.

465  {
466  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
467  Path path =
468  PathBuilder{}
469  .MoveTo({237.164, 125.003})
470  .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
471  {235.81, 125.538})
472  .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
473  {234.592, 125.977})
474  .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
475  {234.59, 125.977})
476  .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
477  {192.381, 141.429})
478  .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
479  .Close()
480  .TakePath();
481  Entity entity;
482  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
483  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
484  ASSERT_TRUE(OpenPlaygroundHere(entity));
485 }

References impeller::Close(), impeller::SolidColorContents::Make(), impeller::Matrix::MakeScale(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [244/317]

impeller::testing::TEST_P ( EntityTest  ,
DoesNotCullEntitiesByDefault   
)

Definition at line 1610 of file entity_unittests.cc.

1610  {
1611  auto fill = std::make_shared<SolidColorContents>();
1612  fill->SetColor(Color::CornflowerBlue());
1613  fill->SetGeometry(
1614  Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));
1615 
1616  Entity entity;
1617  entity.SetContents(fill);
1618 
1619  // Even though the entity is offscreen, this should still render because we do
1620  // not compute the coverage intersection by default.
1621  EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
1622 }

References impeller::Color::CornflowerBlue(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Entity::SetContents(), and impeller::Entity::ShouldRender().

◆ TEST_P() [245/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasNoColor   
)

Definition at line 1339 of file entity_unittests.cc.

1339  {
1340  // Draws the image as four squares stiched together.
1341  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1342  auto size = atlas->GetSize();
1343  // Divide image into four quadrants.
1344  Scalar half_width = size.width / 2;
1345  Scalar half_height = size.height / 2;
1346  std::vector<Rect> texture_coordinates = {
1347  Rect::MakeLTRB(0, 0, half_width, half_height),
1348  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1349  Rect::MakeLTRB(0, half_height, half_width, size.height),
1350  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1351  // Position quadrants adjacent to eachother.
1352  std::vector<Matrix> transforms = {
1353  Matrix::MakeTranslation({0, 0, 0}),
1354  Matrix::MakeTranslation({half_width, 0, 0}),
1355  Matrix::MakeTranslation({0, half_height, 0}),
1356  Matrix::MakeTranslation({half_width, half_height, 0})};
1357  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1358 
1359  contents->SetTransforms(std::move(transforms));
1360  contents->SetTextureCoordinates(std::move(texture_coordinates));
1361  contents->SetTexture(atlas);
1362  contents->SetBlendMode(BlendMode::kSource);
1363 
1364  Entity e;
1365  e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1366  e.SetContents(contents);
1367 
1368  ASSERT_TRUE(OpenPlaygroundHere(e));
1369 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [246/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasNoColorFullSize   
)

Definition at line 1515 of file entity_unittests.cc.

1515  {
1516  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1517  auto size = atlas->GetSize();
1518  std::vector<Rect> texture_coordinates = {
1519  Rect::MakeLTRB(0, 0, size.width, size.height)};
1520  std::vector<Matrix> transforms = {Matrix::MakeTranslation({0, 0, 0})};
1521  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1522 
1523  contents->SetTransforms(std::move(transforms));
1524  contents->SetTextureCoordinates(std::move(texture_coordinates));
1525  contents->SetTexture(atlas);
1526  contents->SetBlendMode(BlendMode::kSource);
1527 
1528  Entity e;
1529  e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1530  e.SetContents(contents);
1531 
1532  ASSERT_TRUE(OpenPlaygroundHere(e));
1533 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [247/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasUsesProvidedCullRectForCoverage   
)

Definition at line 1442 of file entity_unittests.cc.

1442  {
1443  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1444  auto size = atlas->GetSize();
1445 
1446  Scalar half_width = size.width / 2;
1447  Scalar half_height = size.height / 2;
1448  std::vector<Rect> texture_coordinates = {
1449  Rect::MakeLTRB(0, 0, half_width, half_height),
1450  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1451  Rect::MakeLTRB(0, half_height, half_width, size.height),
1452  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1453  std::vector<Matrix> transforms = {
1454  Matrix::MakeTranslation({0, 0, 0}),
1455  Matrix::MakeTranslation({half_width, 0, 0}),
1456  Matrix::MakeTranslation({0, half_height, 0}),
1457  Matrix::MakeTranslation({half_width, half_height, 0})};
1458 
1459  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1460 
1461  contents->SetTransforms(std::move(transforms));
1462  contents->SetTextureCoordinates(std::move(texture_coordinates));
1463  contents->SetTexture(atlas);
1464  contents->SetBlendMode(BlendMode::kSource);
1465 
1466  auto transform = Matrix::MakeScale(GetContentScale());
1467  Entity e;
1468  e.SetTransformation(transform);
1469  e.SetContents(contents);
1470 
1471  ASSERT_EQ(contents->GetCoverage(e).value(),
1472  Rect::MakeSize(size).TransformBounds(transform));
1473 
1474  contents->SetCullRect(Rect::MakeLTRB(0, 0, 10, 10));
1475 
1476  ASSERT_EQ(contents->GetCoverage(e).value(),
1477  Rect::MakeLTRB(0, 0, 10, 10).TransformBounds(transform));
1478 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::TRect< T >::TransformBounds().

◆ TEST_P() [248/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithColorAdvanced   
)

Definition at line 1371 of file entity_unittests.cc.

1371  {
1372  // Draws the image as four squares stiched together.
1373  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1374  auto size = atlas->GetSize();
1375  // Divide image into four quadrants.
1376  Scalar half_width = size.width / 2;
1377  Scalar half_height = size.height / 2;
1378  std::vector<Rect> texture_coordinates = {
1379  Rect::MakeLTRB(0, 0, half_width, half_height),
1380  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1381  Rect::MakeLTRB(0, half_height, half_width, size.height),
1382  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1383  // Position quadrants adjacent to eachother.
1384  std::vector<Matrix> transforms = {
1385  Matrix::MakeTranslation({0, 0, 0}),
1386  Matrix::MakeTranslation({half_width, 0, 0}),
1387  Matrix::MakeTranslation({0, half_height, 0}),
1388  Matrix::MakeTranslation({half_width, half_height, 0})};
1389  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1390  Color::Yellow()};
1391  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1392 
1393  contents->SetTransforms(std::move(transforms));
1394  contents->SetTextureCoordinates(std::move(texture_coordinates));
1395  contents->SetTexture(atlas);
1396  contents->SetColors(colors);
1397  contents->SetBlendMode(BlendMode::kModulate);
1398 
1399  Entity e;
1400  e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1401  e.SetContents(contents);
1402 
1403  ASSERT_TRUE(OpenPlaygroundHere(e));
1404 }

References impeller::Color::Blue(), impeller::Color::Green(), impeller::kModulate, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::Color::Yellow().

◆ TEST_P() [249/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithColorSimple   
)

Definition at line 1406 of file entity_unittests.cc.

1406  {
1407  // Draws the image as four squares stiched together. Because blend modes
1408  // aren't implented this ends up as four solid color blocks.
1409  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1410  auto size = atlas->GetSize();
1411  // Divide image into four quadrants.
1412  Scalar half_width = size.width / 2;
1413  Scalar half_height = size.height / 2;
1414  std::vector<Rect> texture_coordinates = {
1415  Rect::MakeLTRB(0, 0, half_width, half_height),
1416  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1417  Rect::MakeLTRB(0, half_height, half_width, size.height),
1418  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1419  // Position quadrants adjacent to eachother.
1420  std::vector<Matrix> transforms = {
1421  Matrix::MakeTranslation({0, 0, 0}),
1422  Matrix::MakeTranslation({half_width, 0, 0}),
1423  Matrix::MakeTranslation({0, half_height, 0}),
1424  Matrix::MakeTranslation({half_width, half_height, 0})};
1425  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
1426  Color::Yellow()};
1427  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1428 
1429  contents->SetTransforms(std::move(transforms));
1430  contents->SetTextureCoordinates(std::move(texture_coordinates));
1431  contents->SetTexture(atlas);
1432  contents->SetColors(colors);
1433  contents->SetBlendMode(BlendMode::kSourceATop);
1434 
1435  Entity e;
1436  e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1437  e.SetContents(contents);
1438 
1439  ASSERT_TRUE(OpenPlaygroundHere(e));
1440 }

References impeller::Color::Blue(), impeller::Color::Green(), impeller::kSourceATop, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Color::Red(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::Color::Yellow().

◆ TEST_P() [250/317]

impeller::testing::TEST_P ( EntityTest  ,
DrawAtlasWithOpacity   
)

Definition at line 1480 of file entity_unittests.cc.

1480  {
1481  // Draws the image as four squares stiched together slightly
1482  // opaque
1483  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
1484  auto size = atlas->GetSize();
1485  // Divide image into four quadrants.
1486  Scalar half_width = size.width / 2;
1487  Scalar half_height = size.height / 2;
1488  std::vector<Rect> texture_coordinates = {
1489  Rect::MakeLTRB(0, 0, half_width, half_height),
1490  Rect::MakeLTRB(half_width, 0, size.width, half_height),
1491  Rect::MakeLTRB(0, half_height, half_width, size.height),
1492  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
1493  // Position quadrants adjacent to eachother.
1494  std::vector<Matrix> transforms = {
1495  Matrix::MakeTranslation({0, 0, 0}),
1496  Matrix::MakeTranslation({half_width, 0, 0}),
1497  Matrix::MakeTranslation({0, half_height, 0}),
1498  Matrix::MakeTranslation({half_width, half_height, 0})};
1499 
1500  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();
1501 
1502  contents->SetTransforms(std::move(transforms));
1503  contents->SetTextureCoordinates(std::move(texture_coordinates));
1504  contents->SetTexture(atlas);
1505  contents->SetBlendMode(BlendMode::kSource);
1506  contents->SetAlpha(0.5);
1507 
1508  Entity e;
1509  e.SetTransformation(Matrix::MakeScale(GetContentScale()));
1510  e.SetContents(contents);
1511 
1512  ASSERT_TRUE(OpenPlaygroundHere(e));
1513 }

References impeller::kSource, impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [251/317]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCanMergeSubpassIntoParent   
)

Definition at line 149 of file entity_unittests.cc.

149  {
150  // Both a red and a blue box should appear if the pass merging has worked
151  // correctly.
152 
153  EntityPass pass;
154  auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
155  Rect::MakeLTRB(50, 50, 150, 150), true);
156  pass.AddSubpass(std::move(subpass));
157 
158  Entity entity;
159  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
160  auto contents = std::make_unique<SolidColorContents>();
161  contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
162  contents->SetColor(Color::Blue());
163  entity.SetContents(std::move(contents));
164 
165  pass.AddEntity(entity);
166 
167  ASSERT_TRUE(OpenPlaygroundHere(pass));
168 }

References impeller::EntityPass::AddEntity(), impeller::EntityPass::AddSubpass(), impeller::Color::Blue(), CreatePassWithRectPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), impeller::Matrix::MakeScale(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [252/317]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassCoverageRespectsCoverageLimit   
)

Definition at line 170 of file entity_unittests.cc.

170  {
171  // Rect is drawn entirely in negative area.
172  auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
173  std::nullopt);
174 
175  // Without coverage limit.
176  {
177  auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
178  ASSERT_TRUE(pass_coverage.has_value());
179  ASSERT_RECT_NEAR(pass_coverage.value(),
180  Rect::MakeLTRB(-200, -200, -100, -100));
181  }
182 
183  // With limit that doesn't overlap.
184  {
185  auto pass_coverage =
186  pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
187  ASSERT_FALSE(pass_coverage.has_value());
188  }
189 
190  // With limit that partially overlaps.
191  {
192  auto pass_coverage =
193  pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
194  ASSERT_TRUE(pass_coverage.has_value());
195  ASSERT_RECT_NEAR(pass_coverage.value(),
196  Rect::MakeLTRB(-150, -150, -100, -100));
197  }
198 }

References ASSERT_RECT_NEAR, CreatePassWithRectPath(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [253/317]

impeller::testing::TEST_P ( EntityTest  ,
EntityPassRespectsSubpassBoundsLimit   
)

Definition at line 122 of file entity_unittests.cc.

122  {
123  EntityPass pass;
124 
125  auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
126  Rect::MakeLTRB(50, 50, 150, 150));
127  auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
128  Rect::MakeLTRB(800, 800, 900, 900));
129 
130  auto subpass0_coverage =
131  pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
132  ASSERT_TRUE(subpass0_coverage.has_value());
133  ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));
134 
135  auto subpass1_coverage =
136  pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
137  ASSERT_TRUE(subpass1_coverage.has_value());
138  ASSERT_RECT_NEAR(subpass1_coverage.value(),
139  Rect::MakeLTRB(800, 800, 900, 900));
140 
141  pass.AddSubpass(std::move(subpass0));
142  pass.AddSubpass(std::move(subpass1));
143 
144  auto coverage = pass.GetElementsCoverage(std::nullopt);
145  ASSERT_TRUE(coverage.has_value());
146  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
147 }

References impeller::EntityPass::AddSubpass(), ASSERT_RECT_NEAR, CreatePassWithRectPath(), impeller::EntityPass::GetElementsCoverage(), impeller::EntityPass::GetSubpassCoverage(), and impeller::TRect< Scalar >::MakeLTRB().

◆ TEST_P() [254/317]

impeller::testing::TEST_P ( EntityTest  ,
FilterCoverageRespectsCropRect   
)

Definition at line 200 of file entity_unittests.cc.

200  {
201  auto image = CreateTextureForFixture("boston.jpg");
202  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
203  FilterInput::Make({image}));
204 
205  // Without the crop rect (default behavior).
206  {
207  auto actual = filter->GetCoverage({});
208  auto expected = Rect::MakeSize(image->GetSize());
209 
210  ASSERT_TRUE(actual.has_value());
211  ASSERT_RECT_NEAR(actual.value(), expected);
212  }
213 
214  // With the crop rect.
215  {
216  auto expected = Rect::MakeLTRB(50, 50, 100, 100);
217  filter->SetCoverageHint(expected);
218  auto actual = filter->GetCoverage({});
219 
220  ASSERT_TRUE(actual.has_value());
221  ASSERT_RECT_NEAR(actual.value(), expected);
222  }
223 }

References ASSERT_RECT_NEAR, impeller::kSoftLight, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [255/317]

impeller::testing::TEST_P ( EntityTest  ,
Filters   
)

Definition at line 964 of file entity_unittests.cc.

964  {
965  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
966  auto boston = CreateTextureForFixture("boston.jpg");
967  auto kalimba = CreateTextureForFixture("kalimba.jpg");
968  ASSERT_TRUE(bridge && boston && kalimba);
969 
970  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
971  auto fi_bridge = FilterInput::Make(bridge);
972  auto fi_boston = FilterInput::Make(boston);
973  auto fi_kalimba = FilterInput::Make(kalimba);
974 
975  std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
976  BlendMode::kModulate, {fi_kalimba, fi_boston});
977 
978  auto blend1 = ColorFilterContents::MakeBlend(
979  BlendMode::kScreen,
980  {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});
981 
982  Entity entity;
983  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
984  Matrix::MakeTranslation({500, 300}) *
985  Matrix::MakeScale(Vector2{0.5, 0.5}));
986  entity.SetContents(blend1);
987  return entity.Render(context, pass);
988  };
989  ASSERT_TRUE(OpenPlaygroundHere(callback));
990 }

References impeller::kModulate, impeller::kScreen, impeller::FilterInput::Make(), impeller::ColorFilterContents::MakeBlend(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), and impeller::Entity::SetTransformation().

◆ TEST_P() [256/317]

impeller::testing::TEST_P ( EntityTest  ,
GaussianBlurFilter   
)

Definition at line 992 of file entity_unittests.cc.

992  {
993  auto boston = CreateTextureForFixture("boston.jpg");
994  ASSERT_TRUE(boston);
995 
996  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
997  const char* input_type_names[] = {"Texture", "Solid Color"};
998  const char* blur_type_names[] = {"Image blur", "Mask blur"};
999  const char* pass_variation_names[] = {"Two pass", "Directional"};
1000  const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
1001  const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
1002  const FilterContents::BlurStyle blur_styles[] = {
1003  FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
1004  FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
1005  const Entity::TileMode tile_modes[] = {
1006  Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
1007  Entity::TileMode::kMirror, Entity::TileMode::kDecal};
1008 
1009  // UI state.
1010  static int selected_input_type = 0;
1011  static Color input_color = Color::Black();
1012  static int selected_blur_type = 0;
1013  static int selected_pass_variation = 0;
1014  static float blur_amount_coarse[2] = {0, 0};
1015  static float blur_amount_fine[2] = {10, 10};
1016  static int selected_blur_style = 0;
1017  static int selected_tile_mode = 3;
1018  static Color cover_color(1, 0, 0, 0.2);
1019  static Color bounds_color(0, 1, 0, 0.1);
1020  static float offset[2] = {500, 400};
1021  static float rotation = 0;
1022  static float scale[2] = {0.65, 0.65};
1023  static float skew[2] = {0, 0};
1024  static float path_rect[4] = {0, 0,
1025  static_cast<float>(boston->GetSize().width),
1026  static_cast<float>(boston->GetSize().height)};
1027 
1028  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1029  {
1030  ImGui::Combo("Input type", &selected_input_type, input_type_names,
1031  sizeof(input_type_names) / sizeof(char*));
1032  if (selected_input_type == 0) {
1033  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1034  } else {
1035  ImGui::ColorEdit4("Input color",
1036  reinterpret_cast<float*>(&input_color));
1037  }
1038  ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
1039  sizeof(blur_type_names) / sizeof(char*));
1040  if (selected_blur_type == 0) {
1041  ImGui::Combo("Pass variation", &selected_pass_variation,
1042  pass_variation_names,
1043  sizeof(pass_variation_names) / sizeof(char*));
1044  }
1045  ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
1046  ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
1047  ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
1048  sizeof(blur_style_names) / sizeof(char*));
1049  ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
1050  sizeof(tile_mode_names) / sizeof(char*));
1051  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1052  ImGui::ColorEdit4("Bounds color",
1053  reinterpret_cast<float*>(&bounds_color));
1054  ImGui::SliderFloat2("Translation", offset, 0,
1055  pass.GetRenderTargetSize().width);
1056  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1057  ImGui::SliderFloat2("Scale", scale, 0, 3);
1058  ImGui::SliderFloat2("Skew", skew, -3, 3);
1059  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1060  }
1061  ImGui::End();
1062 
1063  auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
1064  auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};
1065 
1066  std::shared_ptr<Contents> input;
1067  Size input_size;
1068 
1069  auto input_rect =
1070  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1071  if (selected_input_type == 0) {
1072  auto texture = std::make_shared<TextureContents>();
1073  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1074  texture->SetDestinationRect(input_rect);
1075  texture->SetTexture(boston);
1076  texture->SetOpacity(input_color.alpha);
1077 
1078  input = texture;
1079  input_size = input_rect.size;
1080  } else {
1081  auto fill = std::make_shared<SolidColorContents>();
1082  fill->SetColor(input_color);
1083  fill->SetGeometry(
1084  Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));
1085 
1086  input = fill;
1087  input_size = input_rect.size;
1088  }
1089 
1090  std::shared_ptr<FilterContents> blur;
1091  if (selected_pass_variation == 0) {
1092  blur = FilterContents::MakeGaussianBlur(
1093  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1094  blur_styles[selected_blur_style], tile_modes[selected_tile_mode]);
1095  } else {
1096  Vector2 blur_vector(blur_sigma_x.sigma, blur_sigma_y.sigma);
1097  blur = FilterContents::MakeDirectionalGaussianBlur(
1098  FilterInput::Make(input), Sigma{blur_vector.GetLength()},
1099  blur_vector.Normalize());
1100  }
1101 
1102  auto mask_blur = FilterContents::MakeBorderMaskBlur(
1103  FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
1104  blur_styles[selected_blur_style]);
1105 
1106  auto ctm = Matrix::MakeScale(GetContentScale()) *
1107  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1108  Matrix::MakeRotationZ(Radians(rotation)) *
1109  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1110  Matrix::MakeSkew(skew[0], skew[1]) *
1111  Matrix::MakeTranslation(-Point(input_size) / 2);
1112 
1113  auto target_contents = selected_blur_type == 0 ? blur : mask_blur;
1114 
1115  Entity entity;
1116  entity.SetContents(target_contents);
1117  entity.SetTransformation(ctm);
1118 
1119  entity.Render(context, pass);
1120 
1121  // Renders a red "cover" rectangle that shows the original position of the
1122  // unfiltered input.
1123  Entity cover_entity;
1124  cover_entity.SetContents(SolidColorContents::Make(
1125  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1126  cover_entity.SetTransformation(ctm);
1127 
1128  cover_entity.Render(context, pass);
1129 
1130  // Renders a green bounding rect of the target filter.
1131  Entity bounds_entity;
1132  bounds_entity.SetContents(SolidColorContents::Make(
1133  PathBuilder{}
1134  .AddRect(target_contents->GetCoverage(entity).value())
1135  .TakePath(),
1136  bounds_color));
1137  bounds_entity.SetTransformation(Matrix());
1138 
1139  bounds_entity.Render(context, pass);
1140 
1141  return true;
1142  };
1143  ASSERT_TRUE(OpenPlaygroundHere(callback));
1144 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::TPoint< T >::GetLength(), impeller::Entity::kClamp, impeller::Entity::kDecal, impeller::FilterContents::kInner, impeller::Entity::kMirror, impeller::FilterContents::kNormal, impeller::FilterContents::kOuter, impeller::kPi, impeller::Entity::kRepeat, impeller::FilterContents::kSolid, impeller::SolidColorContents::Make(), impeller::FilterInput::Make(), impeller::FilterContents::MakeBorderMaskBlur(), impeller::FilterContents::MakeDirectionalGaussianBlur(), impeller::Geometry::MakeFillPath(), impeller::FilterContents::MakeGaussianBlur(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::TPoint< T >::Normalize(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [257/317]

impeller::testing::TEST_P ( EntityTest  ,
GeometryBoundsAreTransformed   
)

Definition at line 253 of file entity_unittests.cc.

253  {
254  auto geometry = Geometry::MakeRect({100, 100, 100, 100});
255  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});
256 
257  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
258  Rect(200, 200, 200, 200));
259 }

References ASSERT_RECT_NEAR, impeller::Geometry::MakeRect(), and impeller::Matrix::MakeScale().

◆ TEST_P() [258/317]

impeller::testing::TEST_P ( EntityTest  ,
InheritOpacityTest   
)

Definition at line 2154 of file entity_unittests.cc.

2154  {
2155  Entity entity;
2156 
2157  // Texture contents can always accept opacity.
2158  auto texture_contents = std::make_shared<TextureContents>();
2159  texture_contents->SetOpacity(0.5);
2160  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2161 
2162  texture_contents->SetInheritedOpacity(0.5);
2163  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2164  texture_contents->SetInheritedOpacity(0.5);
2165  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2166 
2167  // Solid color contents can accept opacity if their geometry
2168  // doesn't overlap.
2169  auto solid_color = std::make_shared<SolidColorContents>();
2170  solid_color->SetGeometry(
2171  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2172  solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2173 
2174  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2175 
2176  solid_color->SetInheritedOpacity(0.5);
2177  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2178  solid_color->SetInheritedOpacity(0.5);
2179  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2180 
2181  // Color source contents can accept opacity if their geometry
2182  // doesn't overlap.
2183  auto tiled_texture = std::make_shared<TiledTextureContents>();
2184  tiled_texture->SetGeometry(
2185  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2186  tiled_texture->SetOpacityFactor(0.5);
2187 
2188  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2189 
2190  tiled_texture->SetInheritedOpacity(0.5);
2191  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2192  tiled_texture->SetInheritedOpacity(0.5);
2193  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2194 
2195  // Text contents can accept opacity if the text frames do not
2196  // overlap
2197  SkFont font;
2198  font.setSize(30);
2199  auto blob = SkTextBlob::MakeFromString("A", font);
2200  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2201  auto lazy_glyph_atlas =
2202  std::make_shared<LazyGlyphAtlas>(TypographerContextSkia::Make());
2203  lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2204 
2205  auto text_contents = std::make_shared<TextContents>();
2206  text_contents->SetTextFrame(frame);
2207  text_contents->SetColor(Color::Blue().WithAlpha(0.5));
2208 
2209  ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2210 
2211  text_contents->SetInheritedOpacity(0.5);
2212  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2213  text_contents->SetInheritedOpacity(0.5);
2214  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2215 
2216  // Clips and restores trivially accept opacity.
2217  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2218  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2219 
2220  // Runtime effect contents can't accept opacity.
2221  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2222  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2223 }

References impeller::Color::Blue(), impeller::TypographerContextSkia::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [259/317]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2337 of file entity_unittests.cc.

2337  {
2338  LinearGradientContents contents;
2339  contents.SetColors({Color::CornflowerBlue()});
2340  ASSERT_TRUE(contents.IsOpaque());
2341  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2342  ASSERT_FALSE(contents.IsOpaque());
2343  contents.SetColors({Color::CornflowerBlue()});
2344  contents.SetTileMode(Entity::TileMode::kDecal);
2345  ASSERT_FALSE(contents.IsOpaque());
2346 }

References impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LinearGradientContents::SetColors(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [260/317]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1866 of file entity_unittests.cc.

1866  {
1867  auto image = CreateTextureForFixture("kalimba.jpg");
1868  ASSERT_TRUE(image);
1869 
1870  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1871  auto filtered =
1872  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1873 
1874  // Define the entity that will serve as the control image as a Gaussian blur
1875  // filter with no filter at all.
1876  Entity entity_left;
1877  entity_left.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1878  Matrix::MakeTranslation({100, 300}) *
1879  Matrix::MakeScale(Vector2{0.5, 0.5}));
1880  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1881  Sigma{0}, Sigma{0});
1882  entity_left.SetContents(unfiltered);
1883 
1884  // Define the entity that will be filtered from linear to sRGB.
1885  Entity entity_right;
1886  entity_right.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1887  Matrix::MakeTranslation({500, 300}) *
1888  Matrix::MakeScale(Vector2{0.5, 0.5}));
1889  entity_right.SetContents(filtered);
1890  return entity_left.Render(context, pass) &&
1891  entity_right.Render(context, pass);
1892  };
1893 
1894  ASSERT_TRUE(OpenPlaygroundHere(callback));
1895 }

References impeller::FilterInput::Make(), impeller::FilterContents::MakeGaussianBlur(), impeller::ColorFilterContents::MakeLinearToSrgbFilter(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [261/317]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1845 of file entity_unittests.cc.

1845  {
1846  // Set up a simple color background.
1847  auto fill = std::make_shared<SolidColorContents>();
1848  fill->SetGeometry(Geometry::MakeFillPath(
1849  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1850  fill->SetColor(Color::MintCream());
1851 
1852  auto filter =
1853  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1854 
1855  Entity e;
1856  e.SetTransformation(Matrix());
1857 
1858  // Confirm that the actual filter coverage matches the expected coverage.
1859  auto actual = filter->GetCoverage(e);
1860  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1861 
1862  ASSERT_TRUE(actual.has_value());
1863  ASSERT_RECT_NEAR(actual.value(), expected);
1864 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::ColorFilterContents::MakeLinearToSrgbFilter(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Color::MintCream(), and impeller::Entity::SetTransformation().

◆ TEST_P() [262/317]

impeller::testing::TEST_P ( EntityTest  ,
MorphologyFilter   
)

Definition at line 1146 of file entity_unittests.cc.

1146  {
1147  auto boston = CreateTextureForFixture("boston.jpg");
1148  ASSERT_TRUE(boston);
1149 
1150  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1151  const char* morphology_type_names[] = {"Dilate", "Erode"};
1152  const FilterContents::MorphType morphology_types[] = {
1153  FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
1154  static Color input_color = Color::Black();
1155  // UI state.
1156  static int selected_morphology_type = 0;
1157  static float radius[2] = {20, 20};
1158  static Color cover_color(1, 0, 0, 0.2);
1159  static Color bounds_color(0, 1, 0, 0.1);
1160  static float offset[2] = {500, 400};
1161  static float rotation = 0;
1162  static float scale[2] = {0.65, 0.65};
1163  static float skew[2] = {0, 0};
1164  static float path_rect[4] = {0, 0,
1165  static_cast<float>(boston->GetSize().width),
1166  static_cast<float>(boston->GetSize().height)};
1167  static float effect_transform_scale = 1;
1168 
1169  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1170  {
1171  ImGui::Combo("Morphology type", &selected_morphology_type,
1172  morphology_type_names,
1173  sizeof(morphology_type_names) / sizeof(char*));
1174  ImGui::SliderFloat2("Radius", radius, 0, 200);
1175  ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
1176  ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
1177  ImGui::ColorEdit4("Bounds color",
1178  reinterpret_cast<float*>(&bounds_color));
1179  ImGui::SliderFloat2("Translation", offset, 0,
1180  pass.GetRenderTargetSize().width);
1181  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1182  ImGui::SliderFloat2("Scale", scale, 0, 3);
1183  ImGui::SliderFloat2("Skew", skew, -3, 3);
1184  ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
1185  ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
1186  3);
1187  }
1188  ImGui::End();
1189 
1190  std::shared_ptr<Contents> input;
1191  Size input_size;
1192 
1193  auto input_rect =
1194  Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
1195  auto texture = std::make_shared<TextureContents>();
1196  texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
1197  texture->SetDestinationRect(input_rect);
1198  texture->SetTexture(boston);
1199  texture->SetOpacity(input_color.alpha);
1200 
1201  input = texture;
1202  input_size = input_rect.size;
1203 
1204  auto contents = FilterContents::MakeMorphology(
1205  FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
1206  morphology_types[selected_morphology_type]);
1207  contents->SetEffectTransform(Matrix::MakeScale(
1208  Vector2{effect_transform_scale, effect_transform_scale}));
1209 
1210  auto ctm = Matrix::MakeScale(GetContentScale()) *
1211  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1212  Matrix::MakeRotationZ(Radians(rotation)) *
1213  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1214  Matrix::MakeSkew(skew[0], skew[1]) *
1215  Matrix::MakeTranslation(-Point(input_size) / 2);
1216 
1217  Entity entity;
1218  entity.SetContents(contents);
1219  entity.SetTransformation(ctm);
1220 
1221  entity.Render(context, pass);
1222 
1223  // Renders a red "cover" rectangle that shows the original position of the
1224  // unfiltered input.
1225  Entity cover_entity;
1226  cover_entity.SetContents(SolidColorContents::Make(
1227  PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
1228  cover_entity.SetTransformation(ctm);
1229 
1230  cover_entity.Render(context, pass);
1231 
1232  // Renders a green bounding rect of the target filter.
1233  Entity bounds_entity;
1234  bounds_entity.SetContents(SolidColorContents::Make(
1235  PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
1236  bounds_color));
1237  bounds_entity.SetTransformation(Matrix());
1238 
1239  bounds_entity.Render(context, pass);
1240 
1241  return true;
1242  };
1243  ASSERT_TRUE(OpenPlaygroundHere(callback));
1244 }

References impeller::PathBuilder::AddRect(), impeller::Color::alpha, impeller::Color::Black(), impeller::FilterContents::kDilate, impeller::FilterContents::kErode, impeller::kPi, impeller::SolidColorContents::Make(), impeller::FilterInput::Make(), impeller::FilterContents::MakeMorphology(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeSkew(), impeller::Matrix::MakeTranslation(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::PathBuilder::TakePath().

◆ TEST_P() [263/317]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2434 of file entity_unittests.cc.

2434  {
2435  std::vector<Point> points = {{10, 20}, {100, 200}};
2436  auto geometry = Geometry::MakePointField(points, 5.0, false);
2437  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2438  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2439  Rect::MakeLTRB(35, 15, 135, 205));
2440 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakePointField(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [264/317]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryDivisions   
)

Definition at line 2416 of file entity_unittests.cc.

2416  {
2417  // Square always gives 4 divisions.
2418  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u);
2419  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u);
2420  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u);
2421 
2422  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u);
2423  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u);
2424  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u);
2425  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u);
2426  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u);
2427  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u);
2428  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u);
2429  // Caps at 140.
2430  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u);
2431  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u);
2432 }

References impeller::PointFieldGeometry::ComputeCircleDivisions().

◆ TEST_P() [265/317]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2348 of file entity_unittests.cc.

2348  {
2349  RadialGradientContents contents;
2350  contents.SetColors({Color::CornflowerBlue()});
2351  ASSERT_TRUE(contents.IsOpaque());
2352  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2353  ASSERT_FALSE(contents.IsOpaque());
2354  contents.SetColors({Color::CornflowerBlue()});
2355  contents.SetTileMode(Entity::TileMode::kDecal);
2356  ASSERT_FALSE(contents.IsOpaque());
2357 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [266/317]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1708 of file entity_unittests.cc.

1708  {
1709  auto callback = [&](ContentContext& context, RenderPass& pass) {
1710  static Color color = Color::Red();
1711  static float corner_radius = 100;
1712  static float blur_radius = 100;
1713  static bool show_coverage = false;
1714  static Color coverage_color = Color::Green().WithAlpha(0.2);
1715 
1716  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1717  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1718  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1719  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1720  ImGui::Checkbox("Show coverage", &show_coverage);
1721  if (show_coverage) {
1722  ImGui::ColorEdit4("Coverage color",
1723  reinterpret_cast<Scalar*>(&coverage_color));
1724  }
1725  ImGui::End();
1726 
1727  auto [top_left, bottom_right] = IMPELLER_PLAYGROUND_LINE(
1728  Point(200, 200), Point(600, 400), 30, Color::White(), Color::White());
1729  auto rect =
1730  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1731 
1732  auto contents = std::make_unique<SolidRRectBlurContents>();
1733  contents->SetRRect(rect, corner_radius);
1734  contents->SetColor(color);
1735  contents->SetSigma(Radius(blur_radius));
1736 
1737  Entity entity;
1738  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
1739  entity.SetContents(std::move(contents));
1740  entity.Render(context, pass);
1741 
1742  auto coverage = entity.GetCoverage();
1743  if (show_coverage && coverage.has_value()) {
1744  auto bounds_contents = std::make_unique<SolidColorContents>();
1745  bounds_contents->SetGeometry(Geometry::MakeFillPath(
1746  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1747  bounds_contents->SetColor(coverage_color.Premultiply());
1748  Entity bounds_entity;
1749  bounds_entity.SetContents(std::move(bounds_contents));
1750  bounds_entity.Render(context, pass);
1751  }
1752 
1753  return true;
1754  };
1755  ASSERT_TRUE(OpenPlaygroundHere(callback));
1756 }

References impeller::PathBuilder::AddRect(), impeller::Entity::GetCoverage(), impeller::Color::Green(), IMPELLER_PLAYGROUND_LINE, impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeScale(), impeller::Color::Premultiply(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), impeller::PathBuilder::TakePath(), impeller::Color::White(), and impeller::Color::WithAlpha().

◆ TEST_P() [267/317]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 2113 of file entity_unittests.cc.

2113  {
2114  if (GetParam() != PlaygroundBackend::kMetal) {
2115  GTEST_SKIP_("This backend doesn't support runtime effects.");
2116  }
2117 
2118  auto runtime_stage =
2119  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2120  ASSERT_TRUE(runtime_stage->IsDirty());
2121 
2122  bool first_frame = true;
2123  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2124  if (first_frame) {
2125  first_frame = false;
2126  } else {
2127  assert(runtime_stage->IsDirty() == false);
2128  }
2129 
2130  auto contents = std::make_shared<RuntimeEffectContents>();
2131  contents->SetGeometry(Geometry::MakeCover());
2132 
2133  contents->SetRuntimeStage(runtime_stage);
2134 
2135  struct FragUniforms {
2136  Vector2 iResolution;
2137  Scalar iTime;
2138  } frag_uniforms = {
2139  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2140  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2141  };
2142  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2143  uniform_data->resize(sizeof(FragUniforms));
2144  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2145  contents->SetUniformData(uniform_data);
2146 
2147  Entity entity;
2148  entity.SetContents(contents);
2149  return contents->Render(context, entity, pass);
2150  };
2151  ASSERT_TRUE(OpenPlaygroundHere(callback));
2152 }

References impeller::kMetal, impeller::Geometry::MakeCover(), and impeller::Entity::SetContents().

◆ TEST_P() [268/317]

impeller::testing::TEST_P ( EntityTest  ,
SetBlendMode   
)

Definition at line 1246 of file entity_unittests.cc.

1246  {
1247  Entity entity;
1248  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
1249  entity.SetBlendMode(BlendMode::kClear);
1250  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
1251 }

References impeller::Entity::GetBlendMode(), impeller::kClear, impeller::kSourceOver, and impeller::Entity::SetBlendMode().

◆ TEST_P() [269/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2321 of file entity_unittests.cc.

2321  {
2322  SolidColorContents contents;
2323  contents.SetColor(Color::CornflowerBlue());
2324  ASSERT_TRUE(contents.IsOpaque());
2325  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2326  ASSERT_FALSE(contents.IsOpaque());
2327 }

References impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), and impeller::SolidColorContents::SetColor().

◆ TEST_P() [270/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetMiterLimit   
)

Definition at line 783 of file entity_unittests.cc.

783  {
784  {
785  auto geometry = Geometry::MakeStrokePath(Path{});
786  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
787  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
788  }
789 
790  {
791  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
792  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
793  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
794  }
795 
796  {
797  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
798  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
799  ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
800  }
801 }

References impeller::Geometry::MakeStrokePath().

◆ TEST_P() [271/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsStrokeSetStrokeCapsAndJoins   
)

Definition at line 761 of file entity_unittests.cc.

761  {
762  {
763  auto geometry = Geometry::MakeStrokePath(Path{});
764  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
765  // Defaults.
766  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
767  ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
768  }
769 
770  {
771  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
772  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
773  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
774  }
775 
776  {
777  auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
778  auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
779  ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
780  }
781 }

References impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, and impeller::Geometry::MakeStrokePath().

◆ TEST_P() [272/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillCoverageIsCorrect   
)

Definition at line 1535 of file entity_unittests.cc.

1535  {
1536  // No transform
1537  {
1538  auto fill = std::make_shared<SolidColorContents>();
1539  fill->SetColor(Color::CornflowerBlue());
1540  auto expected = Rect::MakeLTRB(100, 110, 200, 220);
1541  fill->SetGeometry(
1542  Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));
1543 
1544  auto coverage = fill->GetCoverage({});
1545  ASSERT_TRUE(coverage.has_value());
1546  ASSERT_RECT_NEAR(coverage.value(), expected);
1547  }
1548 
1549  // Entity transform
1550  {
1551  auto fill = std::make_shared<SolidColorContents>();
1552  fill->SetColor(Color::CornflowerBlue());
1553  fill->SetGeometry(Geometry::MakeFillPath(
1554  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1555 
1556  Entity entity;
1557  entity.SetTransformation(Matrix::MakeTranslation(Vector2(4, 5)));
1558  entity.SetContents(std::move(fill));
1559 
1560  auto coverage = entity.GetCoverage();
1561  auto expected = Rect::MakeLTRB(104, 115, 204, 225);
1562  ASSERT_TRUE(coverage.has_value());
1563  ASSERT_RECT_NEAR(coverage.value(), expected);
1564  }
1565 
1566  // No coverage for fully transparent colors
1567  {
1568  auto fill = std::make_shared<SolidColorContents>();
1569  fill->SetColor(Color::WhiteTransparent());
1570  fill->SetGeometry(Geometry::MakeFillPath(
1571  PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));
1572 
1573  auto coverage = fill->GetCoverage({});
1574  ASSERT_FALSE(coverage.has_value());
1575  }
1576 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::CornflowerBlue(), impeller::Entity::GetCoverage(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Matrix::MakeTranslation(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), and impeller::Color::WhiteTransparent().

◆ TEST_P() [273/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidFillShouldRenderIsCorrect   
)

Definition at line 1578 of file entity_unittests.cc.

1578  {
1579  // No path.
1580  {
1581  auto fill = std::make_shared<SolidColorContents>();
1582  fill->SetColor(Color::CornflowerBlue());
1583  ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1584  ASSERT_FALSE(
1585  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1586  }
1587 
1588  // With path.
1589  {
1590  auto fill = std::make_shared<SolidColorContents>();
1591  fill->SetColor(Color::CornflowerBlue());
1592  fill->SetGeometry(Geometry::MakeFillPath(
1593  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1594  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1595  ASSERT_FALSE(
1596  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1597  }
1598 
1599  // With paint cover.
1600  {
1601  auto fill = std::make_shared<SolidColorContents>();
1602  fill->SetColor(Color::CornflowerBlue());
1603  fill->SetGeometry(Geometry::MakeCover());
1604  ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1605  ASSERT_TRUE(
1606  fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1607  }
1608 }

References impeller::PathBuilder::AddRect(), impeller::Color::CornflowerBlue(), impeller::Geometry::MakeCover(), impeller::Geometry::MakeFillPath(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TRect< Scalar >::MakeSize().

◆ TEST_P() [274/317]

impeller::testing::TEST_P ( EntityTest  ,
SolidStrokeCoverageIsCorrect   
)

Definition at line 1259 of file entity_unittests.cc.

1259  {
1260  {
1261  auto geometry = Geometry::MakeStrokePath(
1262  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1263  Cap::kButt, Join::kBevel);
1264 
1265  Entity entity;
1266  auto contents = std::make_unique<SolidColorContents>();
1267  contents->SetGeometry(std::move(geometry));
1268  contents->SetColor(Color::Black());
1269  entity.SetContents(std::move(contents));
1270  auto actual = entity.GetCoverage();
1271  auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
1272  ASSERT_TRUE(actual.has_value());
1273  ASSERT_RECT_NEAR(actual.value(), expected);
1274  }
1275 
1276  // Cover the Cap::kSquare case.
1277  {
1278  auto geometry = Geometry::MakeStrokePath(
1279  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
1280  Cap::kSquare, Join::kBevel);
1281 
1282  Entity entity;
1283  auto contents = std::make_unique<SolidColorContents>();
1284  contents->SetGeometry(std::move(geometry));
1285  contents->SetColor(Color::Black());
1286  entity.SetContents(std::move(contents));
1287  auto actual = entity.GetCoverage();
1288  auto expected =
1289  Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
1290  ASSERT_TRUE(actual.has_value());
1291  ASSERT_RECT_NEAR(actual.value(), expected);
1292  }
1293 
1294  // Cover the Join::kMiter case.
1295  {
1296  auto geometry = Geometry::MakeStrokePath(
1297  PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
1298  Cap::kSquare, Join::kMiter);
1299 
1300  Entity entity;
1301  auto contents = std::make_unique<SolidColorContents>();
1302  contents->SetGeometry(std::move(geometry));
1303  contents->SetColor(Color::Black());
1304  entity.SetContents(std::move(contents));
1305  auto actual = entity.GetCoverage();
1306  auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
1307  ASSERT_TRUE(actual.has_value());
1308  ASSERT_RECT_NEAR(actual.value(), expected);
1309  }
1310 }

References impeller::PathBuilder::AddLine(), ASSERT_RECT_NEAR, impeller::Color::Black(), impeller::Entity::GetCoverage(), impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kSquare, impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeStrokePath(), and impeller::Entity::SetContents().

◆ TEST_P() [275/317]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1918 of file entity_unittests.cc.

1918  {
1919  auto image = CreateTextureForFixture("embarcadero.jpg");
1920  ASSERT_TRUE(image);
1921 
1922  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1923  auto filtered =
1924  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1925 
1926  // Define the entity that will serve as the control image as a Gaussian blur
1927  // filter with no filter at all.
1928  Entity entity_left;
1929  entity_left.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1930  Matrix::MakeTranslation({100, 300}) *
1931  Matrix::MakeScale(Vector2{0.5, 0.5}));
1932  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1933  Sigma{0}, Sigma{0});
1934  entity_left.SetContents(unfiltered);
1935 
1936  // Define the entity that will be filtered from sRGB to linear.
1937  Entity entity_right;
1938  entity_right.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1939  Matrix::MakeTranslation({500, 300}) *
1940  Matrix::MakeScale(Vector2{0.5, 0.5}));
1941  entity_right.SetContents(filtered);
1942  return entity_left.Render(context, pass) &&
1943  entity_right.Render(context, pass);
1944  };
1945 
1946  ASSERT_TRUE(OpenPlaygroundHere(callback));
1947 }

References impeller::FilterInput::Make(), impeller::FilterContents::MakeGaussianBlur(), impeller::Matrix::MakeScale(), impeller::ColorFilterContents::MakeSrgbToLinearFilter(), impeller::Matrix::MakeTranslation(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [276/317]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1897 of file entity_unittests.cc.

1897  {
1898  // Set up a simple color background.
1899  auto fill = std::make_shared<SolidColorContents>();
1900  fill->SetGeometry(Geometry::MakeFillPath(
1901  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1902  fill->SetColor(Color::DeepPink());
1903 
1904  auto filter =
1905  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1906 
1907  Entity e;
1908  e.SetTransformation(Matrix());
1909 
1910  // Confirm that the actual filter coverage matches the expected coverage.
1911  auto actual = filter->GetCoverage(e);
1912  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1913 
1914  ASSERT_TRUE(actual.has_value());
1915  ASSERT_RECT_NEAR(actual.value(), expected);
1916 }

References impeller::PathBuilder::AddRect(), ASSERT_RECT_NEAR, impeller::Color::DeepPink(), impeller::FilterInput::Make(), impeller::Geometry::MakeFillPath(), impeller::ColorFilterContents::MakeSrgbToLinearFilter(), impeller::TRect< Scalar >::MakeXYWH(), and impeller::Entity::SetTransformation().

◆ TEST_P() [277/317]

impeller::testing::TEST_P ( EntityTest  ,
StrokeCapAndJoinTest   
)

Definition at line 343 of file entity_unittests.cc.

343  {
344  const Point padding(300, 250);
345  const Point margin(140, 180);
346 
347  auto callback = [&](ContentContext& context, RenderPass& pass) {
348  // Slightly above sqrt(2) by default, so that right angles are just below
349  // the limit and acute angles are over the limit (causing them to get
350  // beveled).
351  static Scalar miter_limit = 1.41421357;
352  static Scalar width = 30;
353 
354  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
355  {
356  ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
357  ImGui::SliderFloat("Stroke width", &width, 0, 100);
358  if (ImGui::Button("Reset")) {
359  miter_limit = 1.41421357;
360  width = 30;
361  }
362  }
363  ImGui::End();
364 
365  auto world_matrix = Matrix::MakeScale(GetContentScale());
366  auto render_path = [width = width, &context, &pass, &world_matrix](
367  const Path& path, Cap cap, Join join) {
368  auto contents = std::make_unique<SolidColorContents>();
369  contents->SetGeometry(
370  Geometry::MakeStrokePath(path, width, miter_limit, cap, join));
371  contents->SetColor(Color::Red());
372 
373  Entity entity;
374  entity.SetTransformation(world_matrix);
375  entity.SetContents(std::move(contents));
376 
377  auto coverage = entity.GetCoverage();
378  if (coverage.has_value()) {
379  auto bounds_contents = std::make_unique<SolidColorContents>();
380  bounds_contents->SetGeometry(Geometry::MakeFillPath(
381  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
382  bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
383  Entity bounds_entity;
384  bounds_entity.SetContents(std::move(bounds_contents));
385  bounds_entity.Render(context, pass);
386  }
387 
388  entity.Render(context, pass);
389  };
390 
391  const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
392  e_def(75, 75);
393  const Scalar r = 30;
394  // Cap::kButt demo.
395  {
396  Point off = Point(0, 0) * padding + margin;
397  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
398  Color::Black(), Color::White());
399  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
400  Color::Black(), Color::White());
401  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
402  Cap::kButt, Join::kBevel);
403  }
404 
405  // Cap::kSquare demo.
406  {
407  Point off = Point(1, 0) * padding + margin;
408  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
409  Color::Black(), Color::White());
410  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
411  Color::Black(), Color::White());
412  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
413  Cap::kSquare, Join::kBevel);
414  }
415 
416  // Cap::kRound demo.
417  {
418  Point off = Point(2, 0) * padding + margin;
419  auto [a, b] = IMPELLER_PLAYGROUND_LINE(off + a_def, off + b_def, r,
420  Color::Black(), Color::White());
421  auto [c, d] = IMPELLER_PLAYGROUND_LINE(off + c_def, off + d_def, r,
422  Color::Black(), Color::White());
423  render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
424  Cap::kRound, Join::kBevel);
425  }
426 
427  // Join::kBevel demo.
428  {
429  Point off = Point(0, 1) * padding + margin;
430  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
431  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
432  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
433  render_path(
434  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
435  Cap::kButt, Join::kBevel);
436  }
437 
438  // Join::kMiter demo.
439  {
440  Point off = Point(1, 1) * padding + margin;
441  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
442  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
443  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
444  render_path(
445  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
446  Cap::kButt, Join::kMiter);
447  }
448 
449  // Join::kRound demo.
450  {
451  Point off = Point(2, 1) * padding + margin;
452  Point a = IMPELLER_PLAYGROUND_POINT(off + a_def, r, Color::White());
453  Point b = IMPELLER_PLAYGROUND_POINT(off + e_def, r, Color::White());
454  Point c = IMPELLER_PLAYGROUND_POINT(off + c_def, r, Color::White());
455  render_path(
456  PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
457  Cap::kButt, Join::kRound);
458  }
459 
460  return true;
461  };
462  ASSERT_TRUE(OpenPlaygroundHere(callback));
463 }

References impeller::PathBuilder::AddCubicCurve(), impeller::PathBuilder::AddRect(), impeller::Color::Black(), impeller::Close(), impeller::Entity::GetCoverage(), impeller::Color::Green(), IMPELLER_PLAYGROUND_LINE, IMPELLER_PLAYGROUND_POINT, impeller::kBevel, impeller::kButt, impeller::kMiter, impeller::kRound, impeller::kSquare, impeller::LineTo(), impeller::Geometry::MakeFillPath(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [278/317]

impeller::testing::TEST_P ( EntityTest  ,
StrokeWithTextureContents   
)

Definition at line 280 of file entity_unittests.cc.

280  {
281  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
282  Path path = PathBuilder{}
283  .MoveTo({100, 100})
284  .LineTo({100, 200})
285  .MoveTo({100, 300})
286  .LineTo({100, 400})
287  .MoveTo({100, 500})
288  .LineTo({100, 600})
289  .TakePath();
290 
291  Entity entity;
292  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
293  auto contents = std::make_unique<TiledTextureContents>();
294  contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
295  contents->SetTexture(bridge);
296  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
297  entity.SetContents(std::move(contents));
298  ASSERT_TRUE(OpenPlaygroundHere(entity));
299 }

References impeller::Entity::kClamp, impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [279/317]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2359 of file entity_unittests.cc.

2359  {
2360  RadialGradientContents contents;
2361  contents.SetColors({Color::CornflowerBlue()});
2362  ASSERT_TRUE(contents.IsOpaque());
2363  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2364  ASSERT_FALSE(contents.IsOpaque());
2365  contents.SetColors({Color::CornflowerBlue()});
2366  contents.SetTileMode(Entity::TileMode::kDecal);
2367  ASSERT_FALSE(contents.IsOpaque());
2368 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [280/317]

impeller::testing::TEST_P ( EntityTest  ,
TessellateConvex   
)

Definition at line 2380 of file entity_unittests.cc.

2380  {
2381  {
2382  // Sanity check simple rectangle.
2383  auto [pts, indices] =
2384  TessellateConvex(PathBuilder{}
2385  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
2386  .TakePath()
2387  .CreatePolyline(1.0));
2388 
2389  std::vector<Point> expected = {
2390  {0, 0}, {10, 0}, {10, 10}, {0, 10}, //
2391  };
2392  std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3};
2393  ASSERT_EQ(pts, expected);
2394  ASSERT_EQ(indices, expected_indices);
2395  }
2396 
2397  {
2398  auto [pts, indices] =
2399  TessellateConvex(PathBuilder{}
2400  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
2401  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
2402  .TakePath()
2403  .CreatePolyline(1.0));
2404 
2405  std::vector<Point> expected = {
2406  {0, 0}, {10, 0}, {10, 10}, {0, 10}, //
2407  {20, 20}, {30, 20}, {30, 30}, {20, 30} //
2408  };
2409  std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3,
2410  0, 6, 7, 0, 7, 8};
2411  ASSERT_EQ(pts, expected);
2412  ASSERT_EQ(indices, expected_indices);
2413  }
2414 }

References impeller::PathBuilder::AddRect(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TessellateConvex().

◆ TEST_P() [281/317]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2462 of file entity_unittests.cc.

2462  {
2463  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2464  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2465  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2466  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2467 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [282/317]

impeller::testing::TEST_P ( EntityTest  ,
ThreeStrokesInOnePath   
)

Definition at line 261 of file entity_unittests.cc.

261  {
262  Path path = PathBuilder{}
263  .MoveTo({100, 100})
264  .LineTo({100, 200})
265  .MoveTo({100, 300})
266  .LineTo({100, 400})
267  .MoveTo({100, 500})
268  .LineTo({100, 600})
269  .TakePath();
270 
271  Entity entity;
272  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
273  auto contents = std::make_unique<SolidColorContents>();
274  contents->SetGeometry(Geometry::MakeStrokePath(path, 5.0));
275  contents->SetColor(Color::Red());
276  entity.SetContents(std::move(contents));
277  ASSERT_TRUE(OpenPlaygroundHere(entity));
278 }

References impeller::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::MoveTo(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [283/317]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2370 of file entity_unittests.cc.

2370  {
2371  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2372  TiledTextureContents contents;
2373  contents.SetTexture(bay_bridge);
2374  // This is a placeholder test. Images currently never decompress as opaque
2375  // (whether in Flutter or the playground), and so this should currently always
2376  // return false in practice.
2377  ASSERT_FALSE(contents.IsOpaque());
2378 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [284/317]

impeller::testing::TEST_P ( EntityTest  ,
TriangleInsideASquare   
)

Definition at line 301 of file entity_unittests.cc.

301  {
302  auto callback = [&](ContentContext& context, RenderPass& pass) {
303  Point offset(100, 100);
304 
305  Point a =
306  IMPELLER_PLAYGROUND_POINT(Point(10, 10) + offset, 20, Color::White());
307  Point b =
308  IMPELLER_PLAYGROUND_POINT(Point(210, 10) + offset, 20, Color::White());
309  Point c =
310  IMPELLER_PLAYGROUND_POINT(Point(210, 210) + offset, 20, Color::White());
311  Point d =
312  IMPELLER_PLAYGROUND_POINT(Point(10, 210) + offset, 20, Color::White());
313  Point e =
314  IMPELLER_PLAYGROUND_POINT(Point(50, 50) + offset, 20, Color::White());
315  Point f =
316  IMPELLER_PLAYGROUND_POINT(Point(100, 50) + offset, 20, Color::White());
317  Point g =
318  IMPELLER_PLAYGROUND_POINT(Point(50, 150) + offset, 20, Color::White());
319  Path path = PathBuilder{}
320  .MoveTo(a)
321  .LineTo(b)
322  .LineTo(c)
323  .LineTo(d)
324  .Close()
325  .MoveTo(e)
326  .LineTo(f)
327  .LineTo(g)
328  .Close()
329  .TakePath();
330 
331  Entity entity;
332  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
333  auto contents = std::make_unique<SolidColorContents>();
334  contents->SetGeometry(Geometry::MakeStrokePath(path, 20.0));
335  contents->SetColor(Color::Red());
336  entity.SetContents(std::move(contents));
337 
338  return entity.Render(context, pass);
339  };
340  ASSERT_TRUE(OpenPlaygroundHere(callback));
341 }

References impeller::PathBuilder::Close(), IMPELLER_PLAYGROUND_POINT, impeller::PathBuilder::LineTo(), impeller::Matrix::MakeScale(), impeller::Geometry::MakeStrokePath(), impeller::PathBuilder::MoveTo(), impeller::Color::Red(), impeller::Entity::Render(), impeller::Entity::SetContents(), impeller::Entity::SetTransformation(), impeller::PathBuilder::TakePath(), and impeller::Color::White().

◆ TEST_P() [285/317]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 2080 of file entity_unittests.cc.

2080  {
2081  if (GetParam() == PlaygroundBackend::kOpenGLES) {
2082  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
2083  GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
2084  }
2085 
2086  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2087  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
2088  YUVColorSpace::kBT601LimitedRange};
2089  for (int i = 0; i < 2; i++) {
2090  auto yuv_color_space = yuv_color_space_array[i];
2091  auto textures =
2092  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
2093  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
2094  textures[0], textures[1], yuv_color_space);
2095  Entity filter_entity;
2096  filter_entity.SetContents(filter_contents);
2097  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2098 
2099  Entity entity;
2100  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
2101  contents->SetTexture(snapshot->texture);
2102  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
2103  entity.SetContents(contents);
2104  entity.SetTransformation(
2105  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
2106  entity.Render(context, pass);
2107  }
2108  return true;
2109  };
2110  ASSERT_TRUE(OpenPlaygroundHere(callback));
2111 }

References CreateTestYUVTextures(), impeller::kBT601FullRange, impeller::kBT601LimitedRange, impeller::kOpenGLES, impeller::TRect< Scalar >::MakeLTRB(), impeller::TextureContents::MakeRect(), impeller::TRect< Scalar >::MakeSize(), impeller::Matrix::MakeTranslation(), impeller::FilterContents::MakeYUVToRGBFilter(), impeller::Entity::Render(), impeller::Entity::SetContents(), and impeller::Entity::SetTransformation().

◆ TEST_P() [286/317]

impeller::testing::TEST_P ( RendererDartTest  ,
CanEmplaceHostBuffer   
)

Definition at line 114 of file renderer_dart_unittests.cc.

114  {
115  auto isolate = GetIsolate();
116  bool result = isolate->RunInIsolateScope([]() -> bool {
117  if (tonic::CheckAndHandleError(
118  ::Dart_Invoke(Dart_RootLibrary(),
119  tonic::ToDart("canEmplaceHostBuffer"), 0, nullptr))) {
120  return false;
121  }
122  return true;
123  });
124 
125  ASSERT_TRUE(result);
126 }

◆ TEST_P() [287/317]

impeller::testing::TEST_P ( RendererDartTest  ,
CanInstantiateFlutterGPUContext   
)

Definition at line 100 of file renderer_dart_unittests.cc.

100  {
101  auto isolate = GetIsolate();
102  bool result = isolate->RunInIsolateScope([]() -> bool {
103  if (tonic::CheckAndHandleError(::Dart_Invoke(
104  Dart_RootLibrary(), tonic::ToDart("instantiateDefaultContext"), 0,
105  nullptr))) {
106  return false;
107  }
108  return true;
109  });
110 
111  ASSERT_TRUE(result);
112 }

◆ TEST_P() [288/317]

impeller::testing::TEST_P ( RendererDartTest  ,
CanRunDartInPlaygroundFrame   
)

Definition at line 80 of file renderer_dart_unittests.cc.

80  {
81  auto isolate = GetIsolate();
82 
83  SinglePassCallback callback = [&](RenderPass& pass) {
84  ImGui::Begin("Dart test", nullptr);
85  ImGui::Text(
86  "This test executes Dart code during the playground frame callback.");
87  ImGui::End();
88 
89  return isolate->RunInIsolateScope([]() -> bool {
90  if (tonic::CheckAndHandleError(::Dart_Invoke(
91  Dart_RootLibrary(), tonic::ToDart("sayHi"), 0, nullptr))) {
92  return false;
93  }
94  return true;
95  });
96  };
97  OpenPlaygroundHere(callback);
98 }

◆ TEST_P() [289/317]

impeller::testing::TEST_P ( RendererTest  ,
ArrayUniforms   
)

Definition at line 881 of file renderer_unittests.cc.

881  {
882  using VS = ArrayVertexShader;
883  using FS = ArrayFragmentShader;
884 
885  auto context = GetContext();
886  auto pipeline_descriptor =
887  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
888  ASSERT_TRUE(pipeline_descriptor.has_value());
889  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
890  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
891  auto pipeline =
892  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
893  ASSERT_TRUE(pipeline && pipeline->IsValid());
894 
895  SinglePassCallback callback = [&](RenderPass& pass) {
896  auto size = pass.GetRenderTargetSize();
897 
898  Command cmd;
899  cmd.pipeline = pipeline;
900  DEBUG_COMMAND_INFO(cmd, "Google Dots");
901  VertexBufferBuilder<VS::PerVertexData> builder;
902  builder.AddVertices({{Point()},
903  {Point(0, size.height)},
904  {Point(size.width, 0)},
905  {Point(size.width, 0)},
906  {Point(0, size.height)},
907  {Point(size.width, size.height)}});
908  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
909 
910  VS::FrameInfo frame_info;
911  frame_info.mvp =
912  Matrix::MakeOrthographic(size) * Matrix::MakeScale(GetContentScale());
913  VS::BindFrameInfo(cmd,
914  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
915 
916  auto time = GetSecondsElapsed();
917  auto y_pos = [&time](float x) {
918  return 400 + 10 * std::cos(time * 5 + x / 6);
919  };
920 
921  FS::FragInfo fs_uniform = {
922  .circle_positions = {Point(430, y_pos(0)), Point(480, y_pos(1)),
923  Point(530, y_pos(2)), Point(580, y_pos(3))},
924  .colors = {Color::MakeRGBA8(66, 133, 244, 255),
925  Color::MakeRGBA8(219, 68, 55, 255),
926  Color::MakeRGBA8(244, 180, 0, 255),
927  Color::MakeRGBA8(15, 157, 88, 255)},
928  };
929  FS::BindFragInfo(cmd,
930  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
931 
932  pass.AddCommand(std::move(cmd));
933  return true;
934  };
935  OpenPlaygroundHere(callback);
936 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Color::MakeRGBA8(), impeller::Matrix::MakeScale(), and impeller::Command::pipeline.

◆ TEST_P() [290/317]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToBuffer   
)

Definition at line 571 of file renderer_unittests.cc.

571  {
572  auto context = GetContext();
573  ASSERT_TRUE(context);
574 
575  using VS = MipmapsVertexShader;
576  using FS = MipmapsFragmentShader;
577  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
578  ASSERT_TRUE(desc.has_value());
579  desc->SetSampleCount(SampleCount::kCount4);
580  desc->SetStencilAttachmentDescriptors(std::nullopt);
581  auto mipmaps_pipeline =
582  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
583  ASSERT_TRUE(mipmaps_pipeline);
584 
585  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
586  auto boston = CreateTextureForFixture("boston.jpg");
587  ASSERT_TRUE(bridge && boston);
588  auto sampler = context->GetSamplerLibrary()->GetSampler({});
589  ASSERT_TRUE(sampler);
590 
591  TextureDescriptor texture_desc;
592  texture_desc.storage_mode = StorageMode::kHostVisible;
593  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
594  texture_desc.size = bridge->GetTextureDescriptor().size;
595  texture_desc.mip_count = 1u;
596  texture_desc.usage =
597  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget) |
598  static_cast<TextureUsageMask>(TextureUsage::kShaderWrite) |
599  static_cast<TextureUsageMask>(TextureUsage::kShaderRead);
600  DeviceBufferDescriptor device_buffer_desc;
601  device_buffer_desc.storage_mode = StorageMode::kHostVisible;
602  device_buffer_desc.size =
603  bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
604  auto device_buffer =
605  context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
606 
607  // Vertex buffer.
608  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
609  vertex_builder.SetLabel("Box");
610  auto size = Point(boston->GetSize());
611  vertex_builder.AddVertices({
612  {{0, 0}, {0.0, 0.0}}, // 1
613  {{size.x, 0}, {1.0, 0.0}}, // 2
614  {{size.x, size.y}, {1.0, 1.0}}, // 3
615  {{0, 0}, {0.0, 0.0}}, // 1
616  {{size.x, size.y}, {1.0, 1.0}}, // 3
617  {{0, size.y}, {0.0, 1.0}}, // 4
618  });
619  auto vertex_buffer =
620  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
621  ASSERT_TRUE(vertex_buffer);
622 
623  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
624  {
625  auto buffer = context->CreateCommandBuffer();
626  if (!buffer) {
627  return false;
628  }
629  buffer->SetLabel("Playground Command Buffer");
630  auto pass = buffer->CreateBlitPass();
631  if (!pass) {
632  return false;
633  }
634  pass->SetLabel("Playground Blit Pass");
635 
636  if (render_target.GetColorAttachments().empty()) {
637  return false;
638  }
639 
640  // Blit `bridge` to the top left corner of the texture.
641  pass->AddCopy(bridge, device_buffer);
642 
643  pass->EncodeCommands(context->GetResourceAllocator());
644 
645  if (!buffer->SubmitCommands()) {
646  return false;
647  }
648  }
649 
650  {
651  auto buffer = context->CreateCommandBuffer();
652  if (!buffer) {
653  return false;
654  }
655  buffer->SetLabel("Playground Command Buffer");
656 
657  auto pass = buffer->CreateRenderPass(render_target);
658  if (!pass) {
659  return false;
660  }
661  pass->SetLabel("Playground Render Pass");
662  {
663  Command cmd;
664  DEBUG_COMMAND_INFO(cmd, "Image");
665  cmd.pipeline = mipmaps_pipeline;
666 
667  cmd.BindVertices(vertex_buffer);
668 
669  VS::FrameInfo frame_info;
670  frame_info.mvp = Matrix::MakeOrthographic(pass->GetRenderTargetSize()) *
671  Matrix::MakeScale(GetContentScale());
672  VS::BindFrameInfo(
673  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
674 
675  FS::FragInfo frag_info;
676  frag_info.lod = 0;
677  FS::BindFragInfo(cmd,
678  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
679 
680  auto sampler = context->GetSamplerLibrary()->GetSampler({});
681  auto buffer_view = device_buffer->AsBufferView();
682  auto texture =
683  context->GetResourceAllocator()->CreateTexture(texture_desc);
684  if (!texture->SetContents(buffer_view.contents,
685  buffer_view.range.length)) {
686  VALIDATION_LOG << "Could not upload texture to device memory";
687  return false;
688  }
689  FS::BindTex(cmd, texture, sampler);
690 
691  pass->AddCommand(std::move(cmd));
692  }
693  pass->EncodeCommands();
694  if (!buffer->SubmitCommands()) {
695  return false;
696  }
697  }
698  return true;
699  };
700  OpenPlaygroundHere(callback);
701 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::kShaderWrite, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, impeller::TextureDescriptor::usage, and VALIDATION_LOG.

◆ TEST_P() [291/317]

impeller::testing::TEST_P ( RendererTest  ,
CanBlitTextureToTexture   
)

Definition at line 458 of file renderer_unittests.cc.

458  {
459  auto context = GetContext();
460  ASSERT_TRUE(context);
461 
462  using VS = MipmapsVertexShader;
463  using FS = MipmapsFragmentShader;
464  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
465  ASSERT_TRUE(desc.has_value());
466  desc->SetSampleCount(SampleCount::kCount4);
467  desc->SetStencilAttachmentDescriptors(std::nullopt);
468  auto mipmaps_pipeline =
469  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
470  ASSERT_TRUE(mipmaps_pipeline);
471 
472  TextureDescriptor texture_desc;
473  texture_desc.storage_mode = StorageMode::kHostVisible;
474  texture_desc.format = PixelFormat::kR8G8B8A8UNormInt;
475  texture_desc.size = {800, 600};
476  texture_desc.mip_count = 1u;
477  texture_desc.usage =
478  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget) |
479  static_cast<TextureUsageMask>(TextureUsage::kShaderRead);
480  auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
481  ASSERT_TRUE(texture);
482 
483  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
484  auto boston = CreateTextureForFixture("boston.jpg");
485  ASSERT_TRUE(bridge && boston);
486  auto sampler = context->GetSamplerLibrary()->GetSampler({});
487  ASSERT_TRUE(sampler);
488 
489  // Vertex buffer.
490  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
491  vertex_builder.SetLabel("Box");
492  auto size = Point(boston->GetSize());
493  vertex_builder.AddVertices({
494  {{0, 0}, {0.0, 0.0}}, // 1
495  {{size.x, 0}, {1.0, 0.0}}, // 2
496  {{size.x, size.y}, {1.0, 1.0}}, // 3
497  {{0, 0}, {0.0, 0.0}}, // 1
498  {{size.x, size.y}, {1.0, 1.0}}, // 3
499  {{0, size.y}, {0.0, 1.0}}, // 4
500  });
501  auto vertex_buffer =
502  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
503  ASSERT_TRUE(vertex_buffer);
504 
505  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
506  auto buffer = context->CreateCommandBuffer();
507  if (!buffer) {
508  return false;
509  }
510  buffer->SetLabel("Playground Command Buffer");
511 
512  {
513  auto pass = buffer->CreateBlitPass();
514  if (!pass) {
515  return false;
516  }
517  pass->SetLabel("Playground Blit Pass");
518 
519  if (render_target.GetColorAttachments().empty()) {
520  return false;
521  }
522 
523  // Blit `bridge` to the top left corner of the texture.
524  pass->AddCopy(bridge, texture);
525 
526  if (!pass->EncodeCommands(context->GetResourceAllocator())) {
527  return false;
528  }
529  }
530 
531  {
532  auto pass = buffer->CreateRenderPass(render_target);
533  if (!pass) {
534  return false;
535  }
536  pass->SetLabel("Playground Render Pass");
537  {
538  Command cmd;
539  DEBUG_COMMAND_INFO(cmd, "Image");
540  cmd.pipeline = mipmaps_pipeline;
541 
542  cmd.BindVertices(vertex_buffer);
543 
544  VS::FrameInfo frame_info;
545  frame_info.mvp = Matrix::MakeOrthographic(pass->GetRenderTargetSize()) *
546  Matrix::MakeScale(GetContentScale());
547  VS::BindFrameInfo(
548  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
549 
550  FS::FragInfo frag_info;
551  frag_info.lod = 0;
552  FS::BindFragInfo(cmd,
553  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
554 
555  auto sampler = context->GetSamplerLibrary()->GetSampler({});
556  FS::BindTex(cmd, texture, sampler);
557 
558  pass->AddCommand(std::move(cmd));
559  }
560  pass->EncodeCommands();
561  }
562 
563  if (!buffer->SubmitCommands()) {
564  return false;
565  }
566  return true;
567  };
568  OpenPlaygroundHere(callback);
569 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::kCount4, impeller::kHostVisible, impeller::kR8G8B8A8UNormInt, impeller::kRenderTarget, impeller::kShaderRead, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, and impeller::TextureDescriptor::usage.

◆ TEST_P() [292/317]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateBoxPrimitive   
)

Definition at line 52 of file renderer_unittests.cc.

52  {
53  using VS = BoxFadeVertexShader;
54  using FS = BoxFadeFragmentShader;
55  auto context = GetContext();
56  ASSERT_TRUE(context);
57  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
58  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
59  ASSERT_TRUE(desc.has_value());
60  desc->SetSampleCount(SampleCount::kCount4);
61  desc->SetStencilAttachmentDescriptors(std::nullopt);
62 
63  // Vertex buffer.
64  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
65  vertex_builder.SetLabel("Box");
66  vertex_builder.AddVertices({
67  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
68  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
69  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
70  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
71  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
72  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
73  });
74  auto vertex_buffer =
75  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
76  ASSERT_TRUE(vertex_buffer);
77 
78  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
79  auto boston = CreateTextureForFixture("boston.jpg");
80  ASSERT_TRUE(bridge && boston);
81  auto sampler = context->GetSamplerLibrary()->GetSampler({});
82  ASSERT_TRUE(sampler);
83  SinglePassCallback callback = [&](RenderPass& pass) {
84  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
85  static bool wireframe;
86  ImGui::Checkbox("Wireframe", &wireframe);
87  ImGui::End();
88 
89  desc->SetPolygonMode(wireframe ? PolygonMode::kLine : PolygonMode::kFill);
90  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
91 
92  assert(pipeline && pipeline->IsValid());
93 
94  Command cmd;
95  DEBUG_COMMAND_INFO(cmd, "Box");
96  cmd.pipeline = pipeline;
97 
98  cmd.BindVertices(vertex_buffer);
99 
100  VS::UniformBuffer uniforms;
101  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
102  Matrix::MakeScale(GetContentScale());
103  VS::BindUniformBuffer(cmd,
104  pass.GetTransientsBuffer().EmplaceUniform(uniforms));
105 
106  FS::FrameInfo frame_info;
107  frame_info.current_time = GetSecondsElapsed();
108  frame_info.cursor_position = GetCursorPosition();
109  frame_info.window_size.x = GetWindowSize().width;
110  frame_info.window_size.y = GetWindowSize().height;
111 
112  FS::BindFrameInfo(cmd,
113  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
114  FS::BindContents1(cmd, boston, sampler);
115  FS::BindContents2(cmd, bridge, sampler);
116  if (!pass.AddCommand(std::move(cmd))) {
117  return false;
118  }
119  return true;
120  };
121  OpenPlaygroundHere(callback);
122 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::kFill, impeller::kLine, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [293/317]

impeller::testing::TEST_P ( RendererTest  ,
CanCreateCPUBackedTexture   
)

Definition at line 984 of file renderer_unittests.cc.

984  {
985  if (GetParam() == PlaygroundBackend::kOpenGLES) {
986  GTEST_SKIP_("CPU backed textures are not supported on OpenGLES.");
987  }
988 
989  auto context = GetContext();
990  auto allocator = context->GetResourceAllocator();
991  size_t dimension = 2;
992 
993  do {
994  ISize size(dimension, dimension);
995  TextureDescriptor texture_descriptor;
996  texture_descriptor.storage_mode = StorageMode::kHostVisible;
997  texture_descriptor.format = PixelFormat::kR8G8B8A8UNormInt;
998  texture_descriptor.size = size;
999  auto row_bytes =
1000  std::max(static_cast<uint16_t>(size.width * 4),
1001  allocator->MinimumBytesPerRow(texture_descriptor.format));
1002  auto buffer_size = size.height * row_bytes;
1003 
1004  DeviceBufferDescriptor buffer_descriptor;
1005  buffer_descriptor.storage_mode = StorageMode::kHostVisible;
1006  buffer_descriptor.size = buffer_size;
1007 
1008  auto buffer = allocator->CreateBuffer(buffer_descriptor);
1009 
1010  ASSERT_TRUE(buffer);
1011 
1012  auto texture = buffer->AsTexture(*allocator, texture_descriptor, row_bytes);
1013 
1014  ASSERT_TRUE(texture);
1015  ASSERT_TRUE(texture->IsValid());
1016 
1017  dimension *= 2;
1018  } while (dimension <= 8192);
1019 }

References impeller::TextureDescriptor::format, impeller::TSize< T >::height, impeller::kHostVisible, impeller::kOpenGLES, impeller::kR8G8B8A8UNormInt, impeller::DeviceBufferDescriptor::size, impeller::TextureDescriptor::size, impeller::DeviceBufferDescriptor::storage_mode, impeller::TextureDescriptor::storage_mode, and impeller::TSize< T >::width.

◆ TEST_P() [294/317]

impeller::testing::TEST_P ( RendererTest  ,
CanGenerateMipmaps   
)

Definition at line 703 of file renderer_unittests.cc.

703  {
704  auto context = GetContext();
705  ASSERT_TRUE(context);
706 
707  using VS = MipmapsVertexShader;
708  using FS = MipmapsFragmentShader;
709  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
710  ASSERT_TRUE(desc.has_value());
711  desc->SetSampleCount(SampleCount::kCount4);
712  desc->SetStencilAttachmentDescriptors(std::nullopt);
713  auto mipmaps_pipeline =
714  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
715  ASSERT_TRUE(mipmaps_pipeline);
716 
717  auto boston = CreateTextureForFixture("boston.jpg", true);
718  ASSERT_TRUE(boston);
719 
720  // Vertex buffer.
721  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
722  vertex_builder.SetLabel("Box");
723  auto size = Point(boston->GetSize());
724  vertex_builder.AddVertices({
725  {{0, 0}, {0.0, 0.0}}, // 1
726  {{size.x, 0}, {1.0, 0.0}}, // 2
727  {{size.x, size.y}, {1.0, 1.0}}, // 3
728  {{0, 0}, {0.0, 0.0}}, // 1
729  {{size.x, size.y}, {1.0, 1.0}}, // 3
730  {{0, size.y}, {0.0, 1.0}}, // 4
731  });
732  auto vertex_buffer =
733  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
734  ASSERT_TRUE(vertex_buffer);
735 
736  bool first_frame = true;
737  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
738  const char* mip_filter_names[] = {"Nearest", "Linear"};
739  const MipFilter mip_filters[] = {MipFilter::kNearest, MipFilter::kLinear};
740  const char* min_filter_names[] = {"Nearest", "Linear"};
741  const MinMagFilter min_filters[] = {MinMagFilter::kNearest,
742  MinMagFilter::kLinear};
743 
744  // UI state.
745  static int selected_mip_filter = 1;
746  static int selected_min_filter = 0;
747  static float lod = 4.5;
748 
749  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
750  ImGui::Combo("Mip filter", &selected_mip_filter, mip_filter_names,
751  sizeof(mip_filter_names) / sizeof(char*));
752  ImGui::Combo("Min filter", &selected_min_filter, min_filter_names,
753  sizeof(min_filter_names) / sizeof(char*));
754  ImGui::SliderFloat("LOD", &lod, 0, boston->GetMipCount() - 1);
755  ImGui::End();
756 
757  auto buffer = context->CreateCommandBuffer();
758  if (!buffer) {
759  return false;
760  }
761  buffer->SetLabel("Playground Command Buffer");
762 
763  if (first_frame) {
764  auto pass = buffer->CreateBlitPass();
765  if (!pass) {
766  return false;
767  }
768  pass->SetLabel("Playground Blit Pass");
769 
770  pass->GenerateMipmap(boston, "Boston Mipmap");
771 
772  pass->EncodeCommands(context->GetResourceAllocator());
773  }
774 
775  first_frame = false;
776 
777  {
778  auto pass = buffer->CreateRenderPass(render_target);
779  if (!pass) {
780  return false;
781  }
782  pass->SetLabel("Playground Render Pass");
783  {
784  Command cmd;
785  DEBUG_COMMAND_INFO(cmd, "Image LOD");
786  cmd.pipeline = mipmaps_pipeline;
787 
788  cmd.BindVertices(vertex_buffer);
789 
790  VS::FrameInfo frame_info;
791  frame_info.mvp = Matrix::MakeOrthographic(pass->GetRenderTargetSize()) *
792  Matrix::MakeScale(GetContentScale());
793  VS::BindFrameInfo(
794  cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
795 
796  FS::FragInfo frag_info;
797  frag_info.lod = lod;
798  FS::BindFragInfo(cmd,
799  pass->GetTransientsBuffer().EmplaceUniform(frag_info));
800 
801  SamplerDescriptor sampler_desc;
802  sampler_desc.mip_filter = mip_filters[selected_mip_filter];
803  sampler_desc.min_filter = min_filters[selected_min_filter];
804  auto sampler = context->GetSamplerLibrary()->GetSampler(sampler_desc);
805  FS::BindTex(cmd, boston, sampler);
806 
807  pass->AddCommand(std::move(cmd));
808  }
809  pass->EncodeCommands();
810  }
811 
812  if (!buffer->SubmitCommands()) {
813  return false;
814  }
815  return true;
816  };
817  OpenPlaygroundHere(callback);
818 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::kLinear, impeller::kNearest, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::SamplerDescriptor::min_filter, impeller::SamplerDescriptor::mip_filter, impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [295/317]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderInstanced   
)

Definition at line 391 of file renderer_unittests.cc.

391  {
392  if (GetParam() == PlaygroundBackend::kOpenGLES) {
393  GTEST_SKIP_("Instancing is not supported on OpenGL.");
394  }
395  using VS = InstancedDrawVertexShader;
396  using FS = InstancedDrawFragmentShader;
397 
398  VertexBufferBuilder<VS::PerVertexData> builder;
399 
400  ASSERT_EQ(Tessellator::Result::kSuccess,
401  Tessellator{}.Tessellate(
402  FillType::kPositive,
403  PathBuilder{}
404  .AddRect(Rect::MakeXYWH(10, 10, 100, 100))
405  .TakePath()
406  .CreatePolyline(1.0f),
407  [&builder](const float* vertices, size_t vertices_count,
408  const uint16_t* indices, size_t indices_count) {
409  for (auto i = 0u; i < vertices_count * 2; i += 2) {
410  VS::PerVertexData data;
411  data.vtx = {vertices[i], vertices[i + 1]};
412  builder.AppendVertex(data);
413  }
414  for (auto i = 0u; i < indices_count; i++) {
415  builder.AppendIndex(indices[i]);
416  }
417  return true;
418  }));
419 
420  ASSERT_NE(GetContext(), nullptr);
421  auto pipeline =
422  GetContext()
423  ->GetPipelineLibrary()
424  ->GetPipeline(PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(
425  *GetContext())
426  ->SetSampleCount(SampleCount::kCount4)
427  .SetStencilAttachmentDescriptors(std::nullopt))
428 
429  .Get();
430  ASSERT_TRUE(pipeline && pipeline->IsValid());
431 
432  Command cmd;
433  cmd.pipeline = pipeline;
434  DEBUG_COMMAND_INFO(cmd, "InstancedDraw");
435 
436  static constexpr size_t kInstancesCount = 5u;
437  VS::InstanceInfo<kInstancesCount> instances;
438  for (size_t i = 0; i < kInstancesCount; i++) {
439  instances.colors[i] = Color::Random();
440  }
441 
442  ASSERT_TRUE(OpenPlaygroundHere([&](RenderPass& pass) -> bool {
443  VS::FrameInfo frame_info;
444  frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
445  Matrix::MakeScale(GetContentScale());
446  VS::BindFrameInfo(cmd,
447  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
448  VS::BindInstanceInfo(
449  cmd, pass.GetTransientsBuffer().EmplaceStorageBuffer(instances));
450  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
451 
452  cmd.instance_count = kInstancesCount;
453  pass.AddCommand(std::move(cmd));
454  return true;
455  }));
456 }

References impeller::RenderPass::AddCommand(), impeller::PathBuilder::AddRect(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendVertex(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::HostBuffer::EmplaceStorageBuffer(), impeller::HostBuffer::EmplaceUniform(), impeller::RenderPass::GetRenderTargetSize(), impeller::RenderPass::GetTransientsBuffer(), impeller::Command::instance_count, impeller::kCount4, impeller::kOpenGLES, impeller::kPositive, impeller::Tessellator::kSuccess, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::TRect< Scalar >::MakeXYWH(), impeller::Command::pipeline, impeller::Color::Random(), and impeller::Tessellator::Tessellate().

◆ TEST_P() [296/317]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderMultiplePrimitives   
)

Definition at line 215 of file renderer_unittests.cc.

215  {
216  using VS = BoxFadeVertexShader;
217  using FS = BoxFadeFragmentShader;
218  auto context = GetContext();
219  ASSERT_TRUE(context);
220  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
221  auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
222  ASSERT_TRUE(desc.has_value());
223  desc->SetSampleCount(SampleCount::kCount4);
224  desc->SetStencilAttachmentDescriptors(std::nullopt);
225  auto box_pipeline =
226  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
227  ASSERT_TRUE(box_pipeline);
228 
229  // Vertex buffer.
230  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
231  vertex_builder.SetLabel("Box");
232  vertex_builder.AddVertices({
233  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
234  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
235  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
236  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
237  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
238  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
239  });
240  auto vertex_buffer =
241  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
242  ASSERT_TRUE(vertex_buffer);
243 
244  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
245  auto boston = CreateTextureForFixture("boston.jpg");
246  ASSERT_TRUE(bridge && boston);
247  auto sampler = context->GetSamplerLibrary()->GetSampler({});
248  ASSERT_TRUE(sampler);
249 
250  SinglePassCallback callback = [&](RenderPass& pass) {
251  Command cmd;
252  DEBUG_COMMAND_INFO(cmd, "Box");
253  cmd.pipeline = box_pipeline;
254 
255  cmd.BindVertices(vertex_buffer);
256 
257  FS::FrameInfo frame_info;
258  frame_info.current_time = GetSecondsElapsed();
259  frame_info.cursor_position = GetCursorPosition();
260  frame_info.window_size.x = GetWindowSize().width;
261  frame_info.window_size.y = GetWindowSize().height;
262 
263  FS::BindFrameInfo(cmd,
264  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
265  FS::BindContents1(cmd, boston, sampler);
266  FS::BindContents2(cmd, bridge, sampler);
267 
268  for (size_t i = 0; i < 1; i++) {
269  for (size_t j = 0; j < 1; j++) {
270  VS::UniformBuffer uniforms;
271  uniforms.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
272  Matrix::MakeScale(GetContentScale()) *
273  Matrix::MakeTranslation({i * 50.0f, j * 50.0f, 0.0f});
274  VS::BindUniformBuffer(
275  cmd, pass.GetTransientsBuffer().EmplaceUniform(uniforms));
276  if (!pass.AddCommand(std::move(cmd))) {
277  return false;
278  }
279  }
280  }
281 
282  return true;
283  };
284  OpenPlaygroundHere(callback);
285 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::kCount4, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Matrix::MakeTranslation(), impeller::Command::pipeline, and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [297/317]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderPerspectiveCube   
)

Definition at line 124 of file renderer_unittests.cc.

124  {
125  using VS = ColorsVertexShader;
126  using FS = ColorsFragmentShader;
127  auto context = GetContext();
128  ASSERT_TRUE(context);
129  auto desc = PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
130  ASSERT_TRUE(desc.has_value());
131  desc->SetCullMode(CullMode::kBackFace);
132  desc->SetWindingOrder(WindingOrder::kCounterClockwise);
133  desc->SetSampleCount(SampleCount::kCount4);
134  desc->SetStencilAttachmentDescriptors(std::nullopt);
135  auto pipeline =
136  context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
137  ASSERT_TRUE(pipeline);
138 
139  struct Cube {
140  VS::PerVertexData vertices[8] = {
141  // -Z
142  {{-1, -1, -1}, Color::Red()},
143  {{1, -1, -1}, Color::Yellow()},
144  {{1, 1, -1}, Color::Green()},
145  {{-1, 1, -1}, Color::Blue()},
146  // +Z
147  {{-1, -1, 1}, Color::Green()},
148  {{1, -1, 1}, Color::Blue()},
149  {{1, 1, 1}, Color::Red()},
150  {{-1, 1, 1}, Color::Yellow()},
151  };
152  uint16_t indices[36] = {
153  1, 5, 2, 2, 5, 6, // +X
154  4, 0, 7, 7, 0, 3, // -X
155  4, 5, 0, 0, 5, 1, // +Y
156  3, 2, 7, 7, 2, 6, // -Y
157  5, 4, 6, 6, 4, 7, // +Z
158  0, 1, 3, 3, 1, 2, // -Z
159  };
160  } cube;
161 
162  VertexBuffer vertex_buffer;
163  {
164  auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
165  reinterpret_cast<uint8_t*>(&cube), sizeof(cube));
166  vertex_buffer.vertex_buffer = {
167  .buffer = device_buffer,
168  .range = Range(offsetof(Cube, vertices), sizeof(Cube::vertices))};
169  vertex_buffer.index_buffer = {
170  .buffer = device_buffer,
171  .range = Range(offsetof(Cube, indices), sizeof(Cube::indices))};
172  vertex_buffer.vertex_count = 36;
173  vertex_buffer.index_type = IndexType::k16bit;
174  }
175 
176  auto sampler = context->GetSamplerLibrary()->GetSampler({});
177  ASSERT_TRUE(sampler);
178 
179  Vector3 euler_angles;
180  SinglePassCallback callback = [&](RenderPass& pass) {
181  static Degrees fov_y(60);
182  static Scalar distance = 10;
183 
184  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
185  ImGui::SliderFloat("Field of view", &fov_y.degrees, 0, 180);
186  ImGui::SliderFloat("Camera distance", &distance, 0, 30);
187  ImGui::End();
188 
189  Command cmd;
190  DEBUG_COMMAND_INFO(cmd, "Perspective Cube");
191  cmd.pipeline = pipeline;
192 
193  cmd.BindVertices(vertex_buffer);
194 
195  VS::UniformBuffer uniforms;
196  Scalar time = GetSecondsElapsed();
197  euler_angles = Vector3(0.19 * time, 0.7 * time, 0.43 * time);
198 
199  uniforms.mvp =
200  Matrix::MakePerspective(fov_y, pass.GetRenderTargetSize(), 0, 10) *
201  Matrix::MakeTranslation({0, 0, distance}) *
202  Matrix::MakeRotationX(Radians(euler_angles.x)) *
203  Matrix::MakeRotationY(Radians(euler_angles.y)) *
204  Matrix::MakeRotationZ(Radians(euler_angles.z));
205  VS::BindUniformBuffer(cmd,
206  pass.GetTransientsBuffer().EmplaceUniform(uniforms));
207  if (!pass.AddCommand(std::move(cmd))) {
208  return false;
209  }
210  return true;
211  };
212  OpenPlaygroundHere(callback);
213 }

References impeller::Command::BindVertices(), impeller::Color::Blue(), impeller::BufferView::buffer, DEBUG_COMMAND_INFO, impeller::Degrees::degrees, impeller::Color::Green(), impeller::VertexBuffer::index_buffer, impeller::VertexBuffer::index_type, impeller::k16bit, impeller::kBackFace, impeller::kCount4, impeller::kCounterClockwise, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakePerspective(), impeller::Matrix::MakeRotationX(), impeller::Matrix::MakeRotationY(), impeller::Matrix::MakeRotationZ(), impeller::Matrix::MakeTranslation(), impeller::Command::pipeline, impeller::Color::Red(), impeller::VertexBuffer::vertex_buffer, impeller::VertexBuffer::vertex_count, impeller::Vector3::x, impeller::Vector3::y, impeller::Color::Yellow(), and impeller::Vector3::z.

◆ TEST_P() [298/317]

impeller::testing::TEST_P ( RendererTest  ,
CanRenderToTexture   
)

Definition at line 287 of file renderer_unittests.cc.

287  {
288  using VS = BoxFadeVertexShader;
289  using FS = BoxFadeFragmentShader;
290  auto context = GetContext();
291  ASSERT_TRUE(context);
292  using BoxPipelineBuilder = PipelineBuilder<VS, FS>;
293  auto pipeline_desc =
294  BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
295  pipeline_desc->SetSampleCount(SampleCount::kCount1);
296 
297  ASSERT_TRUE(pipeline_desc.has_value());
298  auto box_pipeline =
299  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
300  ASSERT_TRUE(box_pipeline);
301 
302  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
303  vertex_builder.SetLabel("Box");
304  vertex_builder.AddVertices({
305  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
306  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
307  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
308  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
309  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
310  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
311  });
312  auto vertex_buffer =
313  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
314  ASSERT_TRUE(vertex_buffer);
315 
316  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
317  auto boston = CreateTextureForFixture("boston.jpg");
318  ASSERT_TRUE(bridge && boston);
319  auto sampler = context->GetSamplerLibrary()->GetSampler({});
320  ASSERT_TRUE(sampler);
321  std::shared_ptr<RenderPass> r2t_pass;
322  auto cmd_buffer = context->CreateCommandBuffer();
323  ASSERT_TRUE(cmd_buffer);
324  {
325  ColorAttachment color0;
326  color0.load_action = LoadAction::kClear;
327  color0.store_action = StoreAction::kStore;
328 
329  TextureDescriptor texture_descriptor;
330  ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u), nullptr);
331  texture_descriptor.format =
332  pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
333  texture_descriptor.storage_mode = StorageMode::kHostVisible;
334  texture_descriptor.size = {400, 400};
335  texture_descriptor.mip_count = 1u;
336  texture_descriptor.usage =
337  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
338 
339  color0.texture =
340  context->GetResourceAllocator()->CreateTexture(texture_descriptor);
341 
342  ASSERT_TRUE(color0.IsValid());
343 
344  color0.texture->SetLabel("r2t_target");
345 
346  StencilAttachment stencil0;
347  stencil0.load_action = LoadAction::kClear;
348  stencil0.store_action = StoreAction::kDontCare;
349  TextureDescriptor stencil_texture_desc;
350  stencil_texture_desc.storage_mode = StorageMode::kDeviceTransient;
351  stencil_texture_desc.size = texture_descriptor.size;
352  stencil_texture_desc.format = PixelFormat::kS8UInt;
353  stencil_texture_desc.usage =
354  static_cast<TextureUsageMask>(TextureUsage::kRenderTarget);
355  stencil0.texture =
356  context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
357 
358  RenderTarget r2t_desc;
359  r2t_desc.SetColorAttachment(color0, 0u);
360  r2t_desc.SetStencilAttachment(stencil0);
361  r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
362  ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
363  }
364 
365  Command cmd;
366  DEBUG_COMMAND_INFO(cmd, "Box");
367  cmd.pipeline = box_pipeline;
368 
369  cmd.BindVertices(vertex_buffer);
370 
371  FS::FrameInfo frame_info;
372  frame_info.current_time = GetSecondsElapsed();
373  frame_info.cursor_position = GetCursorPosition();
374  frame_info.window_size.x = GetWindowSize().width;
375  frame_info.window_size.y = GetWindowSize().height;
376 
377  FS::BindFrameInfo(cmd,
378  r2t_pass->GetTransientsBuffer().EmplaceUniform(frame_info));
379  FS::BindContents1(cmd, boston, sampler);
380  FS::BindContents2(cmd, bridge, sampler);
381 
382  VS::UniformBuffer uniforms;
383  uniforms.mvp = Matrix::MakeOrthographic(ISize{1024, 768}) *
384  Matrix::MakeTranslation({50.0f, 50.0f, 0.0f});
385  VS::BindUniformBuffer(
386  cmd, r2t_pass->GetTransientsBuffer().EmplaceUniform(uniforms));
387  ASSERT_TRUE(r2t_pass->AddCommand(std::move(cmd)));
388  ASSERT_TRUE(r2t_pass->EncodeCommands());
389 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::TextureDescriptor::format, impeller::Attachment::IsValid(), impeller::kClear, impeller::kCount1, impeller::kDeviceTransient, impeller::kDontCare, impeller::kHostVisible, impeller::kRenderTarget, impeller::kS8UInt, impeller::kStore, impeller::Attachment::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeTranslation(), impeller::TextureDescriptor::mip_count, impeller::Command::pipeline, impeller::RenderTarget::SetColorAttachment(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::RenderTarget::SetStencilAttachment(), impeller::TextureDescriptor::size, impeller::TextureDescriptor::storage_mode, impeller::Attachment::store_action, impeller::Attachment::texture, and impeller::TextureDescriptor::usage.

◆ TEST_P() [299/317]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexBehavior   
)

Definition at line 1031 of file renderer_unittests.cc.

1031  {
1032  using VS = BoxFadeVertexShader;
1033 
1034  // Do not create any index buffer if no indices were provided.
1035  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1036  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::kNone);
1037 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::kNone.

◆ TEST_P() [300/317]

impeller::testing::TEST_P ( RendererTest  ,
DefaultIndexSize   
)

Definition at line 1021 of file renderer_unittests.cc.

1021  {
1022  using VS = BoxFadeVertexShader;
1023 
1024  // Default to 16bit index buffer size, as this is a reasonable default and
1025  // supported on all backends without extensions.
1026  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1027  vertex_builder.AppendIndex(0u);
1028  ASSERT_EQ(vertex_builder.GetIndexType(), IndexType::k16bit);
1029 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexType(), and impeller::k16bit.

◆ TEST_P() [301/317]

impeller::testing::TEST_P ( RendererTest  ,
InactiveUniforms   
)

Definition at line 938 of file renderer_unittests.cc.

938  {
939  using VS = InactiveUniformsVertexShader;
940  using FS = InactiveUniformsFragmentShader;
941 
942  auto context = GetContext();
943  auto pipeline_descriptor =
944  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
945  ASSERT_TRUE(pipeline_descriptor.has_value());
946  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
947  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
948  auto pipeline =
949  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
950  ASSERT_TRUE(pipeline && pipeline->IsValid());
951 
952  SinglePassCallback callback = [&](RenderPass& pass) {
953  auto size = pass.GetRenderTargetSize();
954 
955  Command cmd;
956  cmd.pipeline = pipeline;
957  DEBUG_COMMAND_INFO(cmd, "Inactive Uniform");
958  VertexBufferBuilder<VS::PerVertexData> builder;
959  builder.AddVertices({{Point()},
960  {Point(0, size.height)},
961  {Point(size.width, 0)},
962  {Point(size.width, 0)},
963  {Point(0, size.height)},
964  {Point(size.width, size.height)}});
965  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
966 
967  VS::FrameInfo frame_info;
968  frame_info.mvp =
969  Matrix::MakeOrthographic(size) * Matrix::MakeScale(GetContentScale());
970  VS::BindFrameInfo(cmd,
971  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
972 
973  FS::FragInfo fs_uniform = {.unused_color = Color::Red(),
974  .color = Color::Green()};
975  FS::BindFragInfo(cmd,
976  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
977 
978  pass.AddCommand(std::move(cmd));
979  return true;
980  };
981  OpenPlaygroundHere(callback);
982 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::Color::Green(), impeller::kCount4, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, and impeller::Color::Red().

◆ TEST_P() [302/317]

impeller::testing::TEST_P ( RendererTest  ,
StencilMask   
)

Definition at line 1109 of file renderer_unittests.cc.

1109  {
1110  using VS = BoxFadeVertexShader;
1111  using FS = BoxFadeFragmentShader;
1112  auto context = GetContext();
1113  ASSERT_TRUE(context);
1114  using BoxFadePipelineBuilder = PipelineBuilder<VS, FS>;
1115  auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1116  ASSERT_TRUE(desc.has_value());
1117 
1118  // Vertex buffer.
1119  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1120  vertex_builder.SetLabel("Box");
1121  vertex_builder.AddVertices({
1122  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1123  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1124  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1125  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1126  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1127  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1128  });
1129  auto vertex_buffer =
1130  vertex_builder.CreateVertexBuffer(*context->GetResourceAllocator());
1131  ASSERT_TRUE(vertex_buffer);
1132 
1133  desc->SetSampleCount(SampleCount::kCount4);
1134  desc->SetStencilAttachmentDescriptors(std::nullopt);
1135 
1136  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
1137  auto boston = CreateTextureForFixture("boston.jpg");
1138  ASSERT_TRUE(bridge && boston);
1139  auto sampler = context->GetSamplerLibrary()->GetSampler({});
1140  ASSERT_TRUE(sampler);
1141 
1142  static bool mirror = false;
1143  static int stencil_reference_write = 0xFF;
1144  static int stencil_reference_read = 0x1;
1145  std::vector<uint8_t> stencil_contents;
1146  static int last_stencil_contents_reference_value = 0;
1147  static int current_front_compare =
1148  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1149  static int current_back_compare =
1150  CompareFunctionUI().IndexOf(CompareFunction::kLessEqual);
1151  Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
1152  auto buffer = context->CreateCommandBuffer();
1153  if (!buffer) {
1154  return false;
1155  }
1156  buffer->SetLabel("Playground Command Buffer");
1157 
1158  {
1159  // Configure the stencil attachment for the test.
1160  RenderTarget::AttachmentConfig stencil_config;
1161  stencil_config.load_action = LoadAction::kLoad;
1162  stencil_config.store_action = StoreAction::kDontCare;
1163  stencil_config.storage_mode = StorageMode::kHostVisible;
1164  auto render_target_allocator =
1165  RenderTargetAllocator(context->GetResourceAllocator());
1166  render_target.SetupStencilAttachment(*context, render_target_allocator,
1167  render_target.GetRenderTargetSize(),
1168  true, "stencil", stencil_config);
1169  // Fill the stencil buffer with an checkerboard pattern.
1170  const auto target_width = render_target.GetRenderTargetSize().width;
1171  const auto target_height = render_target.GetRenderTargetSize().height;
1172  const size_t target_size = target_width * target_height;
1173  if (stencil_contents.size() != target_size ||
1174  last_stencil_contents_reference_value != stencil_reference_write) {
1175  stencil_contents.resize(target_size);
1176  last_stencil_contents_reference_value = stencil_reference_write;
1177  for (int y = 0; y < target_height; y++) {
1178  for (int x = 0; x < target_width; x++) {
1179  const auto index = y * target_width + x;
1180  const auto kCheckSize = 64;
1181  const auto value =
1182  (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1183  stencil_reference_write;
1184  stencil_contents[index] = value;
1185  }
1186  }
1187  }
1188  if (!render_target.GetStencilAttachment()->texture->SetContents(
1189  stencil_contents.data(), stencil_contents.size(), 0, false)) {
1190  VALIDATION_LOG << "Could not upload stencil contents to device memory";
1191  return false;
1192  }
1193  auto pass = buffer->CreateRenderPass(render_target);
1194  if (!pass) {
1195  return false;
1196  }
1197  pass->SetLabel("Stencil Buffer");
1198  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1199  ImGui::SliderInt("Stencil Write Value", &stencil_reference_write, 0,
1200  0xFF);
1201  ImGui::SliderInt("Stencil Compare Value", &stencil_reference_read, 0,
1202  0xFF);
1203  ImGui::Checkbox("Back face mode", &mirror);
1204  ImGui::ListBox("Front face compare function", &current_front_compare,
1205  CompareFunctionUI().labels(), CompareFunctionUI().size());
1206  ImGui::ListBox("Back face compare function", &current_back_compare,
1207  CompareFunctionUI().labels(), CompareFunctionUI().size());
1208  ImGui::End();
1209 
1210  StencilAttachmentDescriptor front;
1211  front.stencil_compare =
1212  CompareFunctionUI().FunctionOf(current_front_compare);
1213  StencilAttachmentDescriptor back;
1214  back.stencil_compare =
1215  CompareFunctionUI().FunctionOf(current_back_compare);
1216  desc->SetStencilAttachmentDescriptors(front, back);
1217  auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1218 
1219  assert(pipeline && pipeline->IsValid());
1220 
1221  Command cmd;
1222  DEBUG_COMMAND_INFO(cmd, "Box");
1223  cmd.pipeline = pipeline;
1224  cmd.stencil_reference = stencil_reference_read;
1225 
1226  cmd.BindVertices(vertex_buffer);
1227 
1228  VS::UniformBuffer uniforms;
1229  uniforms.mvp = Matrix::MakeOrthographic(pass->GetRenderTargetSize()) *
1230  Matrix::MakeScale(GetContentScale());
1231  if (mirror) {
1232  uniforms.mvp = Matrix::MakeScale(Vector2(-1, 1)) * uniforms.mvp;
1233  }
1234  VS::BindUniformBuffer(
1235  cmd, pass->GetTransientsBuffer().EmplaceUniform(uniforms));
1236 
1237  FS::FrameInfo frame_info;
1238  frame_info.current_time = GetSecondsElapsed();
1239  frame_info.cursor_position = GetCursorPosition();
1240  frame_info.window_size.x = GetWindowSize().width;
1241  frame_info.window_size.y = GetWindowSize().height;
1242 
1243  FS::BindFrameInfo(cmd,
1244  pass->GetTransientsBuffer().EmplaceUniform(frame_info));
1245  FS::BindContents1(cmd, boston, sampler);
1246  FS::BindContents2(cmd, bridge, sampler);
1247  if (!pass->AddCommand(std::move(cmd))) {
1248  return false;
1249  }
1250  pass->EncodeCommands();
1251  }
1252 
1253  if (!buffer->SubmitCommands()) {
1254  return false;
1255  }
1256  return true;
1257  };
1258  OpenPlaygroundHere(callback);
1259 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), CompareFunctionUI(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::testing::CompareFunctionUIData::FunctionOf(), impeller::testing::CompareFunctionUIData::IndexOf(), impeller::kCount4, impeller::kDontCare, impeller::kHostVisible, impeller::kLessEqual, impeller::kLoad, impeller::RenderTarget::AttachmentConfig::load_action, impeller::Matrix::MakeOrthographic(), impeller::Matrix::MakeScale(), impeller::Command::pipeline, impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel(), impeller::StencilAttachmentDescriptor::stencil_compare, impeller::Command::stencil_reference, impeller::RenderTarget::AttachmentConfig::storage_mode, impeller::RenderTarget::AttachmentConfig::store_action, and VALIDATION_LOG.

◆ TEST_P() [303/317]

impeller::testing::TEST_P ( RendererTest  ,
TheImpeller   
)

Definition at line 820 of file renderer_unittests.cc.

820  {
821  using VS = ImpellerVertexShader;
822  using FS = ImpellerFragmentShader;
823 
824  auto context = GetContext();
825  auto pipeline_descriptor =
826  PipelineBuilder<VS, FS>::MakeDefaultPipelineDescriptor(*context);
827  ASSERT_TRUE(pipeline_descriptor.has_value());
828  pipeline_descriptor->SetSampleCount(SampleCount::kCount4);
829  pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
830  auto pipeline =
831  context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
832  ASSERT_TRUE(pipeline && pipeline->IsValid());
833 
834  auto blue_noise = CreateTextureForFixture("blue_noise.png");
835  SamplerDescriptor noise_sampler_desc;
836  noise_sampler_desc.width_address_mode = SamplerAddressMode::kRepeat;
837  noise_sampler_desc.height_address_mode = SamplerAddressMode::kRepeat;
838  auto noise_sampler =
839  context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
840 
841  auto cube_map = CreateTextureCubeForFixture(
842  {"table_mountain_px.png", "table_mountain_nx.png",
843  "table_mountain_py.png", "table_mountain_ny.png",
844  "table_mountain_pz.png", "table_mountain_nz.png"});
845  auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({});
846 
847  SinglePassCallback callback = [&](RenderPass& pass) {
848  auto size = pass.GetRenderTargetSize();
849 
850  Command cmd;
851  cmd.pipeline = pipeline;
852  DEBUG_COMMAND_INFO(cmd, "Impeller SDF scene");
853  VertexBufferBuilder<VS::PerVertexData> builder;
854  builder.AddVertices({{Point()},
855  {Point(0, size.height)},
856  {Point(size.width, 0)},
857  {Point(size.width, 0)},
858  {Point(0, size.height)},
859  {Point(size.width, size.height)}});
860  cmd.BindVertices(builder.CreateVertexBuffer(pass.GetTransientsBuffer()));
861 
862  VS::FrameInfo frame_info;
863  frame_info.mvp = Matrix::MakeOrthographic(size);
864  VS::BindFrameInfo(cmd,
865  pass.GetTransientsBuffer().EmplaceUniform(frame_info));
866 
867  FS::FragInfo fs_uniform;
868  fs_uniform.texture_size = Point(size);
869  fs_uniform.time = GetSecondsElapsed();
870  FS::BindFragInfo(cmd,
871  pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
872  FS::BindBlueNoise(cmd, blue_noise, noise_sampler);
873  FS::BindCubeMap(cmd, cube_map, cube_map_sampler);
874 
875  pass.AddCommand(std::move(cmd));
876  return true;
877  };
878  OpenPlaygroundHere(callback);
879 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::Command::BindVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::CreateVertexBuffer(), DEBUG_COMMAND_INFO, impeller::SamplerDescriptor::height_address_mode, impeller::kCount4, impeller::kRepeat, impeller::PipelineBuilder< VertexShader_, FragmentShader_ >::MakeDefaultPipelineDescriptor(), impeller::Matrix::MakeOrthographic(), impeller::Command::pipeline, and impeller::SamplerDescriptor::width_address_mode.

◆ TEST_P() [304/317]

impeller::testing::TEST_P ( RendererTest  ,
VertexBufferBuilder   
)

Definition at line 1039 of file renderer_unittests.cc.

1039  {
1040  // Does not create index buffer if one is provided.
1041  using VS = BoxFadeVertexShader;
1042  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
1043  vertex_builder.SetLabel("Box");
1044  vertex_builder.AddVertices({
1045  {{100, 100, 0.0}, {0.0, 0.0}}, // 1
1046  {{800, 100, 0.0}, {1.0, 0.0}}, // 2
1047  {{800, 800, 0.0}, {1.0, 1.0}}, // 3
1048  {{100, 800, 0.0}, {0.0, 1.0}}, // 4
1049  });
1050  vertex_builder.AppendIndex(0);
1051  vertex_builder.AppendIndex(1);
1052  vertex_builder.AppendIndex(2);
1053  vertex_builder.AppendIndex(1);
1054  vertex_builder.AppendIndex(2);
1055  vertex_builder.AppendIndex(3);
1056 
1057  ASSERT_EQ(vertex_builder.GetIndexCount(), 6u);
1058  ASSERT_EQ(vertex_builder.GetVertexCount(), 4u);
1059 }

References impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AddVertices(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::AppendIndex(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetIndexCount(), impeller::VertexBufferBuilder< VertexType_, IndexType_ >::GetVertexCount(), and impeller::VertexBufferBuilder< VertexType_, IndexType_ >::SetLabel().

◆ TEST_P() [305/317]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanCreatePipelineFromRuntimeStage   
)

Definition at line 226 of file runtime_stage_unittests.cc.

226  {
227  if (GetParam() != PlaygroundBackend::kMetal) {
228  GTEST_SKIP_("Skipped: https://github.com/flutter/flutter/issues/105538");
229  }
230  auto stage = OpenAssetAsRuntimeStage("ink_sparkle.frag.iplr");
231  ASSERT_NE(stage, nullptr);
232  ASSERT_TRUE(RegisterStage(*stage));
233  auto library = GetContext()->GetShaderLibrary();
234  using VS = SimpleVertexShader;
235  PipelineDescriptor desc;
236  desc.SetLabel("Runtime Stage InkSparkle");
237  desc.AddStageEntrypoint(
238  library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex));
239  desc.AddStageEntrypoint(
240  library->GetFunction(stage->GetEntrypoint(), ShaderStage::kFragment));
241  auto vertex_descriptor = std::make_shared<VertexDescriptor>();
242  vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
243  VS::kInterleavedBufferLayout);
244 
245  desc.SetVertexDescriptor(std::move(vertex_descriptor));
246  ColorAttachmentDescriptor color0;
247  color0.format = GetContext()->GetCapabilities()->GetDefaultColorFormat();
248  StencilAttachmentDescriptor stencil0;
249  stencil0.stencil_compare = CompareFunction::kEqual;
250  desc.SetColorAttachmentDescriptor(0u, color0);
251  desc.SetStencilAttachmentDescriptors(stencil0);
252  const auto stencil_fmt =
253  GetContext()->GetCapabilities()->GetDefaultStencilFormat();
254  desc.SetStencilPixelFormat(stencil_fmt);
255  auto pipeline = GetContext()->GetPipelineLibrary()->GetPipeline(desc).Get();
256  ASSERT_NE(pipeline, nullptr);
257 }

References impeller::PipelineDescriptor::AddStageEntrypoint(), impeller::ColorAttachmentDescriptor::format, impeller::kEqual, impeller::kFragment, impeller::kMetal, impeller::kVertex, impeller::PipelineDescriptor::SetColorAttachmentDescriptor(), impeller::PipelineDescriptor::SetLabel(), impeller::PipelineDescriptor::SetStencilAttachmentDescriptors(), impeller::PipelineDescriptor::SetStencilPixelFormat(), impeller::PipelineDescriptor::SetVertexDescriptor(), and impeller::StencilAttachmentDescriptor::stencil_compare.

◆ TEST_P() [306/317]

impeller::testing::TEST_P ( RuntimeStageTest  ,
CanRegisterStage   
)

Definition at line 189 of file runtime_stage_unittests.cc.

189  {
190  if (GetParam() != PlaygroundBackend::kMetal) {
191  GTEST_SKIP_("Skipped: https://github.com/flutter/flutter/issues/105538");
192  }
193  auto fixture =
194  flutter::testing::OpenFixtureAsMapping("ink_sparkle.frag.iplr");
195  ASSERT_TRUE(fixture);
196  ASSERT_GT(fixture->GetSize(), 0u);
197  RuntimeStage stage(std::move(fixture));
198  ASSERT_TRUE(stage.IsValid());
199  std::promise<bool> registration;
200  auto future = registration.get_future();
201  auto library = GetContext()->GetShaderLibrary();
202  library->RegisterFunction(
203  stage.GetEntrypoint(), //
204  ToShaderStage(stage.GetShaderStage()), //
205  stage.GetCodeMapping(), //
206  fml::MakeCopyable([reg = std::move(registration)](bool result) mutable {
207  reg.set_value(result);
208  }));
209  ASSERT_TRUE(future.get());
210  {
211  auto function =
212  library->GetFunction(stage.GetEntrypoint(), ShaderStage::kFragment);
213  ASSERT_NE(function, nullptr);
214  }
215 
216  // Check if unregistering works.
217 
218  library->UnregisterFunction(stage.GetEntrypoint(), ShaderStage::kFragment);
219  {
220  auto function =
221  library->GetFunction(stage.GetEntrypoint(), ShaderStage::kFragment);
222  ASSERT_EQ(function, nullptr);
223  }
224 }

References impeller::RuntimeStage::GetCodeMapping(), impeller::RuntimeStage::GetEntrypoint(), impeller::RuntimeStage::GetShaderStage(), impeller::RuntimeStage::IsValid(), impeller::kFragment, impeller::kMetal, and impeller::ToShaderStage().

◆ TEST_P() [307/317]

impeller::testing::TEST_P ( TypographerTest  ,
CanConvertTextBlob   
)

Definition at line 38 of file typographer_unittests.cc.

38  {
39  SkFont font;
40  auto blob = SkTextBlob::MakeFromString(
41  "the quick brown fox jumped over the lazy dog.", font);
42  ASSERT_TRUE(blob);
43  auto frame = MakeTextFrameFromTextBlobSkia(blob);
44  ASSERT_EQ(frame->GetRunCount(), 1u);
45  for (const auto& run : frame->GetRuns()) {
46  ASSERT_TRUE(run.IsValid());
47  ASSERT_EQ(run.GetGlyphCount(), 45u);
48  }
49 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [308/317]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateGlyphAtlas   
)

Definition at line 56 of file typographer_unittests.cc.

56  {
57  auto context = TypographerContextSkia::Make();
58  auto atlas_context = context->CreateGlyphAtlasContext();
59  ASSERT_TRUE(context && context->IsValid());
60  SkFont sk_font;
61  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
62  ASSERT_TRUE(blob);
63  auto atlas = CreateGlyphAtlas(
64  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
65  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
66  ASSERT_NE(atlas, nullptr);
67  ASSERT_NE(atlas->GetTexture(), nullptr);
68  ASSERT_EQ(atlas->GetType(), GlyphAtlas::Type::kAlphaBitmap);
69  ASSERT_EQ(atlas->GetGlyphCount(), 4llu);
70 
71  std::optional<impeller::ScaledFont> first_scaled_font;
72  std::optional<impeller::Glyph> first_glyph;
73  Rect first_rect;
74  atlas->IterateGlyphs([&](const ScaledFont& scaled_font, const Glyph& glyph,
75  const Rect& rect) -> bool {
76  first_scaled_font = scaled_font;
77  first_glyph = glyph;
78  first_rect = rect;
79  return false;
80  });
81 
82  ASSERT_TRUE(first_scaled_font.has_value());
83  ASSERT_TRUE(atlas
84  ->FindFontGlyphBounds(
85  {first_scaled_font.value(), first_glyph.value()})
86  .has_value());
87 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [309/317]

impeller::testing::TEST_P ( TypographerTest  ,
CanCreateRenderContext   
)

Definition at line 51 of file typographer_unittests.cc.

51  {
52  auto context = TypographerContextSkia::Make();
53  ASSERT_TRUE(context && context->IsValid());
54 }

References impeller::TypographerContextSkia::Make().

◆ TEST_P() [310/317]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasIsRecycledIfUnchanged   
)

Definition at line 158 of file typographer_unittests.cc.

158  {
159  auto context = TypographerContextSkia::Make();
160  auto atlas_context = context->CreateGlyphAtlasContext();
161  ASSERT_TRUE(context && context->IsValid());
162  SkFont sk_font;
163  auto blob = SkTextBlob::MakeFromString("spooky skellingtons", sk_font);
164  ASSERT_TRUE(blob);
165  auto atlas = CreateGlyphAtlas(
166  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
167  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
168  ASSERT_NE(atlas, nullptr);
169  ASSERT_NE(atlas->GetTexture(), nullptr);
170  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
171 
172  // now attempt to re-create an atlas with the same text blob.
173 
174  auto next_atlas = CreateGlyphAtlas(
175  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
176  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
177  ASSERT_EQ(atlas, next_atlas);
178  ASSERT_EQ(atlas_context->GetGlyphAtlas(), atlas);
179 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [311/317]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecreatedIfTypeChanges   
)

Definition at line 258 of file typographer_unittests.cc.

258  {
259  auto context = TypographerContextSkia::Make();
260  auto atlas_context = context->CreateGlyphAtlasContext();
261  ASSERT_TRUE(context && context->IsValid());
262  SkFont sk_font;
263  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
264  ASSERT_TRUE(blob);
265  auto atlas = CreateGlyphAtlas(
266  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
267  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
268  auto old_packer = atlas_context->GetRectPacker();
269 
270  ASSERT_NE(atlas, nullptr);
271  ASSERT_NE(atlas->GetTexture(), nullptr);
272  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
273 
274  auto* first_texture = atlas->GetTexture().get();
275 
276  // now create a new glyph atlas with an identical blob,
277  // but change the type.
278 
279  auto blob2 = SkTextBlob::MakeFromString("spooky 1", sk_font);
280  auto next_atlas = CreateGlyphAtlas(
281  *GetContext(), context.get(), GlyphAtlas::Type::kColorBitmap, 1.0f,
282  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
283  ASSERT_NE(atlas, next_atlas);
284  auto* second_texture = next_atlas->GetTexture().get();
285 
286  auto new_packer = atlas_context->GetRectPacker();
287 
288  ASSERT_NE(second_texture, first_texture);
289  ASSERT_NE(old_packer, new_packer);
290 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [312/317]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasTextureIsRecycledIfUnchanged   
)

Definition at line 225 of file typographer_unittests.cc.

225  {
226  auto context = TypographerContextSkia::Make();
227  auto atlas_context = context->CreateGlyphAtlasContext();
228  ASSERT_TRUE(context && context->IsValid());
229  SkFont sk_font;
230  auto blob = SkTextBlob::MakeFromString("spooky 1", sk_font);
231  ASSERT_TRUE(blob);
232  auto atlas = CreateGlyphAtlas(
233  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
234  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
235  auto old_packer = atlas_context->GetRectPacker();
236 
237  ASSERT_NE(atlas, nullptr);
238  ASSERT_NE(atlas->GetTexture(), nullptr);
239  ASSERT_EQ(atlas, atlas_context->GetGlyphAtlas());
240 
241  auto* first_texture = atlas->GetTexture().get();
242 
243  // Now create a new glyph atlas with a nearly identical blob.
244 
245  auto blob2 = SkTextBlob::MakeFromString("spooky 2", sk_font);
246  auto next_atlas = CreateGlyphAtlas(
247  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
248  atlas_context, *MakeTextFrameFromTextBlobSkia(blob2));
249  ASSERT_EQ(atlas, next_atlas);
250  auto* second_texture = next_atlas->GetTexture().get();
251 
252  auto new_packer = atlas_context->GetRectPacker();
253 
254  ASSERT_EQ(second_texture, first_texture);
255  ASSERT_EQ(old_packer, new_packer);
256 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [313/317]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithLotsOfdUniqueGlyphSize   
)

Definition at line 181 of file typographer_unittests.cc.

181  {
182  auto context = TypographerContextSkia::Make();
183  auto atlas_context = context->CreateGlyphAtlasContext();
184  ASSERT_TRUE(context && context->IsValid());
185 
186  const char* test_string =
187  "QWERTYUIOPASDFGHJKLZXCVBNMqewrtyuiopasdfghjklzxcvbnm,.<>[]{};':"
188  "2134567890-=!@#$%^&*()_+"
189  "œ∑´®†¥¨ˆøπ““‘‘åß∂ƒ©˙∆˚¬…æ≈ç√∫˜µ≤≥≥≥≥÷¡™£¢∞§¶•ªº–≠⁄€‹›fifl‡°·‚—±Œ„´‰Á¨Ø∏”’/"
190  "* Í˝ */¸˛Ç◊ı˜Â¯˘¿";
191 
192  SkFont sk_font;
193  auto blob = SkTextBlob::MakeFromString(test_string, sk_font);
194  ASSERT_TRUE(blob);
195 
196  FontGlyphMap font_glyph_map;
197  size_t size_count = 8;
198  for (size_t index = 0; index < size_count; index += 1) {
199  MakeTextFrameFromTextBlobSkia(blob)->CollectUniqueFontGlyphPairs(
200  font_glyph_map, 0.6 * index);
201  };
202  auto atlas =
203  context->CreateGlyphAtlas(*GetContext(), GlyphAtlas::Type::kAlphaBitmap,
204  std::move(atlas_context), font_glyph_map);
205  ASSERT_NE(atlas, nullptr);
206  ASSERT_NE(atlas->GetTexture(), nullptr);
207 
208  std::set<uint16_t> unique_glyphs;
209  std::vector<uint16_t> total_glyphs;
210  atlas->IterateGlyphs(
211  [&](const ScaledFont& scaled_font, const Glyph& glyph, const Rect& rect) {
212  unique_glyphs.insert(glyph.index);
213  total_glyphs.push_back(glyph.index);
214  return true;
215  });
216 
217  EXPECT_EQ(unique_glyphs.size() * size_count, atlas->GetGlyphCount());
218  EXPECT_EQ(total_glyphs.size(), atlas->GetGlyphCount());
219 
220  EXPECT_TRUE(atlas->GetGlyphCount() > 0);
221  EXPECT_TRUE(atlas->GetTexture()->GetSize().width > 0);
222  EXPECT_TRUE(atlas->GetTexture()->GetSize().height > 0);
223 }

References impeller::Glyph::index, impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [314/317]

impeller::testing::TEST_P ( TypographerTest  ,
GlyphAtlasWithOddUniqueGlyphSize   
)

Definition at line 141 of file typographer_unittests.cc.

141  {
142  auto context = TypographerContextSkia::Make();
143  auto atlas_context = context->CreateGlyphAtlasContext();
144  ASSERT_TRUE(context && context->IsValid());
145  SkFont sk_font;
146  auto blob = SkTextBlob::MakeFromString("AGH", sk_font);
147  ASSERT_TRUE(blob);
148  auto atlas = CreateGlyphAtlas(
149  *GetContext(), context.get(), GlyphAtlas::Type::kAlphaBitmap, 1.0f,
150  atlas_context, *MakeTextFrameFromTextBlobSkia(blob));
151  ASSERT_NE(atlas, nullptr);
152  ASSERT_NE(atlas->GetTexture(), nullptr);
153 
154  ASSERT_EQ(atlas->GetTexture()->GetSize().width,
155  atlas->GetTexture()->GetSize().height);
156 }

References CreateGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::TypographerContextSkia::Make(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [315/317]

impeller::testing::TEST_P ( TypographerTest  ,
LazyAtlasTracksColor   
)

Definition at line 104 of file typographer_unittests.cc.

104  {
105 #if FML_OS_MACOSX
106  auto mapping = OpenFixtureAsSkData("Apple Color Emoji.ttc");
107 #else
108  auto mapping = OpenFixtureAsSkData("NotoColorEmoji.ttf");
109 #endif
110  ASSERT_TRUE(mapping);
111  SkFont emoji_font(SkTypeface::MakeFromData(mapping), 50.0);
112  SkFont sk_font;
113 
114  auto blob = SkTextBlob::MakeFromString("hello", sk_font);
115  ASSERT_TRUE(blob);
116  auto frame = MakeTextFrameFromTextBlobSkia(blob);
117 
118  ASSERT_FALSE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
119 
120  LazyGlyphAtlas lazy_atlas(TypographerContextSkia::Make());
121 
122  lazy_atlas.AddTextFrame(*frame, 1.0f);
123 
125  SkTextBlob::MakeFromString("😀 ", emoji_font));
126 
127  ASSERT_TRUE(frame->GetAtlasType() == GlyphAtlas::Type::kColorBitmap);
128 
129  lazy_atlas.AddTextFrame(*frame, 1.0f);
130 
131  // Creates different atlases for color and alpha bitmap.
132  auto color_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
133  *GetContext(), GlyphAtlas::Type::kColorBitmap);
134 
135  auto bitmap_atlas = lazy_atlas.CreateOrGetGlyphAtlas(
136  *GetContext(), GlyphAtlas::Type::kAlphaBitmap);
137 
138  ASSERT_FALSE(color_atlas == bitmap_atlas);
139 }

References impeller::LazyGlyphAtlas::AddTextFrame(), impeller::LazyGlyphAtlas::CreateOrGetGlyphAtlas(), impeller::GlyphAtlas::kAlphaBitmap, impeller::GlyphAtlas::kColorBitmap, impeller::TypographerContextSkia::Make(), impeller::MakeTextFrameFromTextBlobSkia(), and OpenFixtureAsSkData().

◆ TEST_P() [316/317]

impeller::testing::TEST_P ( TypographerTest  ,
MaybeHasOverlapping   
)

Definition at line 292 of file typographer_unittests.cc.

292  {
293  sk_sp<SkFontMgr> font_mgr = SkFontMgr::RefDefault();
294  sk_sp<SkTypeface> typeface =
295  font_mgr->matchFamilyStyle("Arial", SkFontStyle::Normal());
296  SkFont sk_font(typeface, 0.5f);
297 
298  auto frame =
299  MakeTextFrameFromTextBlobSkia(SkTextBlob::MakeFromString("1", sk_font));
300  // Single character has no overlapping
301  ASSERT_FALSE(frame->MaybeHasOverlapping());
302 
303  auto frame_2 = MakeTextFrameFromTextBlobSkia(
304  SkTextBlob::MakeFromString("123456789", sk_font));
305  ASSERT_FALSE(frame_2->MaybeHasOverlapping());
306 }

References impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [317/317]

impeller::testing::TEST_P ( TypographerTest  ,
RectanglePackerAddsNonoverlapingRectangles   
)

Definition at line 308 of file typographer_unittests.cc.

308  {
309  auto packer = RectanglePacker::Factory(200, 100);
310  ASSERT_NE(packer, nullptr);
311  ASSERT_EQ(packer->percentFull(), 0);
312 
313  const SkIRect packer_area = SkIRect::MakeXYWH(0, 0, 200, 100);
314 
315  IPoint16 first_output = {-1, -1}; // Fill with sentinel values
316  ASSERT_TRUE(packer->addRect(20, 20, &first_output));
317  // Make sure the rectangle is placed such that it is inside the bounds of
318  // the packer's area.
319  const SkIRect first_rect =
320  SkIRect::MakeXYWH(first_output.x(), first_output.y(), 20, 20);
321  ASSERT_TRUE(SkIRect::Intersects(packer_area, first_rect));
322 
323  // Initial area was 200 x 100 = 20_000
324  // We added 20x20 = 400. 400 / 20_000 == 0.02 == 2%
325  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.02));
326 
327  IPoint16 second_output = {-1, -1};
328  ASSERT_TRUE(packer->addRect(140, 90, &second_output));
329  const SkIRect second_rect =
330  SkIRect::MakeXYWH(second_output.x(), second_output.y(), 140, 90);
331  // Make sure the rectangle is placed such that it is inside the bounds of
332  // the packer's area but not in the are of the first rectangle.
333  ASSERT_TRUE(SkIRect::Intersects(packer_area, second_rect));
334  ASSERT_FALSE(SkIRect::Intersects(first_rect, second_rect));
335 
336  // We added another 90 x 140 = 12_600 units, now taking us to 13_000
337  // 13_000 / 20_000 == 0.65 == 65%
338  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.65));
339 
340  // There's enough area to add this rectangle, but no space big enough for
341  // the 50 units of width.
342  IPoint16 output;
343  ASSERT_FALSE(packer->addRect(50, 50, &output));
344  // Should be unchanged.
345  ASSERT_TRUE(flutter::testing::NumberNear(packer->percentFull(), 0.65));
346 
347  packer->reset();
348  // Should be empty now.
349  ASSERT_EQ(packer->percentFull(), 0);
350 }

References impeller::RectanglePacker::Factory(), NumberNear(), impeller::IPoint16::x(), and impeller::IPoint16::y().

◆ toColor()

flutter::DlColor impeller::testing::toColor ( const float *  components)

Definition at line 40 of file dl_unittests.cc.

40  {
41  return flutter::DlColor(Color::ToIColor(
42  Color(components[0], components[1], components[2], components[3])));
43 }

References impeller::Color::ToIColor().

Referenced by TEST_P().

Variable Documentation

◆ golden_cubic_and_quad_points

std::vector<Point> impeller::testing::golden_cubic_and_quad_points

Definition at line 15 of file golden_paths.h.

Referenced by TEST_P().

◆ LastSample

int64_t impeller::testing::LastSample = 0
static

Definition at line 20 of file archivist_unittests.cc.

impeller::BlendMode
BlendMode
Definition: color.h:57
NumberNear
bool NumberNear(double a, double b)
Definition: geometry_asserts.h:17
ASSERT_COLOR_NEAR
#define ASSERT_COLOR_NEAR(a, b)
Definition: geometry_asserts.h:155
impeller::kFloat
@ kFloat
Definition: runtime_types.h:24
impeller::OptionsFromPass
ContentContextOptions OptionsFromPass(const RenderPass &pass)
Definition: contents.cc:20
impeller::k1OverSqrt2
constexpr float k1OverSqrt2
Definition: constants.h:49
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:31
impeller::testing::CompareFunctionUI
static const CompareFunctionUIData & CompareFunctionUI()
Definition: renderer_unittests.cc:1104
impeller::BlendModeToString
const char * BlendModeToString(BlendMode blend_mode)
Definition: color.cc:47
impeller::TextureUsageMask
uint64_t TextureUsageMask
Definition: formats.h:274
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::testing::RenderTextInCanvasSkia
bool RenderTextInCanvasSkia(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
Definition: aiks_unittests.cc:1303
impeller::TPoint::Ceil
constexpr TPoint Ceil() const
Definition: point.h:189
impeller::testing::CompareFunctionUIData::IndexOf
int IndexOf(CompareFunction func) const
Definition: renderer_unittests.cc:1087
impeller::testing::CanRenderSweepGradientWithDithering
static void CanRenderSweepGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_unittests.cc:480
impeller::skia_conversions::ConvertStops
void ConvertStops(const flutter::DlGradientColorSourceBase *gradient, std::vector< Color > &colors, std::vector< float > &stops)
Convert display list colors + stops into impeller colors and stops, taking care to ensure that the st...
Definition: skia_conversions.cc:192
impeller::testing::CreateMappingFromString
static std::shared_ptr< fml::Mapping > CreateMappingFromString(std::string p_string)
Definition: blobcat_unittests.cc:15
impeller::TPoint::Lerp
constexpr TPoint Lerp(const TPoint &p, Scalar t) const
Definition: point.h:223
impeller::TextureDescriptor::format
PixelFormat format
Definition: texture_descriptor.h:42
impeller::testing::CanRenderConicalGradientWithDithering
static void CanRenderConicalGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_unittests.cc:509
impeller::TPoint::Min
constexpr TPoint Min(const TPoint &p) const
Definition: point.h:179
impeller::TPoint::Round
static constexpr TPoint Round(const TPoint< U > &other)
Definition: point.h:42
impeller::Vector2
Point Vector2
Definition: point.h:310
impeller::SampleCount::kCount1
@ kCount1
impeller::kPi
constexpr float kPi
Definition: constants.h:25
impeller::testing::OpenFixtureAsSkData
static sk_sp< SkData > OpenFixtureAsSkData(const char *fixture_name)
Definition: aiks_unittests.cc:1282
BLEND_MODE_TUPLE
#define BLEND_MODE_TUPLE(blend_mode)
Definition: aiks_unittests.cc:1603
impeller::skia_conversions::ToColor
Color ToColor(const flutter::DlColor &color)
Definition: skia_conversions.cc:142
IMPELLER_PLAYGROUND_POINT
#define IMPELLER_PLAYGROUND_POINT(default_position, radius, color)
Definition: widgets.h:14
impeller::FontGlyphMap
std::unordered_map< ScaledFont, std::unordered_set< Glyph > > FontGlyphMap
Definition: font_glyph_pair.h:28
impeller::TessellateConvex
std::pair< std::vector< Point >, std::vector< uint16_t > > TessellateConvex(Path::Polyline polyline)
Given a convex polyline, create a triangle fan structure.
Definition: geometry.cc:19
impeller::UintPoint32
TPoint< uint32_t > UintPoint32
Definition: point.h:309
impeller::testing::golden_cubic_and_quad_points
std::vector< Point > golden_cubic_and_quad_points
Definition: golden_paths.h:15
impeller::Size
TSize< Scalar > Size
Definition: size.h:135
impeller::StorageMode::kHostVisible
@ kHostVisible
ASSERT_POINT_NEAR
#define ASSERT_POINT_NEAR(a, b)
Definition: geometry_asserts.h:156
impeller::CreateMappingFromAllocation
std::shared_ptr< fml::Mapping > CreateMappingFromAllocation(const std::shared_ptr< Allocation > &allocation)
Definition: allocation.cc:100
ASSERT_VECTOR4_NEAR
#define ASSERT_VECTOR4_NEAR(a, b)
Definition: geometry_asserts.h:158
impeller::MoveTo
void MoveTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:18
impeller::TPoint::Floor
constexpr TPoint Floor() const
Definition: point.h:187
impeller::ToShaderStage
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
Definition: shader_types.h:29
impeller::testing::RenderTextInCanvasSTB
bool RenderTextInCanvasSTB(const std::shared_ptr< Context > &context, Canvas &canvas, const std::string &text, const std::string &font_fixture, TextRenderOptions options={})
Definition: aiks_unittests.cc:1336
impeller::kPiOver2
constexpr float kPiOver2
Definition: constants.h:31
ASSERT_RECT_NEAR
#define ASSERT_RECT_NEAR(a, b)
Definition: geometry_asserts.h:154
impeller::MakeTextFrameSTB
std::shared_ptr< TextFrame > MakeTextFrameSTB(const std::shared_ptr< TypefaceSTB > &typeface_stb, Font::Metrics metrics, const std::string &text)
Definition: text_frame_stb.cc:11
impeller::kPhi
constexpr float kPhi
Definition: constants.h:52
impeller::kColor
@ kColor
Definition: geometry.h:27
impeller::testing::toColor
flutter::DlColor toColor(const float *components)
Definition: dl_unittests.cc:40
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::k2Pi
constexpr float k2Pi
Definition: constants.h:28
impeller::testing::CompareFunctionUIData::FunctionOf
CompareFunction FunctionOf(int index) const
Definition: renderer_unittests.cc:1097
impeller::testing::RGBToYUV
static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2012
impeller::MipFilter
MipFilter
Definition: formats.h:369
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
impeller::testing::GetBlendModeSelection
static BlendModeSelection GetBlendModeSelection()
Definition: aiks_unittests.cc:1610
impeller::IPoint32
TPoint< int32_t > IPoint32
Definition: point.h:308
impeller::ScalarToHalf
constexpr InternalHalf ScalarToHalf(Scalar f)
Convert a scalar to a half precision float.
Definition: half.h:28
impeller::TPoint::Max
constexpr TPoint Max(const TPoint &p) const
Definition: point.h:183
impeller::testing::CanRenderRadialGradientWithDithering
static void CanRenderRadialGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_unittests.cc:453
impeller::MinMagFilter
MinMagFilter
Definition: formats.h:361
impeller::testing::CanRenderLinearGradientWithDithering
static void CanRenderLinearGradientWithDithering(AiksTest *aiks_test, bool use_dithering)
Definition: aiks_unittests.cc:425
impeller::testing::CreateTestYUVTextures
static std::vector< std::shared_ptr< Texture > > CreateTestYUVTextures(Context *context, YUVColorSpace yuv_color_space)
Definition: entity_unittests.cc:2029
_BLEND_MODE_NAME_CHECK
#define _BLEND_MODE_NAME_CHECK(blend_mode)
Definition: geometry_unittests.cc:1561
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
ASSERT_MATRIX_NEAR
#define ASSERT_MATRIX_NEAR(a, b)
Definition: geometry_asserts.h:152
impeller::testing::CreateStringFromMapping
const std::string CreateStringFromMapping(const fml::Mapping &mapping)
Definition: blobcat_unittests.cc:23
impeller::CreateGradientBuffer
GradientData CreateGradientBuffer(const std::vector< Color > &colors, const std::vector< Scalar > &stops)
Populate a vector with the interpolated color bytes for the linear gradient described by colors and s...
Definition: gradient.cc:20
IMPELLER_FOR_EACH_BLEND_MODE
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
Definition: color.h:17
impeller::testing::CreatePassWithRectPath
auto CreatePassWithRectPath(Rect rect, std::optional< Rect > bounds_hint, bool collapse=false)
Definition: entity_unittests.cc:109
impeller::IRect
TRect< int64_t > IRect
Definition: rect.h:307
impeller::MakeTextFrameFromTextBlobSkia
std::shared_ptr< TextFrame > MakeTextFrameFromTextBlobSkia(const sk_sp< SkTextBlob > &blob)
Definition: text_frame_skia.cc:41
ASSERT_QUATERNION_NEAR
#define ASSERT_QUATERNION_NEAR(a, b)
Definition: geometry_asserts.h:153
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:36
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:136
impeller::TextureDescriptor::size
ISize size
Definition: texture_descriptor.h:43
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:60
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:22
impeller::Join
Join
Definition: path.h:23
impeller::IPoint
TPoint< int64_t > IPoint
Definition: point.h:307
ASSERT_VECTOR3_NEAR
#define ASSERT_VECTOR3_NEAR(a, b)
Definition: geometry_asserts.h:157
impeller::ScalarNearlyEqual
constexpr bool ScalarNearlyEqual(Scalar x, Scalar y, Scalar tolerance=kEhCloseEnough)
Definition: scalar.h:27
impeller::YUVColorSpace
YUVColorSpace
Definition: color.h:53
impeller::TextureDescriptor::storage_mode
StorageMode storage_mode
Definition: texture_descriptor.h:40
impeller::TPoint::GetDistance
constexpr Type GetDistance(const TPoint &p) const
Definition: point.h:193
impeller::TextureDescriptor
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...
Definition: texture_descriptor.h:39
impeller::TRect::GetPositive
constexpr TRect GetPositive() const
Get a version of this rectangle that has a non-negative size.
Definition: rect.h:180
impeller::testing::CreateGlyphAtlas
static std::shared_ptr< GlyphAtlas > CreateGlyphAtlas(Context &context, const TypographerContext *typographer_context, GlyphAtlas::Type type, Scalar scale, const std::shared_ptr< GlyphAtlasContext > &atlas_context, const TextFrame &frame)
Definition: typographer_unittests.cc:25
impeller::TPoint::Normalize
constexpr TPoint Normalize() const
Definition: point.h:201
ASSERT_COLOR_BUFFER_NEAR
#define ASSERT_COLOR_BUFFER_NEAR(a, b)
Definition: geometry_asserts.h:161
IMPELLER_PLAYGROUND_LINE
#define IMPELLER_PLAYGROUND_LINE(default_position_a, default_position_b, radius, color_a, color_b)
Definition: widgets.h:55
impeller::kPiOver4
constexpr float kPiOver4
Definition: constants.h:34
impeller::skia_conversions::ToPath
Path ToPath(const SkPath &path, Point shift)
Definition: skia_conversions.cc:49
impeller::Cap
Cap
Definition: path.h:17
ASSERT_ARRAY_4_NEAR
#define ASSERT_ARRAY_4_NEAR(a, b)
Definition: geometry_asserts.h:160