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 (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_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, 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 15 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 2524 of file aiks_unittests.cc.

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

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 2015 of file entity_unittests.cc.

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

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 1998 of file entity_unittests.cc.

1998  {
1999  Vector3 yuv;
2000  switch (yuv_color_space) {
2001  case YUVColorSpace::kBT601FullRange:
2002  yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
2003  yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
2004  yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
2005  break;
2006  case YUVColorSpace::kBT601LimitedRange:
2007  yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
2008  yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
2009  yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
2010  break;
2011  }
2012  return yuv;
2013 }

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

Referenced by CreateTestYUVTextures().

◆ TEST() [1/201]

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

Definition at line 17 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [2/201]

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

Definition at line 23 of file canvas_unittests.cc.

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

References impeller::Canvas::GetCurrentLocalCullingBounds().

◆ TEST() [3/201]

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

Definition at line 276 of file canvas_unittests.cc.

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

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

◆ TEST() [4/201]

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

Definition at line 324 of file canvas_unittests.cc.

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

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

◆ TEST() [5/201]

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

Definition at line 307 of file canvas_unittests.cc.

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

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

◆ TEST() [6/201]

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

Definition at line 290 of file canvas_unittests.cc.

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

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

◆ TEST() [7/201]

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

Definition at line 260 of file canvas_unittests.cc.

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

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

◆ TEST() [8/201]

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

Definition at line 97 of file canvas_unittests.cc.

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

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

◆ TEST() [9/201]

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

Definition at line 64 of file canvas_unittests.cc.

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

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

◆ TEST() [10/201]

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

Definition at line 157 of file canvas_unittests.cc.

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

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

◆ TEST() [11/201]

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

Definition at line 85 of file canvas_unittests.cc.

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

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

◆ TEST() [12/201]

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

Definition at line 145 of file canvas_unittests.cc.

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

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

◆ TEST() [13/201]

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

Definition at line 109 of file canvas_unittests.cc.

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

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

◆ TEST() [14/201]

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

Definition at line 121 of file canvas_unittests.cc.

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

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

◆ TEST() [15/201]

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

Definition at line 133 of file canvas_unittests.cc.

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

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

◆ TEST() [16/201]

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

Definition at line 73 of file canvas_unittests.cc.

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

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

◆ TEST() [17/201]

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

Definition at line 54 of file canvas_unittests.cc.

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

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

◆ TEST() [18/201]

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

Definition at line 179 of file canvas_unittests.cc.

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

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

◆ TEST() [19/201]

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

Definition at line 248 of file canvas_unittests.cc.

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

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

◆ TEST() [20/201]

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

Definition at line 236 of file canvas_unittests.cc.

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

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

◆ TEST() [21/201]

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

Definition at line 200 of file canvas_unittests.cc.

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

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

◆ TEST() [22/201]

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

Definition at line 224 of file canvas_unittests.cc.

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

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

◆ TEST() [23/201]

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

Definition at line 212 of file canvas_unittests.cc.

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

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

◆ TEST() [24/201]

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

Definition at line 188 of file canvas_unittests.cc.

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

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

◆ TEST() [25/201]

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

Definition at line 169 of file canvas_unittests.cc.

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

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

◆ TEST() [26/201]

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

Definition at line 43 of file canvas_unittests.cc.

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

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

◆ TEST() [27/201]

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

Definition at line 32 of file canvas_unittests.cc.

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

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

◆ TEST() [28/201]

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() [29/201]

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() [30/201]

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() [31/201]

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() [32/201]

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() [33/201]

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() [34/201]

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() [35/201]

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() [36/201]

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() [37/201]

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() [38/201]

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() [39/201]

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() [40/201]

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() [41/201]

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() [42/201]

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() [43/201]

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() [44/201]

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() [45/201]

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() [46/201]

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() [47/201]

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() [48/201]

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() [49/201]

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() [50/201]

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() [51/201]

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() [52/201]

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() [53/201]

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() [54/201]

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() [55/201]

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() [56/201]

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() [57/201]

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() [58/201]

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() [59/201]

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() [60/201]

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() [61/201]

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() [62/201]

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() [63/201]

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() [64/201]

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() [65/201]

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() [66/201]

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() [67/201]

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() [68/201]

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() [69/201]

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() [70/201]

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() [71/201]

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() [72/201]

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() [73/201]

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() [74/201]

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() [75/201]

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() [76/201]

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() [77/201]

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() [78/201]

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() [79/201]

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() [80/201]

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() [81/201]

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() [82/201]

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() [83/201]

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() [84/201]

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() [85/201]

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() [86/201]

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() [87/201]

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() [88/201]

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() [89/201]

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() [90/201]

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() [91/201]

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() [92/201]

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() [93/201]

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() [94/201]

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() [95/201]

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() [96/201]

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() [97/201]

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() [98/201]

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() [99/201]

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() [100/201]

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() [101/201]

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() [102/201]

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() [103/201]

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() [104/201]

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() [105/201]

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() [106/201]

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() [107/201]

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() [108/201]

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() [109/201]

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() [110/201]

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() [111/201]

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() [112/201]

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() [113/201]

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() [114/201]

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() [115/201]

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() [116/201]

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() [117/201]

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() [118/201]

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() [119/201]

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() [120/201]

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() [121/201]

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() [122/201]

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() [123/201]

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() [124/201]

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() [125/201]

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() [126/201]

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() [127/201]

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() [128/201]

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() [129/201]

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() [130/201]

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() [131/201]

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() [132/201]

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() [133/201]

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() [134/201]

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() [135/201]

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() [136/201]

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() [137/201]

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() [138/201]

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() [139/201]

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() [140/201]

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() [141/201]

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() [142/201]

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() [143/201]

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() [144/201]

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() [145/201]

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() [146/201]

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() [147/201]

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() [148/201]

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() [149/201]

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() [150/201]

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() [151/201]

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() [152/201]

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() [153/201]

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() [154/201]

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() [155/201]

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() [156/201]

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() [157/201]

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() [158/201]

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() [159/201]

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() [160/201]

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() [161/201]

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() [162/201]

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() [163/201]

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() [164/201]

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() [165/201]

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() [166/201]

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() [167/201]

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() [168/201]

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() [169/201]

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() [170/201]

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() [171/201]

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() [172/201]

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() [173/201]

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() [174/201]

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() [175/201]

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() [176/201]

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() [177/201]

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() [178/201]

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() [179/201]

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() [180/201]

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() [181/201]

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() [182/201]

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() [183/201]

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() [184/201]

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() [185/201]

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() [186/201]

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() [187/201]

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() [188/201]

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() [189/201]

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() [190/201]

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() [191/201]

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() [192/201]

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() [193/201]

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() [194/201]

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() [195/201]

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() [196/201]

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() [197/201]

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() [198/201]

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() [199/201]

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() [200/201]

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() [201/201]

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/314]

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/314]

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

Definition at line 3204 of file aiks_unittests.cc.

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

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

◆ TEST_P() [3/314]

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

Definition at line 3218 of file aiks_unittests.cc.

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

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

◆ TEST_P() [4/314]

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

Definition at line 3233 of file aiks_unittests.cc.

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

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 3045 of file aiks_unittests.cc.

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

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

◆ TEST_P() [12/314]

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

Definition at line 3139 of file aiks_unittests.cc.

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

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

◆ TEST_P() [13/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 2895 of file aiks_unittests.cc.

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

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

◆ TEST_P() [19/314]

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

Definition at line 2911 of file aiks_unittests.cc.

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

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

◆ TEST_P() [20/314]

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

Definition at line 2872 of file aiks_unittests.cc.

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

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

◆ TEST_P() [21/314]

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

Definition at line 2923 of file aiks_unittests.cc.

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

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

◆ TEST_P() [22/314]

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/314]

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

Definition at line 2982 of file aiks_unittests.cc.

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

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

◆ TEST_P() [24/314]

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/314]

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/314]

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/314]

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

Definition at line 530 of file aiks_unittests.cc.

530  {
532 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [28/314]

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

Definition at line 534 of file aiks_unittests.cc.

534  {
536 }

References CanRenderConicalGradientWithDithering().

◆ TEST_P() [29/314]

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/314]

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

Definition at line 2845 of file aiks_unittests.cc.

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

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

◆ TEST_P() [31/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 2960 of file aiks_unittests.cc.

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

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

◆ TEST_P() [37/314]

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

Definition at line 2939 of file aiks_unittests.cc.

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

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

◆ TEST_P() [38/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 445 of file aiks_unittests.cc.

445  {
447 }

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [57/314]

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

Definition at line 449 of file aiks_unittests.cc.

449  {
451 } // namespace

References CanRenderLinearGradientWithDithering().

◆ TEST_P() [58/314]

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/314]

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

Definition at line 2859 of file aiks_unittests.cc.

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

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

◆ TEST_P() [60/314]

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/314]

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 2797 of file aiks_unittests.cc.

2797  {
2798  Canvas canvas;
2799  canvas.debug_options.offscreen_texture_checkerboard = true;
2800 
2801  canvas.DrawPaint({.color = Color::AntiqueWhite()});
2802  canvas.DrawCircle({400, 300}, 200,
2803  {.color = Color::CornflowerBlue().WithAlpha(0.75)});
2804 
2805  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2806  {
2807  canvas.DrawCircle({500, 400}, 200,
2808  {.color = Color::DarkBlue().WithAlpha(0.75)});
2809  canvas.DrawCircle({550, 450}, 200,
2810  {.color = Color::LightCoral().WithAlpha(0.75),
2811  .blend_mode = BlendMode::kLuminosity});
2812  }
2813  canvas.Restore();
2814 
2815  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2816 }

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/314]

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/314]

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/314]

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

Definition at line 472 of file aiks_unittests.cc.

472  {
474 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [65/314]

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

Definition at line 476 of file aiks_unittests.cc.

476  {
478 }

References CanRenderRadialGradientWithDithering().

◆ TEST_P() [66/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 501 of file aiks_unittests.cc.

501  {
503 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [77/314]

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

Definition at line 505 of file aiks_unittests.cc.

505  {
507 }

References CanRenderSweepGradientWithDithering().

◆ TEST_P() [78/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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 2777 of file aiks_unittests.cc.

2777  {
2778  Canvas canvas;
2779  canvas.DrawPaint({.color = Color::Red()});
2780 
2781  // Draw two overlapping subpixel circles.
2782  canvas.SaveLayer({});
2783  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2784  canvas.Restore();
2785  canvas.SaveLayer({});
2786  canvas.DrawCircle({100, 100}, 0.1, {.color = Color::Yellow()});
2787  canvas.Restore();
2788 
2789  canvas.DrawPaint({.color = Color::Green()});
2790 
2791  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2792 }

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

◆ TEST_P() [88/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 3476 of file aiks_unittests.cc.

3476  {
3477  auto capture_context = CaptureContext::MakeAllowlist({"TestDocument"});
3478 
3479  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3480  Canvas canvas;
3481 
3482  capture_context.Rewind();
3483  auto document = capture_context.GetDocument("TestDocument");
3484 
3485  auto color = document.AddColor("Background color", Color::CornflowerBlue());
3486  canvas.DrawPaint({.color = color});
3487 
3488  ImGui::Begin("TestDocument", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
3489  document.GetElement()->properties.Iterate([](CaptureProperty& property) {
3490  property.Invoke({.color = [](CaptureColorProperty& p) {
3491  ImGui::ColorEdit4(p.label.c_str(), reinterpret_cast<float*>(&p.value));
3492  }});
3493  });
3494  ImGui::End();
3495 
3496  return canvas.EndRecordingAsPicture();
3497  };
3498  OpenPlaygroundHere(callback);
3499 }

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

◆ TEST_P() [93/314]

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

Definition at line 3501 of file aiks_unittests.cc.

3501  {
3502  ASSERT_FALSE(GetContext()->capture.IsActive());
3503 }

◆ TEST_P() [94/314]

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

Definition at line 3578 of file aiks_unittests.cc.

3578  {
3579  Canvas canvas;
3580  Paint white;
3581  white.color = Color::Blue();
3582  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3583 
3584  Paint clear;
3585  clear.blend_mode = BlendMode::kClear;
3586 
3587  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3588 }

References impeller::Paint::blend_mode, impeller::Paint::color, impeller::Canvas::DrawCircle(), and impeller::Canvas::DrawRect().

◆ TEST_P() [95/314]

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

Definition at line 3560 of file aiks_unittests.cc.

3560  {
3561  Canvas canvas;
3562  Paint white;
3563  white.color = Color::Blue();
3564  canvas.DrawRect(Rect::MakeXYWH(0, 0, 600.0, 600.0), white);
3565 
3566  Paint clear;
3567  clear.blend_mode = BlendMode::kClear;
3568  clear.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3569  .style = FilterContents::BlurStyle::kNormal,
3570  .sigma = Sigma(20),
3571  };
3572 
3573  canvas.DrawCircle(Point::MakeXY(300.0, 300.0), 200.0, clear);
3574 
3575  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3576 }

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/314]

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  picture.pass->IterateAllElements([&](EntityPass::Element& element) -> bool {
2420  if (auto subpass = std::get_if<std::unique_ptr<EntityPass>>(&element)) {
2421  actual_color = subpass->get()->GetClearColor();
2422  }
2423  // Fail if the first element isn't a subpass.
2424  return true;
2425  });
2426 
2427  ASSERT_TRUE(actual_color.has_value());
2428  if (!actual_color) {
2429  return;
2430  }
2431  ASSERT_EQ(actual_color.value(), Color::BlackTransparent());
2432 }

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

◆ TEST_P() [97/314]

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

Definition at line 3612 of file aiks_unittests.cc.

3612  {
3613  Canvas canvas;
3614  canvas.Scale(GetContentScale());
3615  canvas.DrawRect(Rect::MakeLTRB(200, 200, 300, 300), {.color = Color::Red()});
3616  canvas.SaveLayer({
3617  .image_filter = std::make_shared<MatrixImageFilter>(
3618  Matrix::MakeScale({2, 2, 1}), SamplerDescriptor{}),
3619  });
3620  // Draw a rectangle that would fully cover the parent pass size, but not
3621  // the subpass that it is rendered in.
3622  canvas.DrawRect(Rect::MakeLTRB(0, 0, 400, 400), {.color = Color::Green()});
3623  // Draw a bigger rectangle to force the subpass to be bigger.
3624  canvas.DrawRect(Rect::MakeLTRB(0, 0, 800, 800), {.color = Color::Red()});
3625  canvas.Restore();
3626 
3627  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3628 }

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

◆ TEST_P() [98/314]

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

Definition at line 3461 of file aiks_unittests.cc.

3461  {
3462  Canvas canvas;
3463  canvas.Translate(Point(0, -400));
3464  Paint paint;
3465  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3466  .style = FilterContents::BlurStyle::kNormal,
3467  .sigma = Radius{120 * 3},
3468  };
3469  paint.color = Color::Red();
3470  PathBuilder builder{};
3471  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3472  canvas.DrawPath(builder.TakePath(), paint);
3473  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3474 }

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/314]

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

Definition at line 3441 of file aiks_unittests.cc.

3441  {
3442  auto callback = [&](AiksContext& renderer) -> std::optional<Picture> {
3443  auto point = IMPELLER_PLAYGROUND_POINT(Point(400, 400), 20, Color::Green());
3444 
3445  Canvas canvas;
3446  canvas.Translate(point - Point(400, 400));
3447  Paint paint;
3448  paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{
3449  .style = FilterContents::BlurStyle::kNormal,
3450  .sigma = Radius{120 * 3},
3451  };
3452  paint.color = Color::Red();
3453  PathBuilder builder{};
3454  builder.AddRect(Rect::MakeLTRB(0, 0, 800, 800));
3455  canvas.DrawPath(builder.TakePath(), paint);
3456  return canvas.EndRecordingAsPicture();
3457  };
3458  ASSERT_TRUE(OpenPlaygroundHere(callback));
3459 }

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/314]

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/314]

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/314]

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

Definition at line 2434 of file aiks_unittests.cc.

2434  {
2435  Canvas canvas;
2436  canvas.DrawPaint(
2437  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2438  canvas.SaveLayer({.blend_mode = BlendMode::kMultiply});
2439  canvas.DrawPaint({.color = Color::CornflowerBlue().WithAlpha(0.75),
2440  .blend_mode = BlendMode::kSourceOver});
2441 
2442  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2443 }

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

◆ TEST_P() [103/314]

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

Definition at line 2445 of file aiks_unittests.cc.

2445  {
2446  // Bug: https://github.com/flutter/flutter/issues/131576
2447  Canvas canvas;
2448  canvas.DrawPaint(
2449  {.color = Color::Yellow(), .blend_mode = BlendMode::kSource});
2450  canvas.SaveLayer({}, {},
2451  ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0),
2452  FilterContents::BlurStyle::kNormal,
2453  Entity::TileMode::kDecal));
2454  canvas.DrawPaint(
2455  {.color = Color::CornflowerBlue(), .blend_mode = BlendMode::kSourceOver});
2456 
2457  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2458 }

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

◆ TEST_P() [104/314]

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

Definition at line 2475 of file aiks_unittests.cc.

2475  {
2476  Canvas canvas;
2477 
2478  canvas.SaveLayer({
2479  .color_filter =
2480  ColorFilter::MakeMatrix({.array =
2481  {
2482  -1.0, 0, 0, 1.0, 0, //
2483  0, -1.0, 0, 1.0, 0, //
2484  0, 0, -1.0, 1.0, 0, //
2485  1.0, 1.0, 1.0, 1.0, 0 //
2486  }}),
2487  });
2488 
2489  canvas.Translate({500, 300, 0});
2490  canvas.Rotate(Radians(2 * kPi / 3));
2491  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2492 
2493  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2494 }

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

◆ TEST_P() [105/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 3109 of file aiks_unittests.cc.

3109  {
3110  // Draws the image as four squares stiched together.
3111  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
3112  auto size = atlas->GetSize();
3113  auto image = std::make_shared<Image>(atlas);
3114  // Divide image into four quadrants.
3115  Scalar half_width = size.width / 2;
3116  Scalar half_height = size.height / 2;
3117  std::vector<Rect> texture_coordinates = {
3118  Rect::MakeLTRB(0, 0, half_width, half_height),
3119  Rect::MakeLTRB(half_width, 0, size.width, half_height),
3120  Rect::MakeLTRB(0, half_height, half_width, size.height),
3121  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
3122  // Position quadrants adjacent to eachother.
3123  std::vector<Matrix> transforms = {
3124  Matrix::MakeTranslation({0, 0, 0}),
3125  Matrix::MakeTranslation({half_width, 0, 0}),
3126  Matrix::MakeTranslation({0, half_height, 0}),
3127  Matrix::MakeTranslation({half_width, half_height, 0})};
3128 
3129  Paint paint;
3130 
3131  Canvas canvas;
3132  canvas.Scale({0.25, 0.25, 1.0});
3133  canvas.DrawAtlas(image, transforms, texture_coordinates, {},
3134  BlendMode::kModulate, {}, std::nullopt, paint);
3135 
3136  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3137 }

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

◆ TEST_P() [110/314]

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

Definition at line 3076 of file aiks_unittests.cc.

3076  {
3077  // Draws the image as four squares stiched together.
3078  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
3079  auto size = atlas->GetSize();
3080  auto image = std::make_shared<Image>(atlas);
3081  // Divide image into four quadrants.
3082  Scalar half_width = size.width / 2;
3083  Scalar half_height = size.height / 2;
3084  std::vector<Rect> texture_coordinates = {
3085  Rect::MakeLTRB(0, 0, half_width, half_height),
3086  Rect::MakeLTRB(half_width, 0, size.width, half_height),
3087  Rect::MakeLTRB(0, half_height, half_width, size.height),
3088  Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
3089  // Position quadrants adjacent to eachother.
3090  std::vector<Matrix> transforms = {
3091  Matrix::MakeTranslation({0, 0, 0}),
3092  Matrix::MakeTranslation({half_width, 0, 0}),
3093  Matrix::MakeTranslation({0, half_height, 0}),
3094  Matrix::MakeTranslation({half_width, half_height, 0})};
3095  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
3096  Color::Yellow()};
3097 
3098  Paint paint;
3099 
3100  Canvas canvas;
3101  canvas.Scale({0.25, 0.25, 1.0});
3102  canvas.DrawAtlas(image, transforms, texture_coordinates, colors,
3103  BlendMode::kModulate, {}, std::nullopt, paint);
3104 
3105  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3106 }

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

◆ TEST_P() [111/314]

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/314]

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

Definition at line 3015 of file aiks_unittests.cc.

3015  {
3016  if (GetParam() != PlaygroundBackend::kMetal) {
3017  GTEST_SKIP_("This backend doesn't support runtime effects.");
3018  }
3019 
3020  auto runtime_stage = OpenAssetAsRuntimeStage("gradient.frag.iplr");
3021  ASSERT_TRUE(runtime_stage->IsDirty());
3022 
3023  struct FragUniforms {
3024  Size size;
3025  } frag_uniforms = {.size = Size::MakeWH(400, 400)};
3026  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
3027  uniform_data->resize(sizeof(FragUniforms));
3028  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
3029 
3030  std::vector<RuntimeEffectContents::TextureInput> texture_inputs;
3031 
3032  Paint paint;
3033  paint.color_source = ColorSource::MakeRuntimeEffect(
3034  runtime_stage, uniform_data, texture_inputs);
3035 
3036  Canvas canvas;
3037  canvas.Save();
3038  canvas.Scale(GetContentScale());
3039  canvas.DrawPaint(paint);
3040  canvas.Restore();
3041 
3042  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3043 }

References impeller::Paint::color_source, impeller::Canvas::DrawPaint(), impeller::Canvas::EndRecordingAsPicture(), impeller::Canvas::Restore(), impeller::Canvas::Save(), and impeller::Canvas::Scale().

◆ TEST_P() [113/314]

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/314]

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

Definition at line 3283 of file aiks_unittests.cc.

3283  {
3284  Canvas subcanvas;
3285  subcanvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400), 15);
3286  subcanvas.DrawPaint({.color = Color::Red()});
3287  auto picture = subcanvas.EndRecordingAsPicture();
3288 
3289  Canvas canvas;
3290  canvas.DrawPaint({.color = Color::CornflowerBlue()});
3291 
3292  // Draw a red RRect via DrawPicture.
3293  canvas.DrawPicture(picture);
3294 
3295  // Draw over the picture with a larger green rectangle, completely covering it
3296  // up.
3297  canvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400).Expand(20), 15);
3298  canvas.DrawPaint({.color = Color::Green()});
3299 
3300  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3301 }

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

◆ TEST_P() [115/314]

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

Definition at line 3254 of file aiks_unittests.cc.

3254  {
3255  Canvas subcanvas;
3256  ASSERT_TRUE(RenderTextInCanvasSkia(
3257  GetContext(), subcanvas,
3258  "the quick brown fox jumped over the lazy dog!.?", "Roboto-Regular.ttf"));
3259  subcanvas.Translate({0, 10});
3260  subcanvas.Scale(Vector2(3, 3));
3261  ASSERT_TRUE(RenderTextInCanvasSkia(
3262  GetContext(), subcanvas,
3263  "the quick brown fox jumped over the very big lazy dog!.?",
3264  "Roboto-Regular.ttf"));
3265  auto picture = subcanvas.EndRecordingAsPicture();
3266 
3267  Canvas canvas;
3268  canvas.Scale(Vector2(.2, .2));
3269  canvas.Save();
3270  canvas.Translate({200, 200});
3271  canvas.Scale(Vector2(3.5, 3.5)); // The text must not be blurry after this.
3272  canvas.DrawPicture(picture);
3273  canvas.Restore();
3274 
3275  canvas.Scale(Vector2(1.5, 1.5));
3276  ASSERT_TRUE(RenderTextInCanvasSkia(
3277  GetContext(), canvas,
3278  "the quick brown fox jumped over the smaller lazy dog!.?",
3279  "Roboto-Regular.ttf"));
3280  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3281 }

References impeller::Canvas::DrawPicture(), impeller::Canvas::EndRecordingAsPicture(), RenderTextInCanvasSkia(), impeller::Canvas::Restore(), impeller::Canvas::Save(), impeller::Canvas::Scale(), and impeller::Canvas::Translate().

◆ TEST_P() [116/314]

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/314]

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/314]

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/314]

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/314]

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/314]

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

Definition at line 3384 of file aiks_unittests.cc.

3384  {
3385  Canvas canvas;
3386  // clang-format off
3387  canvas.Transform(Matrix(
3388  2.000000, 0.000000, 0.000000, 0.000000,
3389  1.445767, 2.637070, -0.507928, 0.001524,
3390  -2.451887, -0.534662, 0.861399, -0.002584,
3391  1063.481934, 1025.951416, -48.300270, 1.144901
3392  ));
3393  // clang-format on
3394 
3395  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3396  "Roboto-Regular.ttf"));
3397 
3398  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3399 }

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

◆ TEST_P() [122/314]

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

Definition at line 3401 of file aiks_unittests.cc.

3401  {
3402  Canvas canvas;
3403  Paint save_paint;
3404  canvas.SaveLayer(save_paint);
3405  // clang-format off
3406  canvas.Transform(Matrix(
3407  2.000000, 0.000000, 0.000000, 0.000000,
3408  1.445767, 2.637070, -0.507928, 0.001524,
3409  -2.451887, -0.534662, 0.861399, -0.002584,
3410  1063.481934, 1025.951416, -48.300270, 1.144901
3411  ));
3412  // clang-format on
3413 
3414  ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world",
3415  "Roboto-Regular.ttf"));
3416 }

References RenderTextInCanvasSkia(), impeller::Canvas::SaveLayer(), and impeller::Canvas::Transform().

◆ TEST_P() [123/314]

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

Definition at line 2460 of file aiks_unittests.cc.

2460  {
2461  Canvas canvas;
2462 
2463  canvas.SaveLayer({
2464  .color_filter =
2465  ColorFilter::MakeBlend(BlendMode::kColorDodge, Color::Red()),
2466  });
2467 
2468  canvas.Translate({500, 300, 0});
2469  canvas.Rotate(Radians(2 * kPi / 3));
2470  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2471 
2472  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2473 }

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

◆ TEST_P() [124/314]

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/314]

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

Definition at line 2496 of file aiks_unittests.cc.

2496  {
2497  Canvas canvas;
2498 
2499  canvas.SaveLayer({
2500  .color_filter = ColorFilter::MakeLinearToSrgb(),
2501  });
2502 
2503  canvas.Translate({500, 300, 0});
2504  canvas.Rotate(Radians(2 * kPi / 3));
2505  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2506 
2507  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2508 }

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

◆ TEST_P() [126/314]

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

Definition at line 3330 of file aiks_unittests.cc.

3330  {
3331  Canvas canvas;
3332  canvas.DrawPaint({.color = Color::Black()});
3333  canvas.SaveLayer({}, std::nullopt);
3334  {
3335  canvas.DrawCircle(Point(200, 200), 100,
3336  {.color = Color::Green().WithAlpha(0.5),
3337  .blend_mode = BlendMode::kPlus});
3338  // Should render a second circle, centered on the bottom-right-most edge of
3339  // the circle.
3340  canvas.SaveLayer(
3341  {}, std::nullopt,
3342  ImageFilter::MakeMatrix(
3343  Matrix::MakeTranslation(Vector2(1, 1) * (100 + 100 * k1OverSqrt2)) *
3344  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3345  Matrix::MakeTranslation(Vector2(-100, -100)),
3346  SamplerDescriptor{}));
3347  canvas.Restore();
3348  }
3349  canvas.Restore();
3350 
3351  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3352 }

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

◆ TEST_P() [127/314]

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

Definition at line 3590 of file aiks_unittests.cc.

3590  {
3591  Canvas canvas;
3592  canvas.Scale(GetContentScale());
3593  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
3594  canvas.Translate({600, -200});
3595  canvas.SaveLayer({
3596  .image_filter = std::make_shared<MatrixImageFilter>(
3597  Matrix{
3598  2, 0, 0, 0, //
3599  0, 2, 0, 0, //
3600  0, 0, 2, 0, //
3601  0, 0, 0, 1 //
3602  },
3603  SamplerDescriptor{}),
3604  });
3605  canvas.DrawImage(image, {0, 0}, Paint{.color = Color(1.0, 1.0, 1.0, 0.5)});
3606  canvas.Restore();
3607 
3608  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3609 }

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() [128/314]

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

Definition at line 3303 of file aiks_unittests.cc.

3303  {
3304  Canvas canvas;
3305  canvas.DrawPaint({.color = Color::Black()});
3306  canvas.SaveLayer({}, std::nullopt);
3307  {
3308  canvas.DrawCircle(Point(200, 200), 100,
3309  {.color = Color::Green().WithAlpha(0.5),
3310  .blend_mode = BlendMode::kPlus});
3311  // Should render a second circle, centered on the bottom-right-most edge of
3312  // the circle.
3313  canvas.SaveLayer({.image_filter = ImageFilter::MakeMatrix(
3314  Matrix::MakeTranslation(Vector2(1, 1) *
3315  (200 + 100 * k1OverSqrt2)) *
3316  Matrix::MakeScale(Vector2(1, 1) * 0.5) *
3317  Matrix::MakeTranslation(Vector2(-200, -200)),
3318  SamplerDescriptor{})},
3319  std::nullopt);
3320  canvas.DrawCircle(Point(200, 200), 100,
3321  {.color = Color::Green().WithAlpha(0.5),
3322  .blend_mode = BlendMode::kPlus});
3323  canvas.Restore();
3324  }
3325  canvas.Restore();
3326 
3327  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3328 }

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

◆ TEST_P() [129/314]

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() [130/314]

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

Definition at line 2818 of file aiks_unittests.cc.

2818  {
2819  Canvas canvas;
2820  canvas.Scale(Vector2(1.618, 1.618));
2821  canvas.DrawCircle(Point(), 10,
2822  {
2823  .color = Color::CornflowerBlue(),
2824  .blend_mode = BlendMode::kSourceOver,
2825  });
2826  Picture picture = canvas.EndRecordingAsPicture();
2827 
2828  // Extract the SolidColorSource.
2829  Entity entity;
2830  std::shared_ptr<SolidColorContents> contents;
2831  picture.pass->IterateAllEntities([&e = entity, &contents](Entity& entity) {
2832  if (ScalarNearlyEqual(entity.GetTransformation().GetScale().x, 1.618f)) {
2833  e = entity;
2834  contents =
2835  std::static_pointer_cast<SolidColorContents>(entity.GetContents());
2836  return false;
2837  }
2838  return true;
2839  });
2840 
2841  ASSERT_TRUE(contents->IsOpaque());
2842  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSource);
2843 }

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() [131/314]

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() [132/314]

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() [133/314]

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() [134/314]

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

Definition at line 3418 of file aiks_unittests.cc.

3418  {
3419  Canvas canvas;
3420 
3421  // Should render a green square in the middle of a blue circle.
3422  canvas.SaveLayer({});
3423  {
3424  canvas.Translate(Point(100, 100));
3425  canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()});
3426  canvas.ClipRect(Rect(100, 100, 200, 200));
3427  canvas.DrawCircle(Point(200, 200), 200,
3428  {
3429  .color = Color::Green(),
3430  .blend_mode = BlendMode::kSourceOver,
3431  .image_filter = ImageFilter::MakeFromColorFilter(
3432  *ColorFilter::MakeBlend(BlendMode::kDestination,
3433  Color::White())),
3434  });
3435  canvas.Restore();
3436  }
3437 
3438  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3439 }

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

◆ TEST_P() [135/314]

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

Definition at line 3506 of file aiks_unittests.cc.

3506  {
3507  auto context = GetContext();
3508  std::weak_ptr<Texture> weak_texture;
3509 
3510  {
3511  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3512 
3513  Canvas canvas;
3514  canvas.Scale(GetContentScale());
3515  canvas.Translate({100.0f, 100.0f, 0});
3516 
3517  Paint paint;
3518  paint.color_source = ColorSource::MakeImage(
3519  texture, Entity::TileMode::kClamp, Entity::TileMode::kClamp, {}, {});
3520  canvas.DrawRect({0, 0, 600, 600}, paint);
3521 
3522  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3523  }
3524 
3525  // See https://github.com/flutter/flutter/issues/134751.
3526  //
3527  // If the fence waiter was working this may not be released by the end of the
3528  // scope above. Adding a manual shutdown so that future changes to the fence
3529  // waiter will not flake this test.
3530  context->Shutdown();
3531 
3532  // The texture should be released by now.
3533  ASSERT_TRUE(weak_texture.expired()) << "When the texture is no longer in use "
3534  "by the backend, it should be "
3535  "released.";
3536 }

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

◆ TEST_P() [136/314]

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() [137/314]

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() [138/314]

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() [139/314]

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() [140/314]

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

Definition at line 3354 of file aiks_unittests.cc.

3354  {
3355  auto contents = SolidColorContents();
3356  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.75));
3357  auto result = contents.ApplyColorFilter([](const Color& color) {
3358  return color.Blend(Color::LimeGreen().WithAlpha(0.75), BlendMode::kScreen);
3359  });
3360  ASSERT_TRUE(result);
3361  ASSERT_COLOR_NEAR(contents.GetColor(),
3362  Color(0.433247, 0.879523, 0.825324, 0.75));
3363 }

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

◆ TEST_P() [141/314]

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() [142/314]

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

Definition at line 2510 of file aiks_unittests.cc.

2510  {
2511  Canvas canvas;
2512 
2513  canvas.SaveLayer({
2514  .color_filter = ColorFilter::MakeSrgbToLinear(),
2515  });
2516 
2517  canvas.Translate({500, 300, 0});
2518  canvas.Rotate(Radians(2 * kPi / 3));
2519  canvas.DrawRect({100, 100, 200, 200}, {.color = Color::Blue()});
2520 
2521  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2522 }

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

◆ TEST_P() [143/314]

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

Definition at line 3172 of file aiks_unittests.cc.

3172  {
3173  auto mapping = OpenFixtureAsSkData("Roboto-Regular.ttf");
3174  ASSERT_NE(mapping, nullptr);
3175 
3176  Scalar font_size = 100;
3177  SkFont sk_font(SkTypeface::MakeFromData(mapping), font_size);
3178 
3179  Paint text_paint;
3180  text_paint.color = Color::Blue();
3181 
3182  std::vector<Color> colors = {Color{0.9568, 0.2627, 0.2118, 1.0},
3183  Color{0.1294, 0.5882, 0.9529, 1.0}};
3184  std::vector<Scalar> stops = {
3185  0.0,
3186  1.0,
3187  };
3188  text_paint.color_source = ColorSource::MakeLinearGradient(
3189  {0, 0}, {100, 100}, std::move(colors), std::move(stops),
3190  Entity::TileMode::kRepeat, {});
3191 
3192  Canvas canvas;
3193  canvas.Translate({100, 100});
3194  canvas.Rotate(Radians(kPi / 4));
3195 
3196  auto blob = SkTextBlob::MakeFromString("Hello", sk_font);
3197  ASSERT_NE(blob, nullptr);
3198  auto frame = MakeTextFrameFromTextBlobSkia(blob);
3199  canvas.DrawTextFrame(frame, Point(), text_paint);
3200 
3201  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3202 }

References impeller::Paint::color, impeller::Paint::color_source, impeller::kPi, impeller::MakeTextFrameFromTextBlobSkia(), OpenFixtureAsSkData(), and impeller::Canvas::Translate().

◆ TEST_P() [144/314]

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() [145/314]

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() [146/314]

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() [147/314]

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

Definition at line 2616 of file aiks_unittests.cc.

2616  {
2617  Canvas canvas;
2618 
2619  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2620 
2621  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2622  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2623  canvas.Restore();
2624 
2625  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2626 }

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

◆ TEST_P() [148/314]

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

Definition at line 2678 of file aiks_unittests.cc.

2678  {
2679  Canvas canvas;
2680 
2681  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2682  canvas.DrawImage(image, {100, 100}, {});
2683 
2684  canvas.SaveLayer({.color = Color::Black().WithAlpha(0.5)});
2685  canvas.DrawImage(image, {100, 500}, {});
2686  canvas.Restore();
2687 
2688  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2689 }

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

◆ TEST_P() [149/314]

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

Definition at line 2762 of file aiks_unittests.cc.

2762  {
2763  Canvas canvas;
2764  canvas.DrawRect({0, 0, 400, 400}, {.color = Color::Red()});
2765  canvas.SaveLayer({
2766  .color = Color::Black().WithAlpha(0.5),
2767  .blend_mode = BlendMode::kLighten,
2768  });
2769  canvas.DrawCircle({200, 200}, 100, {.color = Color::Green()});
2770  canvas.Restore();
2771  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2772 }

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

◆ TEST_P() [150/314]

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

Definition at line 2628 of file aiks_unittests.cc.

2628  {
2629  Canvas canvas;
2630 
2631  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2632 
2633  canvas.SaveLayer({
2634  .color = Color::Black().WithAlpha(0.5),
2635  .color_filter =
2636  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2637  });
2638  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2639  canvas.Restore();
2640 
2641  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2642 }

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

◆ TEST_P() [151/314]

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

Definition at line 2644 of file aiks_unittests.cc.

2644  {
2645  Canvas canvas;
2646 
2647  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2648 
2649  canvas.SaveLayer({
2650  .color = Color::Black().WithAlpha(0.5),
2651  .image_filter = ImageFilter::MakeFromColorFilter(
2652  *ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red())),
2653  });
2654 
2655  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2656  canvas.Restore();
2657 
2658  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2659 }

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

◆ TEST_P() [152/314]

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

Definition at line 2661 of file aiks_unittests.cc.

2661  {
2662  Canvas canvas;
2663 
2664  canvas.DrawRect(Rect::MakeXYWH(100, 100, 300, 300), {.color = Color::Blue()});
2665 
2666  canvas.SaveLayer({
2667  .color = Color::Black().WithAlpha(0.5),
2668  .color_filter =
2669  ColorFilter::MakeBlend(BlendMode::kDestinationOver, Color::Red()),
2670  });
2671 
2672  canvas.DrawRect(Rect::MakeXYWH(100, 500, 300, 300), {.color = Color::Blue()});
2673  canvas.Restore();
2674 
2675  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2676 }

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

◆ TEST_P() [153/314]

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

Definition at line 2736 of file aiks_unittests.cc.

2737  {
2738  Canvas canvas;
2739 
2740  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2741  canvas.DrawImage(image, {100, 100}, {});
2742 
2743  canvas.SaveLayer({
2744  .color = Color::Black().WithAlpha(0.5),
2745  .image_filter = ImageFilter::MakeFromColorFilter(
2746  *ColorFilter::MakeMatrix({.array =
2747  {
2748  1, 0, 0, 0, 0, //
2749  0, 1, 0, 0, 0, //
2750  0, 0.2, 1, 0, 0, //
2751  0, 0, 0, 0.5, 0 //
2752  }})),
2753  .color_filter =
2754  ColorFilter::MakeBlend(BlendMode::kModulate, Color::Green()),
2755  });
2756  canvas.DrawImage(image, {100, 500}, {});
2757  canvas.Restore();
2758 
2759  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2760 }

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

◆ TEST_P() [154/314]

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

Definition at line 2691 of file aiks_unittests.cc.

2691  {
2692  Canvas canvas;
2693 
2694  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2695  canvas.DrawImage(image, {100, 100}, {});
2696 
2697  canvas.SaveLayer({
2698  .color = Color::Black().WithAlpha(0.5),
2699  .color_filter = ColorFilter::MakeMatrix({.array =
2700  {
2701  1, 0, 0, 0, 0, //
2702  0, 1, 0, 0, 0, //
2703  0, 0, 1, 0, 0, //
2704  0, 0, 0, 2, 0 //
2705  }}),
2706  });
2707  canvas.DrawImage(image, {100, 500}, {});
2708  canvas.Restore();
2709 
2710  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2711 }

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

◆ TEST_P() [155/314]

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

Definition at line 2713 of file aiks_unittests.cc.

2713  {
2714  Canvas canvas;
2715 
2716  auto image = std::make_shared<Image>(CreateTextureForFixture("airplane.jpg"));
2717  canvas.DrawImage(image, {100, 100}, {});
2718 
2719  canvas.SaveLayer({
2720  .color = Color::Black().WithAlpha(0.5),
2721  .image_filter = ImageFilter::MakeFromColorFilter(
2722  *ColorFilter::MakeMatrix({.array =
2723  {
2724  1, 0, 0, 0, 0, //
2725  0, 1, 0, 0, 0, //
2726  0, 0, 1, 0, 0, //
2727  0, 0, 0, 2, 0 //
2728  }})),
2729  });
2730  canvas.DrawImage(image, {100, 500}, {});
2731  canvas.Restore();
2732 
2733  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
2734 }

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

◆ TEST_P() [156/314]

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

Definition at line 3539 of file aiks_unittests.cc.

3539  {
3540  Canvas canvas;
3541  Paint paint;
3542  auto texture = CreateTextureForFixture("table_mountain_nx.png");
3543 
3544  paint.color_source = ColorSource::MakeImage(texture, Entity::TileMode::kClamp,
3545  Entity::TileMode::kClamp, {}, {});
3546 
3547  auto vertices = {Point(0, 0), Point(texture->GetSize().width, 0),
3548  Point(0, texture->GetSize().height)};
3549  std::vector<uint16_t> indices = {0u, 1u, 2u};
3550  std::vector<Point> texture_coordinates = {};
3551  std::vector<Color> vertex_colors = {};
3552  auto geometry = std::make_shared<VerticesGeometry>(
3553  vertices, indices, texture_coordinates, vertex_colors,
3554  Rect::MakeLTRB(0, 0, 1, 1), VerticesGeometry::VertexMode::kTriangleStrip);
3555 
3556  canvas.DrawVertices(geometry, BlendMode::kSourceOver, paint);
3557  ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
3558 }

References impeller::Paint::color_source, impeller::Canvas::DrawVertices(), and impeller::Canvas::EndRecordingAsPicture().

◆ TEST_P() [157/314]

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() [158/314]

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() [159/314]

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() [160/314]

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() [161/314]

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() [162/314]

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() [163/314]

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() [164/314]

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() [165/314]

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() [166/314]

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() [167/314]

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() [168/314]

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() [169/314]

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() [170/314]

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() [171/314]

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() [172/314]

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() [173/314]

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() [174/314]

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() [175/314]

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() [176/314]

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() [177/314]

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() [178/314]

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() [179/314]

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() [180/314]

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() [181/314]

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() [182/314]

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() [183/314]

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() [184/314]

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() [185/314]

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() [186/314]

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() [187/314]

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() [188/314]

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() [189/314]

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() [190/314]

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() [191/314]

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() [192/314]

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() [193/314]

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() [194/314]

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() [195/314]

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() [196/314]

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() [197/314]

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() [198/314]

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() [199/314]

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() [200/314]

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() [201/314]

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() [202/314]

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() [203/314]

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() [204/314]

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() [205/314]

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() [206/314]

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() [207/314]

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() [208/314]

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() [209/314]

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() [210/314]

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() [211/314]

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() [212/314]

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() [213/314]

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() [214/314]

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() [215/314]

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() [216/314]

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() [217/314]

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() [218/314]

impeller::testing::TEST_P ( EntityTest  ,
AdvancedBlendCoverageHintIsNotResetByEntityPass   
)

Definition at line 2478 of file entity_unittests.cc.

2478  {
2479  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
2480  GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
2481  "for advanced blends.";
2482  }
2483 
2484  auto contents = std::make_shared<SolidColorContents>();
2485  contents->SetGeometry(Geometry::MakeRect({100, 100, 100, 100}));
2486  contents->SetColor(Color::Red());
2487 
2488  Entity entity;
2489  entity.SetTransformation(Matrix::MakeScale(Vector3(2, 2, 1)));
2490  entity.SetBlendMode(BlendMode::kColorBurn);
2491  entity.SetContents(contents);
2492 
2493  auto coverage = entity.GetCoverage();
2494  EXPECT_TRUE(coverage.has_value());
2495 
2496  auto pass = std::make_unique<EntityPass>();
2497  auto test_allocator = std::make_shared<TestRenderTargetAllocator>(
2498  GetContext()->GetResourceAllocator());
2499  auto stencil_config = RenderTarget::AttachmentConfig{
2500  .storage_mode = StorageMode::kDevicePrivate,
2501  .load_action = LoadAction::kClear,
2502  .store_action = StoreAction::kDontCare,
2503  .clear_color = Color::BlackTransparent()};
2504  auto rt = RenderTarget::CreateOffscreen(
2505  *GetContext(), *test_allocator, ISize::MakeWH(1000, 1000), "Offscreen",
2506  RenderTarget::kDefaultColorAttachmentConfig, stencil_config);
2507  auto content_context = ContentContext(
2508  GetContext(), TypographerContextSkia::Make(), test_allocator);
2509  pass->AddEntity(entity);
2510 
2511  EXPECT_TRUE(pass->Render(content_context, rt));
2512 
2513  if (test_allocator->GetDescriptors().size() == 6u) {
2514  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2515  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2516 
2517  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(200, 200));
2518  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(200, 200));
2519  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(200, 200));
2520  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2521  } else if (test_allocator->GetDescriptors().size() == 9u) {
2522  // Onscreen render target.
2523  EXPECT_EQ(test_allocator->GetDescriptors()[0].size, ISize(1000, 1000));
2524  EXPECT_EQ(test_allocator->GetDescriptors()[1].size, ISize(1000, 1000));
2525  EXPECT_EQ(test_allocator->GetDescriptors()[2].size, ISize(1000, 1000));
2526  EXPECT_EQ(test_allocator->GetDescriptors()[3].size, ISize(1000, 1000));
2527  EXPECT_EQ(test_allocator->GetDescriptors()[4].size, ISize(1000, 1000));
2528 
2529  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2530  EXPECT_EQ(test_allocator->GetDescriptors()[5].size, ISize(200, 200));
2531  EXPECT_EQ(test_allocator->GetDescriptors()[6].size, ISize(200, 200));
2532  EXPECT_EQ(test_allocator->GetDescriptors()[7].size, ISize(200, 200));
2533  } else {
2534  EXPECT_TRUE(false);
2535  }
2536 }

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() [219/314]

impeller::testing::TEST_P ( EntityTest  ,
AtlasContentsSubAtlas   
)

Definition at line 1935 of file entity_unittests.cc.

1935  {
1936  auto boston = CreateTextureForFixture("boston.jpg");
1937 
1938  {
1939  auto contents = std::make_shared<AtlasContents>();
1940  contents->SetBlendMode(BlendMode::kSourceOver);
1941  contents->SetTexture(boston);
1942  contents->SetColors({
1943  Color::Red(),
1944  Color::Red(),
1945  Color::Red(),
1946  });
1947  contents->SetTextureCoordinates({
1948  Rect::MakeLTRB(0, 0, 10, 10),
1949  Rect::MakeLTRB(0, 0, 10, 10),
1950  Rect::MakeLTRB(0, 0, 10, 10),
1951  });
1952  contents->SetTransforms({
1953  Matrix::MakeTranslation(Vector2(0, 0)),
1954  Matrix::MakeTranslation(Vector2(100, 100)),
1955  Matrix::MakeTranslation(Vector2(200, 200)),
1956  });
1957 
1958  // Since all colors and sample rects are the same, there should
1959  // only be a single entry in the sub atlas.
1960  auto subatlas = contents->GenerateSubAtlas();
1961  ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
1962  }
1963 
1964  {
1965  auto contents = std::make_shared<AtlasContents>();
1966  contents->SetBlendMode(BlendMode::kSourceOver);
1967  contents->SetTexture(boston);
1968  contents->SetColors({
1969  Color::Red(),
1970  Color::Green(),
1971  Color::Blue(),
1972  });
1973  contents->SetTextureCoordinates({
1974  Rect::MakeLTRB(0, 0, 10, 10),
1975  Rect::MakeLTRB(0, 0, 10, 10),
1976  Rect::MakeLTRB(0, 0, 10, 10),
1977  });
1978  contents->SetTransforms({
1979  Matrix::MakeTranslation(Vector2(0, 0)),
1980  Matrix::MakeTranslation(Vector2(100, 100)),
1981  Matrix::MakeTranslation(Vector2(200, 200)),
1982  });
1983 
1984  // Since all colors are different, there are three entires.
1985  auto subatlas = contents->GenerateSubAtlas();
1986  ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);
1987 
1988  // The translations are kept but the sample rects point into
1989  // different parts of the sub atlas.
1990  ASSERT_EQ(subatlas->result_texture_coords[0], Rect::MakeXYWH(0, 0, 10, 10));
1991  ASSERT_EQ(subatlas->result_texture_coords[1],
1992  Rect::MakeXYWH(11, 0, 10, 10));
1993  ASSERT_EQ(subatlas->result_texture_coords[2],
1994  Rect::MakeXYWH(22, 0, 10, 10));
1995  }
1996 }

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() [220/314]

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() [221/314]

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() [222/314]

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() [223/314]

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() [224/314]

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() [225/314]

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() [226/314]

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() [227/314]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsGetStencilCoverageIsCorrect   
)

Definition at line 1634 of file entity_unittests.cc.

1634  {
1635  // Intersection: No stencil coverage, no geometry.
1636  {
1637  auto clip = std::make_shared<ClipContents>();
1638  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1639  auto result = clip->GetStencilCoverage(Entity{}, Rect{});
1640 
1641  ASSERT_FALSE(result.coverage.has_value());
1642  }
1643 
1644  // Intersection: No stencil coverage, with geometry.
1645  {
1646  auto clip = std::make_shared<ClipContents>();
1647  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1648  clip->SetGeometry(Geometry::MakeFillPath(
1649  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1650  auto result = clip->GetStencilCoverage(Entity{}, Rect{});
1651 
1652  ASSERT_FALSE(result.coverage.has_value());
1653  }
1654 
1655  // Intersection: With stencil coverage, no geometry.
1656  {
1657  auto clip = std::make_shared<ClipContents>();
1658  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1659  auto result =
1660  clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1661 
1662  ASSERT_FALSE(result.coverage.has_value());
1663  }
1664 
1665  // Intersection: With stencil coverage, with geometry.
1666  {
1667  auto clip = std::make_shared<ClipContents>();
1668  clip->SetClipOperation(Entity::ClipOperation::kIntersect);
1669  clip->SetGeometry(Geometry::MakeFillPath(
1670  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
1671  auto result =
1672  clip->GetStencilCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));
1673 
1674  ASSERT_TRUE(result.coverage.has_value());
1675  ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
1676  ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
1677  }
1678 
1679  // Difference: With stencil coverage, with geometry.
1680  {
1681  auto clip = std::make_shared<ClipContents>();
1682  clip->SetClipOperation(Entity::ClipOperation::kDifference);
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, 100, 100));
1690  ASSERT_EQ(result.type, Contents::StencilCoverage::Type::kAppend);
1691  }
1692 }

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() [228/314]

impeller::testing::TEST_P ( EntityTest  ,
ClipContentsShouldRenderIsCorrect   
)

Definition at line 1610 of file entity_unittests.cc.

1610  {
1611  // For clip ops, `ShouldRender` should always return true.
1612 
1613  // Clip.
1614  {
1615  auto clip = std::make_shared<ClipContents>();
1616  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1617  clip->SetGeometry(Geometry::MakeFillPath(
1618  PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
1619  ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1620  ASSERT_TRUE(
1621  clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1622  }
1623 
1624  // Clip restore.
1625  {
1626  auto restore = std::make_shared<ClipRestoreContents>();
1627  ASSERT_TRUE(
1628  restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
1629  ASSERT_TRUE(
1630  restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
1631  }
1632 }

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

◆ TEST_P() [229/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterContentsWithLargeGeometry   
)

Definition at line 2428 of file entity_unittests.cc.

2428  {
2429  Entity entity;
2430  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
2431  auto src_contents = std::make_shared<SolidColorContents>();
2432  src_contents->SetGeometry(
2433  Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
2434  src_contents->SetColor(Color::Red());
2435 
2436  auto dst_contents = std::make_shared<SolidColorContents>();
2437  dst_contents->SetGeometry(
2438  Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
2439  dst_contents->SetColor(Color::Blue());
2440 
2441  auto contents = ColorFilterContents::MakeBlend(
2442  BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
2443  FilterInput::Make(src_contents, false)});
2444  entity.SetContents(std::move(contents));
2445  ASSERT_TRUE(OpenPlaygroundHere(entity));
2446 }

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() [230/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorAdvancedBlend   
)

Definition at line 2211 of file entity_unittests.cc.

2211  {
2212  auto image = CreateTextureForFixture("boston.jpg");
2213  auto filter = ColorFilterContents::MakeBlend(
2214  BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());
2215 
2216  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2217  Entity entity;
2218  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2219  Matrix::MakeTranslation({500, 300}) *
2220  Matrix::MakeScale(Vector2{0.5, 0.5}));
2221  entity.SetContents(filter);
2222  return entity.Render(context, pass);
2223  };
2224  ASSERT_TRUE(OpenPlaygroundHere(callback));
2225 }

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() [231/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorClearBlend   
)

Definition at line 2227 of file entity_unittests.cc.

2227  {
2228  auto image = CreateTextureForFixture("boston.jpg");
2229  auto filter = ColorFilterContents::MakeBlend(
2230  BlendMode::kClear, FilterInput::Make({image}), Color::Red());
2231 
2232  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2233  Entity entity;
2234  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2235  Matrix::MakeTranslation({500, 300}) *
2236  Matrix::MakeScale(Vector2{0.5, 0.5}));
2237  entity.SetContents(filter);
2238  return entity.Render(context, pass);
2239  };
2240  ASSERT_TRUE(OpenPlaygroundHere(callback));
2241 }

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() [232/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorDstBlend   
)

Definition at line 2259 of file entity_unittests.cc.

2259  {
2260  auto image = CreateTextureForFixture("boston.jpg");
2261  auto filter = ColorFilterContents::MakeBlend(
2262  BlendMode::kDestination, FilterInput::Make({image}), Color::Red());
2263 
2264  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2265  Entity entity;
2266  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2267  Matrix::MakeTranslation({500, 300}) *
2268  Matrix::MakeScale(Vector2{0.5, 0.5}));
2269  entity.SetContents(filter);
2270  return entity.Render(context, pass);
2271  };
2272  ASSERT_TRUE(OpenPlaygroundHere(callback));
2273 }

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() [233/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcBlend   
)

Definition at line 2243 of file entity_unittests.cc.

2243  {
2244  auto image = CreateTextureForFixture("boston.jpg");
2245  auto filter = ColorFilterContents::MakeBlend(
2246  BlendMode::kSource, FilterInput::Make({image}), Color::Red());
2247 
2248  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2249  Entity entity;
2250  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2251  Matrix::MakeTranslation({500, 300}) *
2252  Matrix::MakeScale(Vector2{0.5, 0.5}));
2253  entity.SetContents(filter);
2254  return entity.Render(context, pass);
2255  };
2256  ASSERT_TRUE(OpenPlaygroundHere(callback));
2257 }

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() [234/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorFilterWithForegroundColorSrcInBlend   
)

Definition at line 2275 of file entity_unittests.cc.

2275  {
2276  auto image = CreateTextureForFixture("boston.jpg");
2277  auto filter = ColorFilterContents::MakeBlend(
2278  BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());
2279 
2280  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2281  Entity entity;
2282  entity.SetTransformation(Matrix::MakeScale(GetContentScale()) *
2283  Matrix::MakeTranslation({500, 300}) *
2284  Matrix::MakeScale(Vector2{0.5, 0.5}));
2285  entity.SetContents(filter);
2286  return entity.Render(context, pass);
2287  };
2288  ASSERT_TRUE(OpenPlaygroundHere(callback));
2289 }

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() [235/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterCoverageIsCorrect   
)

Definition at line 1744 of file entity_unittests.cc.

1744  {
1745  // Set up a simple color background.
1746  auto fill = std::make_shared<SolidColorContents>();
1747  fill->SetGeometry(Geometry::MakeFillPath(
1748  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1749  fill->SetColor(Color::Coral());
1750 
1751  // Set the color matrix filter.
1752  ColorMatrix matrix = {
1753  1, 1, 1, 1, 1, //
1754  1, 1, 1, 1, 1, //
1755  1, 1, 1, 1, 1, //
1756  1, 1, 1, 1, 1, //
1757  };
1758 
1759  auto filter =
1760  ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);
1761 
1762  Entity e;
1763  e.SetTransformation(Matrix());
1764 
1765  // Confirm that the actual filter coverage matches the expected coverage.
1766  auto actual = filter->GetCoverage(e);
1767  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1768 
1769  ASSERT_TRUE(actual.has_value());
1770  ASSERT_RECT_NEAR(actual.value(), expected);
1771 }

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() [236/314]

impeller::testing::TEST_P ( EntityTest  ,
ColorMatrixFilterEditable   
)

Definition at line 1773 of file entity_unittests.cc.

1773  {
1774  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
1775  ASSERT_TRUE(bay_bridge);
1776 
1777  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1778  // UI state.
1779  static ColorMatrix color_matrix = {
1780  1, 0, 0, 0, 0, //
1781  0, 3, 0, 0, 0, //
1782  0, 0, 1, 0, 0, //
1783  0, 0, 0, 1, 0, //
1784  };
1785  static float offset[2] = {500, 400};
1786  static float rotation = 0;
1787  static float scale[2] = {0.65, 0.65};
1788  static float skew[2] = {0, 0};
1789 
1790  // Define the ImGui
1791  ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1792  {
1793  std::string label = "##1";
1794  for (int i = 0; i < 20; i += 5) {
1795  ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
1796  &(color_matrix.array[i]), 5, nullptr, nullptr,
1797  "%.2f", 0);
1798  label[2]++;
1799  }
1800 
1801  ImGui::SliderFloat2("Translation", &offset[0], 0,
1802  pass.GetRenderTargetSize().width);
1803  ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
1804  ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
1805  ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
1806  }
1807  ImGui::End();
1808 
1809  // Set the color matrix filter.
1810  auto filter = ColorFilterContents::MakeColorMatrix(
1811  FilterInput::Make(bay_bridge), color_matrix);
1812 
1813  // Define the entity with the color matrix filter.
1814  Entity entity;
1815  entity.SetTransformation(
1816  Matrix::MakeScale(GetContentScale()) *
1817  Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
1818  Matrix::MakeRotationZ(Radians(rotation)) *
1819  Matrix::MakeScale(Vector2(scale[0], scale[1])) *
1820  Matrix::MakeSkew(skew[0], skew[1]) *
1821  Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
1822  entity.SetContents(filter);
1823  entity.Render(context, pass);
1824 
1825  return true;
1826  };
1827 
1828  ASSERT_TRUE(OpenPlaygroundHere(callback));
1829 }

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() [237/314]

impeller::testing::TEST_P ( EntityTest  ,
ConicalGradientContentsIsOpaque   
)

Definition at line 2315 of file entity_unittests.cc.

2315  {
2316  ConicalGradientContents contents;
2317  contents.SetColors({Color::CornflowerBlue()});
2318  ASSERT_FALSE(contents.IsOpaque());
2319  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2320  ASSERT_FALSE(contents.IsOpaque());
2321 }

References impeller::Color::CornflowerBlue(), impeller::Contents::IsOpaque(), impeller::ConicalGradientContents::SetColors(), and impeller::Color::WithAlpha().

◆ TEST_P() [238/314]

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() [239/314]

impeller::testing::TEST_P ( EntityTest  ,
CoverageForStrokePathWithNegativeValuesInTransform   
)

Definition at line 2291 of file entity_unittests.cc.

2291  {
2292  auto arrow_head = PathBuilder{}
2293  .MoveTo({50, 120})
2294  .LineTo({120, 190})
2295  .LineTo({190, 120})
2296  .TakePath();
2297  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
2298  Join::kRound);
2299 
2300  auto transform = Matrix::MakeTranslation({300, 300}) *
2301  Matrix::MakeRotationZ(Radians(kPiOver2));
2302  EXPECT_LT(transform.e[0][0], 0.f);
2303  auto coverage = geometry->GetCoverage(transform);
2304  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
2305 }

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() [240/314]

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() [241/314]

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() [242/314]

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() [243/314]

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() [244/314]

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() [245/314]

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() [246/314]

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() [247/314]

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() [248/314]

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() [249/314]

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() [250/314]

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() [251/314]

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() [252/314]

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() [253/314]

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() [254/314]

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() [255/314]

impeller::testing::TEST_P ( EntityTest  ,
InheritOpacityTest   
)

Definition at line 2140 of file entity_unittests.cc.

2140  {
2141  Entity entity;
2142 
2143  // Texture contents can always accept opacity.
2144  auto texture_contents = std::make_shared<TextureContents>();
2145  texture_contents->SetOpacity(0.5);
2146  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));
2147 
2148  texture_contents->SetInheritedOpacity(0.5);
2149  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2150  texture_contents->SetInheritedOpacity(0.5);
2151  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
2152 
2153  // Solid color contents can accept opacity if their geometry
2154  // doesn't overlap.
2155  auto solid_color = std::make_shared<SolidColorContents>();
2156  solid_color->SetGeometry(
2157  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2158  solid_color->SetColor(Color::Blue().WithAlpha(0.5));
2159 
2160  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));
2161 
2162  solid_color->SetInheritedOpacity(0.5);
2163  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2164  solid_color->SetInheritedOpacity(0.5);
2165  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
2166 
2167  // Color source contents can accept opacity if their geometry
2168  // doesn't overlap.
2169  auto tiled_texture = std::make_shared<TiledTextureContents>();
2170  tiled_texture->SetGeometry(
2171  Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
2172  tiled_texture->SetOpacityFactor(0.5);
2173 
2174  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));
2175 
2176  tiled_texture->SetInheritedOpacity(0.5);
2177  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2178  tiled_texture->SetInheritedOpacity(0.5);
2179  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
2180 
2181  // Text contents can accept opacity if the text frames do not
2182  // overlap
2183  SkFont font;
2184  font.setSize(30);
2185  auto blob = SkTextBlob::MakeFromString("A", font);
2186  auto frame = MakeTextFrameFromTextBlobSkia(blob);
2187  auto lazy_glyph_atlas =
2188  std::make_shared<LazyGlyphAtlas>(TypographerContextSkia::Make());
2189  lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);
2190 
2191  auto text_contents = std::make_shared<TextContents>();
2192  text_contents->SetTextFrame(frame);
2193  text_contents->SetColor(Color::Blue().WithAlpha(0.5));
2194 
2195  ASSERT_TRUE(text_contents->CanInheritOpacity(entity));
2196 
2197  text_contents->SetInheritedOpacity(0.5);
2198  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2199  text_contents->SetInheritedOpacity(0.5);
2200  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
2201 
2202  // Clips and restores trivially accept opacity.
2203  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
2204  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));
2205 
2206  // Runtime effect contents can't accept opacity.
2207  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
2208  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
2209 }

References impeller::Color::Blue(), impeller::TypographerContextSkia::Make(), impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakeRect(), and impeller::MakeTextFrameFromTextBlobSkia().

◆ TEST_P() [256/314]

impeller::testing::TEST_P ( EntityTest  ,
LinearGradientContentsIsOpaque   
)

Definition at line 2323 of file entity_unittests.cc.

2323  {
2324  LinearGradientContents contents;
2325  contents.SetColors({Color::CornflowerBlue()});
2326  ASSERT_TRUE(contents.IsOpaque());
2327  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2328  ASSERT_FALSE(contents.IsOpaque());
2329  contents.SetColors({Color::CornflowerBlue()});
2330  contents.SetTileMode(Entity::TileMode::kDecal);
2331  ASSERT_FALSE(contents.IsOpaque());
2332 }

References impeller::Color::CornflowerBlue(), impeller::LinearGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::LinearGradientContents::SetColors(), impeller::LinearGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [257/314]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilter   
)

Definition at line 1852 of file entity_unittests.cc.

1852  {
1853  auto image = CreateTextureForFixture("kalimba.jpg");
1854  ASSERT_TRUE(image);
1855 
1856  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1857  auto filtered =
1858  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));
1859 
1860  // Define the entity that will serve as the control image as a Gaussian blur
1861  // filter with no filter at all.
1862  Entity entity_left;
1863  entity_left.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1864  Matrix::MakeTranslation({100, 300}) *
1865  Matrix::MakeScale(Vector2{0.5, 0.5}));
1866  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1867  Sigma{0}, Sigma{0});
1868  entity_left.SetContents(unfiltered);
1869 
1870  // Define the entity that will be filtered from linear to sRGB.
1871  Entity entity_right;
1872  entity_right.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1873  Matrix::MakeTranslation({500, 300}) *
1874  Matrix::MakeScale(Vector2{0.5, 0.5}));
1875  entity_right.SetContents(filtered);
1876  return entity_left.Render(context, pass) &&
1877  entity_right.Render(context, pass);
1878  };
1879 
1880  ASSERT_TRUE(OpenPlaygroundHere(callback));
1881 }

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() [258/314]

impeller::testing::TEST_P ( EntityTest  ,
LinearToSrgbFilterCoverageIsCorrect   
)

Definition at line 1831 of file entity_unittests.cc.

1831  {
1832  // Set up a simple color background.
1833  auto fill = std::make_shared<SolidColorContents>();
1834  fill->SetGeometry(Geometry::MakeFillPath(
1835  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1836  fill->SetColor(Color::MintCream());
1837 
1838  auto filter =
1839  ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));
1840 
1841  Entity e;
1842  e.SetTransformation(Matrix());
1843 
1844  // Confirm that the actual filter coverage matches the expected coverage.
1845  auto actual = filter->GetCoverage(e);
1846  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1847 
1848  ASSERT_TRUE(actual.has_value());
1849  ASSERT_RECT_NEAR(actual.value(), expected);
1850 }

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() [259/314]

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() [260/314]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryCoverage   
)

Definition at line 2420 of file entity_unittests.cc.

2420  {
2421  std::vector<Point> points = {{10, 20}, {100, 200}};
2422  auto geometry = Geometry::MakePointField(points, 5.0, false);
2423  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2424  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2425  Rect::MakeLTRB(35, 15, 135, 205));
2426 }

References impeller::TRect< Scalar >::MakeLTRB(), impeller::Geometry::MakePointField(), and impeller::Matrix::MakeTranslation().

◆ TEST_P() [261/314]

impeller::testing::TEST_P ( EntityTest  ,
PointFieldGeometryDivisions   
)

Definition at line 2402 of file entity_unittests.cc.

2402  {
2403  // Square always gives 4 divisions.
2404  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u);
2405  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u);
2406  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u);
2407 
2408  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u);
2409  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u);
2410  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u);
2411  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u);
2412  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u);
2413  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u);
2414  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u);
2415  // Caps at 140.
2416  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u);
2417  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u);
2418 }

References impeller::PointFieldGeometry::ComputeCircleDivisions().

◆ TEST_P() [262/314]

impeller::testing::TEST_P ( EntityTest  ,
RadialGradientContentsIsOpaque   
)

Definition at line 2334 of file entity_unittests.cc.

2334  {
2335  RadialGradientContents contents;
2336  contents.SetColors({Color::CornflowerBlue()});
2337  ASSERT_TRUE(contents.IsOpaque());
2338  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2339  ASSERT_FALSE(contents.IsOpaque());
2340  contents.SetColors({Color::CornflowerBlue()});
2341  contents.SetTileMode(Entity::TileMode::kDecal);
2342  ASSERT_FALSE(contents.IsOpaque());
2343 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [263/314]

impeller::testing::TEST_P ( EntityTest  ,
RRectShadowTest   
)

Definition at line 1694 of file entity_unittests.cc.

1694  {
1695  auto callback = [&](ContentContext& context, RenderPass& pass) {
1696  static Color color = Color::Red();
1697  static float corner_radius = 100;
1698  static float blur_radius = 100;
1699  static bool show_coverage = false;
1700  static Color coverage_color = Color::Green().WithAlpha(0.2);
1701 
1702  ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1703  ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
1704  ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
1705  ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
1706  ImGui::Checkbox("Show coverage", &show_coverage);
1707  if (show_coverage) {
1708  ImGui::ColorEdit4("Coverage color",
1709  reinterpret_cast<Scalar*>(&coverage_color));
1710  }
1711  ImGui::End();
1712 
1713  auto [top_left, bottom_right] = IMPELLER_PLAYGROUND_LINE(
1714  Point(200, 200), Point(600, 400), 30, Color::White(), Color::White());
1715  auto rect =
1716  Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);
1717 
1718  auto contents = std::make_unique<SolidRRectBlurContents>();
1719  contents->SetRRect(rect, corner_radius);
1720  contents->SetColor(color);
1721  contents->SetSigma(Radius(blur_radius));
1722 
1723  Entity entity;
1724  entity.SetTransformation(Matrix::MakeScale(GetContentScale()));
1725  entity.SetContents(std::move(contents));
1726  entity.Render(context, pass);
1727 
1728  auto coverage = entity.GetCoverage();
1729  if (show_coverage && coverage.has_value()) {
1730  auto bounds_contents = std::make_unique<SolidColorContents>();
1731  bounds_contents->SetGeometry(Geometry::MakeFillPath(
1732  PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
1733  bounds_contents->SetColor(coverage_color.Premultiply());
1734  Entity bounds_entity;
1735  bounds_entity.SetContents(std::move(bounds_contents));
1736  bounds_entity.Render(context, pass);
1737  }
1738 
1739  return true;
1740  };
1741  ASSERT_TRUE(OpenPlaygroundHere(callback));
1742 }

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() [264/314]

impeller::testing::TEST_P ( EntityTest  ,
RuntimeEffect   
)

Definition at line 2099 of file entity_unittests.cc.

2099  {
2100  if (GetParam() != PlaygroundBackend::kMetal) {
2101  GTEST_SKIP_("This backend doesn't support runtime effects.");
2102  }
2103 
2104  auto runtime_stage =
2105  OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
2106  ASSERT_TRUE(runtime_stage->IsDirty());
2107 
2108  bool first_frame = true;
2109  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2110  if (first_frame) {
2111  first_frame = false;
2112  } else {
2113  assert(runtime_stage->IsDirty() == false);
2114  }
2115 
2116  auto contents = std::make_shared<RuntimeEffectContents>();
2117  contents->SetGeometry(Geometry::MakeCover());
2118 
2119  contents->SetRuntimeStage(runtime_stage);
2120 
2121  struct FragUniforms {
2122  Vector2 iResolution;
2123  Scalar iTime;
2124  } frag_uniforms = {
2125  .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
2126  .iTime = static_cast<Scalar>(GetSecondsElapsed()),
2127  };
2128  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
2129  uniform_data->resize(sizeof(FragUniforms));
2130  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
2131  contents->SetUniformData(uniform_data);
2132 
2133  Entity entity;
2134  entity.SetContents(contents);
2135  return contents->Render(context, entity, pass);
2136  };
2137  ASSERT_TRUE(OpenPlaygroundHere(callback));
2138 }

References impeller::kMetal, impeller::Geometry::MakeCover(), and impeller::Entity::SetContents().

◆ TEST_P() [265/314]

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() [266/314]

impeller::testing::TEST_P ( EntityTest  ,
SolidColorContentsIsOpaque   
)

Definition at line 2307 of file entity_unittests.cc.

2307  {
2308  SolidColorContents contents;
2309  contents.SetColor(Color::CornflowerBlue());
2310  ASSERT_TRUE(contents.IsOpaque());
2311  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
2312  ASSERT_FALSE(contents.IsOpaque());
2313 }

References impeller::Color::CornflowerBlue(), impeller::SolidColorContents::IsOpaque(), and impeller::SolidColorContents::SetColor().

◆ TEST_P() [267/314]

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() [268/314]

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() [269/314]

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() [270/314]

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() [271/314]

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() [272/314]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilter   
)

Definition at line 1904 of file entity_unittests.cc.

1904  {
1905  auto image = CreateTextureForFixture("embarcadero.jpg");
1906  ASSERT_TRUE(image);
1907 
1908  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
1909  auto filtered =
1910  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));
1911 
1912  // Define the entity that will serve as the control image as a Gaussian blur
1913  // filter with no filter at all.
1914  Entity entity_left;
1915  entity_left.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1916  Matrix::MakeTranslation({100, 300}) *
1917  Matrix::MakeScale(Vector2{0.5, 0.5}));
1918  auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
1919  Sigma{0}, Sigma{0});
1920  entity_left.SetContents(unfiltered);
1921 
1922  // Define the entity that will be filtered from sRGB to linear.
1923  Entity entity_right;
1924  entity_right.SetTransformation(Matrix::MakeScale(GetContentScale()) *
1925  Matrix::MakeTranslation({500, 300}) *
1926  Matrix::MakeScale(Vector2{0.5, 0.5}));
1927  entity_right.SetContents(filtered);
1928  return entity_left.Render(context, pass) &&
1929  entity_right.Render(context, pass);
1930  };
1931 
1932  ASSERT_TRUE(OpenPlaygroundHere(callback));
1933 }

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() [273/314]

impeller::testing::TEST_P ( EntityTest  ,
SrgbToLinearFilterCoverageIsCorrect   
)

Definition at line 1883 of file entity_unittests.cc.

1883  {
1884  // Set up a simple color background.
1885  auto fill = std::make_shared<SolidColorContents>();
1886  fill->SetGeometry(Geometry::MakeFillPath(
1887  PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
1888  fill->SetColor(Color::DeepPink());
1889 
1890  auto filter =
1891  ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));
1892 
1893  Entity e;
1894  e.SetTransformation(Matrix());
1895 
1896  // Confirm that the actual filter coverage matches the expected coverage.
1897  auto actual = filter->GetCoverage(e);
1898  auto expected = Rect::MakeXYWH(0, 0, 300, 400);
1899 
1900  ASSERT_TRUE(actual.has_value());
1901  ASSERT_RECT_NEAR(actual.value(), expected);
1902 }

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() [274/314]

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() [275/314]

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() [276/314]

impeller::testing::TEST_P ( EntityTest  ,
SweepGradientContentsIsOpaque   
)

Definition at line 2345 of file entity_unittests.cc.

2345  {
2346  RadialGradientContents contents;
2347  contents.SetColors({Color::CornflowerBlue()});
2348  ASSERT_TRUE(contents.IsOpaque());
2349  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
2350  ASSERT_FALSE(contents.IsOpaque());
2351  contents.SetColors({Color::CornflowerBlue()});
2352  contents.SetTileMode(Entity::TileMode::kDecal);
2353  ASSERT_FALSE(contents.IsOpaque());
2354 }

References impeller::Color::CornflowerBlue(), impeller::RadialGradientContents::IsOpaque(), impeller::Entity::kDecal, impeller::RadialGradientContents::SetColors(), impeller::RadialGradientContents::SetTileMode(), and impeller::Color::WithAlpha().

◆ TEST_P() [277/314]

impeller::testing::TEST_P ( EntityTest  ,
TessellateConvex   
)

Definition at line 2366 of file entity_unittests.cc.

2366  {
2367  {
2368  // Sanity check simple rectangle.
2369  auto [pts, indices] =
2370  TessellateConvex(PathBuilder{}
2371  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
2372  .TakePath()
2373  .CreatePolyline(1.0));
2374 
2375  std::vector<Point> expected = {
2376  {0, 0}, {10, 0}, {10, 10}, {0, 10}, //
2377  };
2378  std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3};
2379  ASSERT_EQ(pts, expected);
2380  ASSERT_EQ(indices, expected_indices);
2381  }
2382 
2383  {
2384  auto [pts, indices] =
2385  TessellateConvex(PathBuilder{}
2386  .AddRect(Rect::MakeLTRB(0, 0, 10, 10))
2387  .AddRect(Rect::MakeLTRB(20, 20, 30, 30))
2388  .TakePath()
2389  .CreatePolyline(1.0));
2390 
2391  std::vector<Point> expected = {
2392  {0, 0}, {10, 0}, {10, 10}, {0, 10}, //
2393  {20, 20}, {30, 20}, {30, 30}, {20, 30} //
2394  };
2395  std::vector<uint16_t> expected_indices = {0, 1, 2, 0, 2, 3,
2396  0, 6, 7, 0, 7, 8};
2397  ASSERT_EQ(pts, expected);
2398  ASSERT_EQ(indices, expected_indices);
2399  }
2400 }

References impeller::PathBuilder::AddRect(), impeller::TRect< Scalar >::MakeLTRB(), and impeller::TessellateConvex().

◆ TEST_P() [278/314]

impeller::testing::TEST_P ( EntityTest  ,
TextContentsCeilsGlyphScaleToDecimal   
)

Definition at line 2448 of file entity_unittests.cc.

2448  {
2449  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
2450  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
2451  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
2452  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
2453 }

References impeller::TextFrame::RoundScaledFontSize().

◆ TEST_P() [279/314]

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() [280/314]

impeller::testing::TEST_P ( EntityTest  ,
TiledTextureContentsIsOpaque   
)

Definition at line 2356 of file entity_unittests.cc.

2356  {
2357  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
2358  TiledTextureContents contents;
2359  contents.SetTexture(bay_bridge);
2360  // This is a placeholder test. Images currently never decompress as opaque
2361  // (whether in Flutter or the playground), and so this should currently always
2362  // return false in practice.
2363  ASSERT_FALSE(contents.IsOpaque());
2364 }

References impeller::TiledTextureContents::IsOpaque(), and impeller::TiledTextureContents::SetTexture().

◆ TEST_P() [281/314]

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() [282/314]

impeller::testing::TEST_P ( EntityTest  ,
YUVToRGBFilter   
)

Definition at line 2066 of file entity_unittests.cc.

2066  {
2067  if (GetParam() == PlaygroundBackend::kOpenGLES) {
2068  // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
2069  GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
2070  }
2071 
2072  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
2073  YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
2074  YUVColorSpace::kBT601LimitedRange};
2075  for (int i = 0; i < 2; i++) {
2076  auto yuv_color_space = yuv_color_space_array[i];
2077  auto textures =
2078  CreateTestYUVTextures(GetContext().get(), yuv_color_space);
2079  auto filter_contents = FilterContents::MakeYUVToRGBFilter(
2080  textures[0], textures[1], yuv_color_space);
2081  Entity filter_entity;
2082  filter_entity.SetContents(filter_contents);
2083  auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);
2084 
2085  Entity entity;
2086  auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
2087  contents->SetTexture(snapshot->texture);
2088  contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
2089  entity.SetContents(contents);
2090  entity.SetTransformation(
2091  Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
2092  entity.Render(context, pass);
2093  }
2094  return true;
2095  };
2096  ASSERT_TRUE(OpenPlaygroundHere(callback));
2097 }

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() [283/314]

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() [284/314]

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() [285/314]

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() [286/314]

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() [287/314]

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() [288/314]

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() [289/314]

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() [290/314]

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() [291/314]

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() [292/314]

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() [293/314]

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() [294/314]

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() [295/314]

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() [296/314]

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() [297/314]

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() [298/314]

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() [299/314]

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() [300/314]

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() [301/314]

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() [302/314]

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() [303/314]

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() [304/314]

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() [305/314]

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() [306/314]

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() [307/314]

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() [308/314]

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() [309/314]

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() [310/314]

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() [311/314]

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() [312/314]

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() [313/314]

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() [314/314]

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:1998
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:2015
_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